Reputation: 114218
The documentation for attr_accessor
explicitly says that it creates an instance variable:
[...] creating an instance variable (
@name
) and a corresponding access method [...]
As does the documentation for attr_reader
:
Creates instance variables and corresponding methods [...]
I understand the second part, i.e. that attr_accessor
and attr_reader
create methods, but I don't get the first part.
What does it mean that they "create an instance variable"?
Upvotes: 4
Views: 612
Reputation: 369556
The documentation for
attr_accessor
explicitly says that it creates an instance variable:[...] creating an instance variable (
@name
) and a corresponding access method [...]As does the documentation for
attr_reader
:Creates instance variables and corresponding methods [...]
I understand the second part, i.e. that
attr_accessor
andattr_reader
create methods, but I don't get the first part.What does it mean that they "create an instance variable"?
The documentation is at least misleading if not plain wrong. They create methods, nothing more. On most Ruby implementations, the implementation is in the host language (e.g. C for YARV, Java for JRuby) with special privileged access to the internals of the implementation, but actually, you can write them in plain Ruby:
class Module
def attr_reader(*attrs)
attrs.each do |attr|
define_method(attr) do
instance_variable_get(:"@{attr}")
end
end
end
def attr_writer(*attrs)
attrs.each do |attr|
define_method(:"{attr}=") do |val|
instance_variable_set(:"@{attr}", val)
end
end
end
def attr_accessor(*attrs)
attr_reader(*attrs)
attr_writer(*attrs)
end
end
Upvotes: 2
Reputation: 230471
That's a bug/misleading wording in documentation. The attr_reader
/attr_accessor
themselves don't create any variables. How can they? They work outside of class instance lifecycle. And even read access don't make the instance variables come to life. Only write access creates them.
class Foo
attr_accessor :bar
end
foo = Foo.new
foo.instance_variables # => []
foo.bar # try read ivar
foo.instance_variables # => [], nope, not yet
foo.bar = 2 # write ivar
foo.instance_variables # => [:@bar], there it is
Upvotes: 4