Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Ruby's attr_accessor automatically create instance variables for attributes?

Tags:

ruby

For example, if we write

class MyClass
  attr_accessor :something
end

but did not explicitly create an initialize method with instance variable @something, does Ruby automatically create it?

like image 474
OneZero Avatar asked Mar 20 '13 02:03

OneZero


People also ask

What does attr_accessor do in Ruby?

Well, attr_accessor creates both the READER & WRITER methods. attr_reader creates only the reader. attr_writer creates only the writer.

How do instance variables work in Ruby?

An instance variable in ruby has a name starting with @ symbol, and its content is restricted to whatever the object itself refers to. Two separate objects, even though they belong to the same class, are allowed to have different values for their instance variables.

Are instance variables attributes?

Class attributes are the variables defined directly in the class that are shared by all objects of the class. Instance attributes are attributes or properties attached to an instance of a class.

What is a class instance variable in Ruby?

What's an instance variable? In the Ruby programming language, an instance variable is a type of variable which starts with an @ symbol. Example: @fruit. An instance variable is used as part of Object-Oriented Programming (OOP) to give objects their own private space to store data.


2 Answers

No. Instance variables are not defined until you assign to them, and attr_accessor doesn't do so automatically.

Attempting to access an undefined instance variable returns nil, but doesn't define that variable. They don't actually get defined until you write to them. attr_accessor relies on this behaviour and doesn't do anything except define a getter/setter.

You can verify this by checking out .instance_variables:

class Test
  attr_accessor :something
end

A new instance of x has no instance variables:

x = Test.new # => #<Test:0xb775314c>
x.instance_variables # => []

Invoking the getter does not cause @something to become defined:

x.something # => nil
x.instance_variables # => []

Invoking the setter does cause @something to become defined:

x.something = 3 # => 3
x.instance_variables # => ["@something"]

Setting something back to nil doesn't cause instance_variables to revert, so we can be sure that the first empty array returned isn't simply a case of instance_variables omitting nil values:

x.something = nil # => nil
x.instance_variables # => ["@something"]

You can also verify that this isn't simply behaviour specific to attr_accessor:

class Test
  def my_method

    @x # nil

    instance_variables # []

    @x = 3 

    instance_variables # ["@x"]
  end 
end

Test.new.my_method
like image 158
meagar Avatar answered Sep 18 '22 09:09

meagar


Sort of. In Ruby, instance variables are created when they are first assigned. This is completely transparent to the programmer. They default to nil until assigned.

Ex:

class Foo
  attr_accessor :bar
  def baz
    @nonexistant
  end
end
f.bar #=> nil
f.baz #=> nil
f.bar = 4
f.bar #=> 4

Until you assign a value to an instance variable, it floats in a undefined nil state.

like image 24
Linuxios Avatar answered Sep 22 '22 09:09

Linuxios