03-24-2025, 07:50 PM
(This post was last modified: 03-24-2025, 10:00 PM by kyonides.
Edit Reason: Updated Many Times Already
)
Effects of Relying on a Bad Explanation:
Getters, Setters & Wrapper Methods
When someone else was explaining how the getter and setter methods work in Ruby, the next thing this guy mentioned was that they were some sort of wrapper methods created around the corresponding variables to let the program access them. Later on you could also read that it limit the circumstances under which the variables can be altered by mistake, but is that true?
I've got some sad news for all those people that once thought it was true. No, that's not how it works and it doesn't prevent you from changing the value at any inconvenient moment and those methods can be accessed from ANYWHERE at ANY GIVEN TIME.
Thus, some var=(val) method isn't a wrapper of @some, it's its actual setter method. It simply was manually created instead of using Module's attr_writter shortcut. Even if the setter included a conditional statement, it'd remain as a setter.
If you don't want any scene or window or sprite to be able to alter those variables, then don't define their setter methods.


Is it a good idea of calling a manually defined getter or setter method a wrapper?
Nope, it isn't. It'd be quite terrible for setters. You better reserve that term for other instances where you'll definitely need it.
It'd be a wrapper method in Ruby IF:
- It had another name or a different number of arguments like set_vars(a, b)
- It's a custom spriteset class that lets you change all of its sprites' visibility state with a visible=(bool) method.
- The Game_Party#add_actor method that will limit the number of heroes that can join our party in the RM engine.
- Of course, there might be other ways to create wrappers that I haven't mentioned here like Game_Actors class being a wrapper class for a @data Array object that contains Game_Actor objects, i.e. $game_actors[1] calls the Game_Actors#[](index) method that internally returns the value of @data[index] or creates a brand new Game_Actor object.
Is there a way to easily prove that those getters and setters don't behave like mere wrappers?
Yes, there is! Let's use a simple test code.
Code:
class Person
def initialize
@age = 1
end
def age
print "Current age #{@age}\n"
@age
end
def age=(new_age)
print "Altering your age now!\n"
@age = new_age
end
attr_reader :age
attr_writer :age
# Or just call this instead: attr_accessor :age
end
The code above would define 2 methods for the same @age variable, its getter and its setter in that specific order. They are supposed to print something on screen on both RMXP and RMVX. In RMVX ACE it would require you to open the console window first.
But there's a catch!

What that means is that now we won't ever be able to print anything on the popup window or the console window depending on which RM engine you're using.

NOTE
I have added the initialize method to the Person class to make sure that the @age variable will never return a nil value, which is the default return value of any variable that has not been assigned a different value at some point.
Other Ways to Deal With It
Later on

The code I had proposed would look like this then:
Code:
class Person
def age
print "Current age #{@age}\n"
@age ||= 1
end
def age=(new_age)
print "Altering your age now!\n"
@age = new_age
end
attr_reader :age
attr_writer :age
# Or just call this instead: attr_accessor :age
end
What does that altered line of code do there?
Well, it's pretty simple indeed. If the @age has not been predefined, it will pick 1 as its default value. If at some point the value of @age has been altered, let's say that now it's 15, it will ignore 1 and return 15 instead.

Yet, don't forget that the attr_ methods are still in use so they won't ever print anything on a popup window or the console window if any.
If it were able to print anything, you'll soon notice that the age getter method would print a nil (an empty string "") instead of a number as its current age.

Is that the only way we could have done it?



Code:
class Person
def age
@age = 1 if @age.nil?
print "Current age #{@age}\n"
@age
end
def age=(new_age)
print "Altering your age now!\n"
@age = new_age
end
attr_reader :age
attr_writer :age
# Or just call this instead: attr_accessor :age
end
As you can see, the interpreter would have to always make the check in a separate line before printing the @age variable via print and then returning the value of @age... IF the attr_reader or attr_writer or attr_accessor methods had not been used there or had been #commented out.
You shouldn't underestimate that piece of code. It does work as intended, but the ||= operator makes it easy to skip it.
Nonetheless, there's a caveat!

The ||= operator won't let you preassign the value before printing the previous value of @age.

"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]](https://www.save-point.org/images/userbars/SP1-Scripter.png)
![[Image: SP1-Writer.png]](https://www.save-point.org/images/userbars/SP1-Writer.png)
![[Image: SP1-Poet.png]](https://www.save-point.org/images/userbars/SP1-Poet.png)
![[Image: SP1-PixelArtist.png]](https://www.save-point.org/images/userbars/SP1-PixelArtist.png)
![[Image: SP1-Reporter.png]](https://i.postimg.cc/GmxWbHyL/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!
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.
![[Image: SP1-Scripter.png]](https://www.save-point.org/images/userbars/SP1-Scripter.png)
![[Image: SP1-Writer.png]](https://www.save-point.org/images/userbars/SP1-Writer.png)
![[Image: SP1-Poet.png]](https://www.save-point.org/images/userbars/SP1-Poet.png)
![[Image: SP1-PixelArtist.png]](https://www.save-point.org/images/userbars/SP1-PixelArtist.png)
![[Image: SP1-Reporter.png]](https://i.postimg.cc/GmxWbHyL/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!

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