Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 Ruby Scripting
#11
That may run fine for a time. And yes, you were able to gain the value of MyModule:MyClass::A just fine. 

However, recursion does occur.  For any who wishes to go into their script editor and type this within the Main script (typically at the bottom), here is an example of said recursion being created:

Code:
module MyModule
  class MyClass
    A = 'A'
    B = 'B'
    include MyModule
  end
end 

p MyModule::MyClass::MyClass::MyClass::MyClass::B
 
I am able to receive output, not just from MyModule::MyClass.   But from MyModule::MyClass:MyClass (which is the contents of MyModule thrown into MyClass), and the contents of MyModule::MyClass::MyClass::MyClass (again, throwing the contents back in once more).

Honestly, the recursion is so bad, I could use this for the output:
Code:
p MyModule::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::B

And with 15 instances of MyClass, one being within the previous over and over, it still yield the same result.  The MyClass object is being duplicated over and over and over, taking up more memory as the program runs.

Anyone can try that example I posted and see for themselves.
Up is down, left is right and sideways is straight ahead. - Cord "Circle of Iron", 1978 (written by Bruce Lee and James Coburn... really...)
[Image: QrnbKlx.jpg]

Reply }
#12
(02-03-2023, 03:52 AM)DerVVulfman Wrote:
Code:
module MyModule
  class MyClass
    A = 'A'
    B = 'B'
    include MyModule
  end
end 

p MyModule::MyClass::MyClass::MyClass::MyClass::B
...
Honestly, the recursion is so bad, I could use this for the output:
Code:
p MyModule::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::MyClass::B

Thinking What a mess made in hell!
Happy with a sweat OK, that case is even worse than the one previously presented on my previous post.
There is a caveat. Oops! It will not cause the recursion on its own, instead it will do it if it is commanded to keep looking for it.
Is that a serious issue? Who Knows?
It is more like a yes and not or a German jein. Laughing

What I mean is that it is a TERRIBLE IDEA for sure, but it is not like a method recursion where you cannot stop it from running unless you had added a valid condition there to break the invisible loop.

This will not cause you an immediate issue like running low on memory per se, but you will NOT be able to undo it unless you quit the program or application.

And even before Wulfo friendly? hijacks my thread again for the same reason, I will explain something that the average joe might not notice.

The first time you call that, it might not be an issue. Nonetheless, it will keep getting ugly the more times you keep calling it because it was used, let us say, inside a specific method. Memory CANNOT be freed soon just as expected. This translates to crafting messy code that is inexcusable at all. Serious

Should we care about it?

The answer is yes!
Simply NEVER EVER ATTEMPT to run a real life program with such a weird and buggy inclusion of a module in a nested class.

Before I finish my short dissertation on this matter, I got to add something else.

Whatever has been included in that module is ALREADY AVAILABLE in the nested classes.
You do not need to include the container module at all! Shocked

Yet, there IS a caveat you should care about! Confused

Code:
module Some
  class Thing
  end
end

The definition above will let you access everything you have defined in the Some module, but the one below does not ever let you get to its CONSTANTS.

Code:
class Some::Thing
  # some code here!
end

Who Knows? Why it doesn't?

The answer is simple, it is because of its Hal 2000 scope!
It cannot see where the CONSTANTS are located. You have reduced the scope to that Thing class only! Happy with a sweat
This means you will need to call all of its module's CONSTANTS like this:

Code:
Some::CONSTANT

And that is, my friends, a very unpractical way to achieve a simple goal. Winking

Thinking Perhaps I could submit a request to the Ruby Core devs to make them forbid that inclusion in recent versions of Ruby Ruby at least.

"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX
Reply }
#13
When to Use the Module Class' include Feature

I have seen many times that people kind of abuse of the :: scope operator when they are fiddling with modules. That inspired me to revisit the modules to make sure they stop repeating themselves like crazy. Winking

Basic Setup Modules

Code:
module SomeUser
  module Config
    DEFAULT_FONT_SIZE = 20
    DEFAULT_TITLE = "Some Label"
  end
end

So far there is nothing new to see here but everything changes Shocked once we start dealing with a specific Window class. Detective Let us take a look at some fake Window_TitleCommand Add-on.

Code:
class Window_TitleCommand
  alias :some_user_config_win_ttl_comm_draw_item :draw_item
  def default_font_size
    SomeUser::Config::DEFAULT_FONT_SIZE
  end

  def draw_item(index)
    some_user_config_win_ttl_comm_draw_item(index)
    contents.font.size = self.default_font_size
    text = SomeUser::Config::DEFAULT_TITLE
    contents.draw_text(4, 26, contents_width, 24, text, 1)
  end
end

As you can see above, we had to use the :: scope operator several times in our scriptlet. Happy with a sweat Honestly, I got to tell you that it is not elegant at all. Confused The more Constants you include the worse it will look like.

Let's make some modifications to the original code.

Code:
class Window_TitleCommand
  include SomeUser::Config
  alias :some_user_config_win_ttl_comm_draw_item :draw_item
  def draw_item(index)
    some_user_config_win_ttl_comm_draw_item(index)
    contents.font.size = DEFAULT_FONT_SIZE
    contents.draw_text(4, 26, contents_width, 24, DEFAULT_TITLE, 1)
  end
end

Wunderbar! Shocked Wonderful!

Now it looks quite neat! And we can even skip the creation of needless methods only to call the same long line of code we could find inside the default_font_size over and over again.

There is a caveat, though. You should NOT do that if you are working on a class that inherits the methods you have altered there. This is especially true if at least one of its child classes does not need such modifications at all. I seriously Serious recommend you to only include the modules in Baby child classes and nowhere else unless you know what you are doing.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX
Reply }
#14
Assignment != Equality && Assignment != Identity && Equality != Identity

Let us review what an assignment actually is. It simply means that you pick either a Constant or a variable and set a value to that object and not any other around it. (Well, you could still do it but you got to have a valid reason for it or else do not even try to do that!)

The assignment operator is an = equal sign.

variable = actual_value

That means that whenever you use that variable or Constant, it will always return the last value you have assigned to that particular object. You should not alter a Constant's value, though. Confused

Equality stands for something that has the save value as another object, be it a Constant or a variable.

Use two == equal signs to make the comparison between two objects that might be different or not.

Code:
CONSTANT = 1
@variable = 1
CONSTANT == @variable #=> Returns true

The === identity operator

And finally, we got the identity operator === to help us define if an object has been placed on both sides of a given comparison.

Here you got to be careful because it is excesively strict when looking for any identical value or object.

Code:
range = 1..8
range === 5 #=> Returns true
range === range #=> Returns... false!
range == range #=> Returns... true!
Object.new === Object.new #=> Returns false, they are two different Objects with their own IDs.

Whenever you are using the case when statement to double check if a give variable is equal to another, it will use the === identity operator by default.

As we could see in the first example of the identity checks, the first test returned a true-ish value because it used the === operator with EVERY SINGLE VALUE of that Range object until it hit number 5.

Honestly, you should use the == equality operator for if and unless statements mainly because there is no specific reason to do otherwise.

When using the case when statement, make sure you will be comparing the same kind of objects like numbers or classes. It will fail if you made a mistake and tested the value of a variable, like number 5, against a class like Integer, even if number 5 is an Integer object on its own right.

Other Operators

By the way, the != operator simply means Not Equal.
The !=== Not Identical operator does exist as well, but it would be quite weird for you to find a good use for it anywhere.
The && double et symbol you could find on the title of this very same post simply means and.

A Terrible But Good Looking Error That Can Make You Break Your Head

You will not be able to tell why it is not working as intended because it will make you think everything is fine.

Code:
variable == 100 || 50

Yeah, everything looks terrific and it NEVER throws any error at your face at all.
Really guys, it never will. Winking 100% guaranteed! Grinning
Still, it is a huge mistake under most circumstances. Confused

The reasoning behind it is QUITE SIMPLE indeed.
How do you know if the test is always working as intended if it never fails?
Thinking So tell me why is that a problem for any novice scripter?

It is a huge problem because you wound up defining a conditional statement you never needed.
Happy with a sweat I mean, if you always get a true-ish value back, why bother at all? Sarcasm
You could simply remove it and the script would work as usually does. Happy with a sweat

Keep in mind that any object other than nil and false are treated as true by default.

Sad But I need it to reject certain requests because it did not hit the 100% accuracy I need in my skill, item consumption, etc.
Detective If that is true, then you better delete the "|| number" part at once.
Sad I cannot. I need it to also work if it hits the 50% mark...
Yellow Card You get a yellow card for making such a noob mistake then.
Actually, the only way that would work is to define the condition like I do it right below this very same line.

Code:
variable == 100 || variable == 50

Detective I would suspect you come from a different programming language that allow you to do that or you simply watched some video tutorial that was not Ruby Ruby specific at all.
Stop mixing language syntaxes right there! Stop 
Don't do it ever again! Angry
It is for your own benefit, anyway. Happy with a sweat
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX
Reply }


Possibly Related Threads…
Thread Author Replies Views Last Post
Information  Assorted Ruby chm documents. hanetzer 10 26,391 08-17-2020, 04:19 AM
Last Post: kyonides
Brick  Learn Ruby! greenraven 2 6,315 05-16-2014, 12:25 PM
Last Post: greenraven
   Creating Your Own Scripting System DerVVulfman 3 6,037 10-12-2009, 03:37 PM
Last Post: Alpha-Mad
   How to make interesting NPC's without scripting Third333Strike 0 3,107 12-06-2008, 04:59 PM
Last Post: Third333Strike



Users browsing this thread: