Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do Ruby instance variables get set?

class Hello @hello = "hello"     def display         puts @hello     end end  h = Hello.new h.display 

I created the class above. It doesn't print anything out. I thought the instance variable @hello was set during the class declaration. But when I call the display method the output is 'nil'. What's the correct way to do this?

like image 825
pez_dispenser Avatar asked May 05 '09 20:05

pez_dispenser


People also ask

How do instance variables work in Ruby?

In the Ruby programming language, an instance variable is a type of variable which starts with an @ symbol. An instance variable is used as part of Object-Oriented Programming (OOP) to give objects their own private space to store data. We say that objects can: Do things.

When instance variables are created?

Instance variables are created when an object is instantiated, and are accessible to all the constructors, methods, or blocks in the class. Access modifiers can be given to the instance variable. An instance variable is not a class variable although there are similarities.

How do I set an instance variable 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 inherited in Ruby?

Instance variables are not inherited. If a method is written in the subclass with the same name and parameters as one in the parent class, the super class' method is overwritten.


1 Answers

Instance variables in ruby may be a bit confusing when first learning Ruby, especially if you are accustomed to another OO language like Java.

You cannot simply declare an instance variable.

One of the most important things to know about instance variables in ruby, apart from the notation with an @ sign prefix, is that they spring into life the first time they are assigned to.

class Hello   def create_some_state     @hello = "hello"   end end  h = Hello.new p h.instance_variables   h.create_some_state p h.instance_variables  # Output [] ["@hello"] 

You can use the method Object#instance_variables to list all instance variables of an object.

You normally “declare” and initialize all the instance variables in the initialize method. Another way to clearly document which instance variables that should be publicly available is to use the Module methods attr_accessor (read/write), attr_writer (write) and attr_reader (read). These methods will synthesize different accessor methods for the listed instance variable.

class Hello   attr_accessor :hello end  h = Hello.new p h.instance_variables   h.hello = "hello" p h.instance_variables  # Output [] ["@hello"] 

The instance variable still isn’t created until it’s assigned to using the synthesized Hello#hello= method.

Another important issue, like kch described, is that you need to be aware of the different contexts active when declaring a class. When declaring a class the default receiver (self) in the outermost scope will be the object that represents the class itself. Hence your code will first create a class instance variable when assigning to @hello on the class level.

Inside methods self will be the object on which the method is invoked, hence you are trying to print the value of an instance variable with the name @hello in the object, which doesn’t exists (note that it’s perfectly legal to read a non existing instance variable).

like image 159
sris Avatar answered Oct 19 '22 22:10

sris