Rails和类变量

时间:2012-07-17 13:28:12

标签: ruby

class MainController < ApplicationController

  @my_var = 123
   def index
    var1 = @my_var
   end

   def index2
    var2 = @my_var
   end
end

为什么var1没有var2等于123

3 个答案:

答案 0 :(得分:22)

带有@的变量是ruby中的实例变量。如果您正在寻找类变量,那么它们的前缀是@@,因此您应该使用@@my_var = 123代替。

并且你不能以这种方式使用实例变量的原因是因为如果你在方法之外定义实例变量,它们与你的方法不在同一个范围内,而只在你的类被解释时才存在。

您的示例中的

var1是一个局部变量,只能在index方法中显示。

示例:

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"

答案 1 :(得分:2)

示例代码中的

@my_var是类MainController上的实例变量。也就是说,它是类级实例变量,而不是实例级实例变量。它存在于与类实例关联的实例变量的完全不同的范围内。

实例方法indexindex2的正文中,您试图取消引用对象的实例变量,该对象是类{{1}的实例但是你还没有在任何地方定义那个实例变量,所以你得到了MainController

如果要将nil用作类级实例变量,可以从类的实例中获取其值,如下所示:

@my_var

类变量用var1 = self.class.instance_variable_get(:@my_var) 前缀表示,并且不完全鼓励使用它们。几分钟与谷歌会告诉你原因。

答案 2 :(得分:0)

因为代码在不同的上下文中执行。你可以在这里看到:

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

正如您在第一次打印中看到的那样,self是MainController,在第二次打印中,self是从MainController类派生的对象。

在@my_vay的赋值中,此变量属于MainController,在第二种情况下,@ my_var属于object(不是类),这些变量是不同的。