Stefan
Stefan

Reputation: 114218

What does it mean that `attr_accessor` / `attr_reader` create an instance variable?

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

Answers (2)

Jörg W Mittag
Jörg W Mittag

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 and attr_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

Sergio Tulentsev
Sergio Tulentsev

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

Related Questions