This content originally appeared on DEV Community and was authored by hungle00
1. Ruby accessor methods
Ruby does not allow instance variables to be accessed outside of methods for that object.
class Person
def initialize(name)
@name = name
@age = 10
end
end
p = Person.new('steve')
p.name # => undefined method `name=' for #<Person ..>
This design ensures OOP encapsulation - an object’s data is protected from the outside world.
In some languages like Java, to access private instance variables, you must define getter/setter methods for each attribute. But in Ruby, you can generate getter/setter methods by using one of the methods in the Module#attr_*
family.
class Person
attr_reader :name, :age # getter
attr_writer :name, :age # setter
# attr_accessor :name, :age # getter + setter
# other code ....
end
p = Person.new('steve')
p.name # => steve
p.age = 20
p.age # => 20
It just takes one or two lines for all of the attributes. These methods are called Class Macros which are class methods only used when in a class definition.
2. DIY accessor methods
There are advanced ways to access instance variables, like instance_variable_get
, instance_eval
.
For example:
p = Person.new('steve')
p.instance_variable_get(:@name)
p.instance_eval { @name }
Using some metaprogramming techniques, we can build attribute accessor methods by myself.
module GetterSetter
def attr_getter(*attributes)
attributes.each do |attribute|
define_method attribute do
instance_variable_get("@#{attribute}")
end
end
end
def attr_setter(*attributes)
attributes.each do |attribute|
define_method "#{attribute}=" do |value|
instance_variable_set("@#{attribute}", value)
end
end
end
def attr_getter_and_setter(*attributes)
attr_getter(*attributes)
attr_setter(*attributes)
end
end
For simplicity, I define getter/setter in separated module and include in Person
class.
class Person
extend GetterSetter
def initialize(name)
@name = name
@age = 10
end
attr_getter :name, :age
attr_setter :name, :age
# or
# attr_getter_and_setter :name, :age
end
p = Person.new('Luke')
p.name = 'anakin'
p.name # => anakin
Summary
Class macros are one of Ruby's magic methods that help developers get rid of a lot of tedious, boilerplate methods. In rails, class macros are used a lot, for associations ( has_many
, belongs_to
), validation, ...
You can learn more about Ruby class macros or other metaprogramming techniques in the Metaprogramming Ruby book ( https://pragprog.com/titles/ppmetr2/metaprogramming-ruby-2/)
This content originally appeared on DEV Community and was authored by hungle00
hungle00 | Sciencx (2023-06-05T06:06:58+00:00) Ruby – DIY accessor methods. Retrieved from https://www.scien.cx/2023/06/05/ruby-diy-accessor-methods/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.