5
class MainController < ApplicationController

  @my_var = 123
   def index
    var1 = @my_var
   end

   def index2
    var2 = @my_var
   end
end

Why is neither var1 no var2 equal to 123?

Frost
  • 11,121
  • 3
  • 37
  • 44
Alexandre
  • 13,030
  • 35
  • 114
  • 173

3 Answers3

22

Variables with @ are instance variables in ruby. If you're looking for class variables, they're prefixed with @@, so you should be using @@my_var = 123 instead.

And the reason you can't use instance variables that way, is because if you define instance variables outside methods, they don't live in the same scope as your methods, but only live while your class is interpreted.

var1 in your example is a local variable, which will only be visible inside the index method.

Examples:

class Foo
  @@class_variable = "I'm a class variable"

  def initialize
    @instance_variable = "I'm an instance variable in a Foo class"
    local_variable = "I won't be visible outside this method"
  end

  def instance_method_returning_an_instance_variable
    @instance_variable
  end

  def instance_method_returning_a_class_variable
    @@class_variable
  end

  def self.class_method_returning_an_instance_variable
    @instance_variable
  end

  def self.class_method_returning_a_class_variable
    @@class_variable
  end
end

Foo.new
=> #<Foo:0x007fc365f1d8c8 @instance_variable="I'm an instance variable in a Foo class">
Foo.new.instance_method_returning_an_instance_variable
=> "I'm an instance variable in a Foo class"
Foo.new.instance_method_returning_a_class_variable
=> "I'm a class variable"
Foo.class_method_returning_an_instance_variable
=> nil
Foo.class_method_returning_a_class_variable
=> "I'm a class variable"
Frost
  • 11,121
  • 3
  • 37
  • 44
  • So what is difference between @var and var? – Alexandre Jul 17 '12 at 13:43
  • 2
    `@var` is an instance variable, which will be visible in all methods in an instance of the class. `var` is a local variable, which will only be visible in the scope it is defined. – Frost Jul 17 '12 at 13:45
  • Ok, what is the difference between @var and @@var? – Alexandre Jul 17 '12 at 13:46
  • 1
    That's what I explained in the actual answer. `@@` are class variables, which are visible in the whole class, even in class methods (methods defined as `self.method_name`, they cannot see instance variables). – Frost Jul 17 '12 at 13:48
  • Then I don't understand the difference between class variables and instance variables. Does a `class variable` mean `static` variable (like in Java, C++...)? – Alexandre Jul 17 '12 at 13:57
  • http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/ might also be a good read. – Frost Jul 17 '12 at 14:00
2

@my_var, in your sample code, is an instance variable on the class MainController. That is, it's a class-level instance variable, and not an instance-level instance variable. It exists in a totally different scope to the instance variable associated with an instance of the class.

Within the body of your instance methods, index and index2, you are attempting to dereference an instance variable on an object that is an instance of class MainController, but you have not defined that instance variable anywhere, so you get back nil.

If you want to use @my_var as a class-level instance variable, you can get its value from within an instance of the class like this:

var1 = self.class.instance_variable_get(:@my_var)

Class variables are indicated with a @@ prefix, and their use is not entirely encouraged. A couple of minutes with Google will tell you why.

D_Bye
  • 869
  • 6
  • 10
0

Because code executes in different context. You can see here:

class MainController
  puts self
  def print_self
    puts self
  end
end
#=> MainController
MainController.new.print_self #=> <MainController:0x00000001761140>

As you can see in first print the self is MainController, in second print the self is the object which derived from MainController class.

In the assignment to @my_vay this variable belongs to MainController, and in the second cases, the @my_var belongs to object (not a class) and these varaibles are different.

megas
  • 21,401
  • 12
  • 79
  • 130