Rails and class variables

class MainController < ApplicationController @my_var = 123 def index var1 = @my_var end def index2 var2 = @my_var end end 

Why is var1 no var2 equal to 123 ?

+5
ruby
source share
3 answers

Variables with @ are instance variables in ruby. If you are looking for class variables, they have the @@ prefix, so you should use @@my_var = 123 instead.

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

var1 in your example is a local variable that 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" 
+22
source share

@my_var , in your sample code, is an instance variable of the MainController class. That is, it is an instance variable of a class, not an instance variable. It exists in a completely different scope to the instance variable associated with the class instance.

Inside the body of your instance methods index and index2 you are trying to dereference the instance variable for an object that is an instance of the MainController class, but you did not specify this instance variable anywhere, so you will return nil .

If you want to use @my_var as a class instance variable, you can get its value from the class instance as follows:

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

Class variables are indicated by the @@ prefix, and their use is not fully encouraged. After a couple of minutes, Google will tell you why.

+2
source share

Because the code is executed in a different context. You can look here:

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

As you can see in the first print, self MainController , in the second type, self is an object obtained from the MainController class.

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

0
source share

All Articles