11-18-2023, 09:02 AM
(This post was last modified: 11-18-2023, 09:14 PM by kyonides.
Edit Reason: Small Code Mod + Additional Statement
)
Moronic Design: Ruby & The Embedded Methods
Months ago there was a discussion on a topic that made some people not used to Ruby's nuances pretty mad indeed. The topic at hand was defining a method inside another method, pretty much embedding it without caring about the consequences of such a poor design. I heavily critized it because it will never ever make any sense in Ruby nor RGSS any version at all.
Now I am going to cover that here to let you know what actually happens when you try to imitate one of the effects, namely treating Ruby's methods as JavaScript's functions thinking they both are first class citizens in their respective programming languages.
The results might heavily disappoint some of you for not reflecting your wishes or fears as accurately as it was expected. Actually, the outcome is quite predictable while still retaining its nonsensical nature intact.
Conclusions:
- Ruby has NEVER treated its methods as objects that can be easily and perfectly defined pretty much anywhere in your code like JavaScript functions do in later iterations of the RM engine.
- The contents of embedded methods will not be accessible from within the "parent" method. They will just get defined as usual and will belong to that instance of the class, aka the current object, only and not to the fake parent method.
- Ruby will parse and (re)define that weird internal method will take place every single time you call the so called parent method. (Ruby will only keep a reference to the last definition of a method. Here it will only replace the previous definition over and over again.)
- There is no way you can make Ruby get in trouble by making a large chain of methods the way it allows you to chain constants in a weird mix of module / class & constant list kept together as a single but large script call that has no theoretical end as far as we scripters know.
- There is no way we can ever get something meaningful and useful out of making this terrible mistake.
The Proof
We need to come up with some test code to make sure we can prove what I have exposed above as the only valid conclusions I could come up with after running it several times in a row.
So here it is!
Sample Code
Code:
class A
def hello
print "Hello!"
def bye
print "Bye!"
end
end
end
Now let us run it by pasting the following snippet right on a script section located before the Main script and lets launch the game after saving our changes to the script editor.
Test Code
Code:
print a = A.new
print a.hello
begin
print a.hello.bye
rescue
print "Failed to execute a.hello.bye"
end
a.bye
a.hello
a.bye
a.hello
Side Note:
If you print both the a.hello or a.bye calls, you will not get any error messages. Even so, removing the print call like I did in the code above can make you throw an error for relying on a rescue call inside an IRB binding. What this means is that a console window running the Ruby interpreter is not supposed to execute such a rescue statement. This is true for the 2.7 release at least.
Inline rescue calls work normally even while running the IRB on a console window aka shell.
What we are going to do now is test it on vanilla RMXP (or VX or ACE if you prefer) and also on HiddenChest game engine and just see what happens then. Will both engines return the same results?
Ruby 1.8's Output - vanilla RGSS1
Code:
#<A:0x41a3481>
Hello!
nil
Hello!
Failed to execute a.hello.bye
Bye!
nil
Hello!
nil
Bye!
nil
Hello!
nil
What we should notice after reading the output above is that whenever a method gets defined, meaning being parsed and evaluated first, it will always return a nil object as its normal outcome.
Ruby 2.7's Output - HiddenChest
Code:
#<A:0x00007f1d4cf54810>
Hello!
bye
Hello!
Failed to execute a.hello.bye
Bye!
Hello!
bye
Bye!
Hello!
bye
OK, this is very similar to the first output, except that Ruby 2.7 returns a :bye symbol after defining any given method. For some reason still unknown to your servitor, it doesn't return anything readable after printing the bye method's return value.
Note:
After other people also ran the code and reviewing the default implementation of Ruby called either MRI or YARV depending on the version, using two consecutive print calls like I originally did will return a nil value or a whitespace accordingly.
In both cases you can either get a bye string representing the method's name by calling the usual print function or the actual :bye "symbol" (actually a string that keeps its typical colon at the beginning) if you call the p function instead.
"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.
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!
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, OpenChest XP VX & ACE
Maranatha!
The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.
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!
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, OpenChest XP VX & ACE