5
class MainController < ApplicationController

  @my_var = 123
   def index
    var1 = @my_var
   end

   def index2
    var2 = @my_var
   end
end

为什么不等于var1var2等于123

4

3 回答 3

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"
于 2012-07-17T13:32:24.410 回答
2

@my_var,在您的示例代码中,是类的实例变量MainController。也就是说,它是一个类级别的实例变量,而不是一个实例级别的实例变量。它存在于与类实例关联的实例变量完全不同的范围内。

在您的实例方法的主体indexindex2,您试图取消引用作为 class 实例的对象上的实例变量MainController,但您尚未在任何地方定义该实例变量,因此您返回nil.

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

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

类变量用@@前缀表示,并不完全鼓励使用它们。用谷歌几分钟就会告诉你为什么。

于 2012-07-17T14:02:23.107 回答
0

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

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

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

在对@my_vay 的赋值中,这个变量属于MainController,而在第二种情况下,@my_var 属于对象(不是类)并且这些变量是不同的。

于 2012-07-17T13:34:26.603 回答