在Ruby中,在类方法的上下文中,实例和类变量是什么?

时间:2010-04-08 09:34:01

标签: ruby class-variables class-instance-variables

如果我有以下Ruby代码:

class Blah
  def self.bleh
    @blih = "Hello"
    @@bloh = "World"
  end
end

@blih和@@ bloh究竟是什么? @blih是Blah类中的实例变量,而@@ bloh是Blah类中的类变量,对吗?这是否意味着@@ bloh是Blah班级中的一个变量,Class?

4 个答案:

答案 0 :(得分:4)

这种疯狂有一种方法......

class Example
  @foo # class instance variable
  @@bar # class variable

  def fun1
    @baz # instance variable
  end
end

实例变量

实例变量(示例中的@foo@baz)始终以@开头,始终属于自我引用的任何对象:类的对象或表示类的Class对象。类定义或类方法中的实例变量引用与实例方法中的实例变量引用完全不同。

<强>继承
因为实例变量不是由类定义的,所以它们与继承机制无关 - 它们只是在为它们赋值时创建。因此,不会继承类实例变量,它们只是表示类的Class对象的实例变量。

类变量

类变量对类的类方法和实例方法可见,并由类定义本身共享。类变量可以在实例方法,类方法中使用,也可以在类定义本身中,在任何方法之外使用。 类变量总是在引用由封闭类定义语句创建的类对象时进行计算。

类实例变量vs实例变量

类实例变量的缺点是它们不能像实例类变量那样在实例方法中使用。另一个缺点是可能会将它们与普通实例变量混淆。类实例变量优于类变量的优点与子类化现有类时类变量的混乱行为有关:如果类使用类变量,那么任何子类都可以通过更改值来改变类及其所有后代的行为共享类变量。对于使用类实例变量而不是类变量,这是一个强有力的论据。

大部分来自优秀"The Ruby Programming Language" alt text http://ecx.images-amazon.com/images/I/517LDwIEYwL._SL75_.jpg

答案 1 :(得分:4)

人们似乎忽略了该方法是一种类方法。

@blih将是常量Bleh的类Class实例的实例变量。因此:

irb(main):001:0> class Bleh
irb(main):002:1>   def self.bleh
irb(main):003:2>     @blih = "Hello"
irb(main):004:2>     @@blah = "World"
irb(main):005:2>   end
irb(main):006:1> end
=> nil
irb(main):007:0> Bleh.instance_variables
=> []
irb(main):008:0> Bleh.bleh
=> "World"
irb(main):009:0> Bleh.instance_variables
=> ["@blih"]
irb(main):010:0> Bleh.instance_variable_get :@blih
=> "Hello"

@@ blah将作为Bleh的类变量提供:

irb(main):017:0> Bleh.class_variables
=> ["@@blah"]
irb(main):018:0> Bleh.send :class_variable_get, :@@blah
=> "World"

答案 2 :(得分:1)

以符号为前缀的变量是一个类变量,可以在类的实例和类方法中访问。

示例:

class CountEm
  @@children = 0

  def initialize
    @@children += 1
    @myNumber = @@children
  end

  def whoAmI
    "I'm child number #@myNumber (out of #@@children)"
  end

  def CountEm.totalChildren
    @@children
  end
end

c1 = CountEm.new
c2 = CountEm.new
c3 = CountEm.new
c1.whoAmI              # -> "I'm child number 1 (out of 3)"
c3.whoAmI              # -> "I'm child number 3 (out of 3)"
CountEm.totalChildren  # -> 3

取自link text

的示例

答案 3 :(得分:0)

[为清晰起见而编辑]

在你的示例设置中,@ blih在类方法的范围之外是不可见的,因为在类方法中没有实例将实例变量绑定到它。

说到术语,我会说“@@ bloh是Blah类中的类变量”但不是“Blah类类中的变量”。 “阶级”一词保持不变。