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

发布于 2024-08-28 19:35:33 字数 239 浏览 10 评论 0原文

如果我有以下一段 Ruby 代码:

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

@blih 和 @@bloh 到底是什么? @blih 是 Blah 类中的实例变量,@@bloh 是 Blah 类中的类变量,对吗?这是否意味着 @@bloh 是 Blah 类 Class 中的变量?

If I have the following piece of Ruby code:

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

What exactly are @blih and @@bloh? @blih is an instance variable in the class Blah, and @@bloh is a class variable in the class Blah, correct? Does it mean that @@bloh is a variable in Blah's class, Class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

幸福还没到 2024-09-04 19:35:33

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

@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"

People seem to be ignoring that the method is a class method.

@blih will be instance variable of the instance of class Class for the constant Bleh. Hence:

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 will be available as a class variable of Bleh:

irb(main):017:0> Bleh.class_variables
=> ["@@blah"]
irb(main):018:0> Bleh.send :class_variable_get, :@@blah
=> "World"
メ斷腸人バ 2024-09-04 19:35:33

有一种方法可以实现这种疯狂......

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

  def fun1
    @baz # instance variable
  end
end

实例变量

实例变量(示例中的@foo@baz)始终以@开头,并且它们总是属于 self 所指的任何对象:要么是类的对象,要么是代表类的 Class 对象。类定义或类方法中的实例变量引用与实例方法中的实例变量引用完全不同。

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

类变量

类变量对类方法和类的实例方法以及类定义本身可见并由它们共享。类变量可以在实例方法、类方法以及任何方法之外的类定义本身中使用。 类变量始终参考由封闭类定义语句创建的类对象来计算

类实例变量与实例变量

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

其中大部分内容来自优秀的“Ruby 编程语言”
替代文本

There is a method to this madness...

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

  def fun1
    @baz # instance variable
  end
end

Instance variables

Instance variables (@foo and @baz in the example) always begin with @, and they always belong to whatever object self refers to: either an object of the class, or the Class object representing a class. An instance variable reference in a class definition or class method is completely different from an instance variable reference in an instance method.

Inheritance
Because instance variables are not defined by a class, they are unrelated to the inheritance mechanism —they are simply created when a value is assigned to them. Class instance variables, being simply instance variables of the Class object that represents a class, are thus not inherited.

Class variables

Class variables are visible to, and shared by, the class methods and the instance methods of a class, and also by the class definition itself. Class variables can be used in instance methods, class methods, and in the class definition itself, outside of any method. Class variables are always evaluated in reference to the class object created by the enclosing class definition statement.

Class instance variable vs instance variable

A disadvantage of class instance variables is that they cannot be used within instance methods as class variables can. Another disadvantage is the potential for confusing them with ordinary instance variables. An advantage of class instance variables over class variables has to do with the confusing behavior of class variables when subclassing an existing class: if a class uses class variables, then any subclass can alter the behavior of the class and all its descendants by changing the value of the shared class variable. This is a strong argument for the use of class instance variables instead of class variables.

Much of this is from the excellent "The Ruby Programming Language"
alt text

夏尔 2024-09-04 19:35:33

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

示例:

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

示例取自 链接文本

A variable prefixed with two at signs is a class variable, accessible within both instance and class methods of the class.

Example:

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

Example taken from link text

明月松间行 2024-09-04 19:35:33

[为清楚起见进行编辑]

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

说到术语,我会说“@@bloh 是 Blah 类中的一个类变量”,而不是“Blah 类 Class 中的变量”。 “Class”类保持不变。

[edited for clarity]

In your example setting @blih will not be visible outside the scope of your class method, because inside a class method there's no instance to bind an instance variable to it.

Speaking of terminology, I'd say "@@bloh is a class variable in class Blah" but not "variable in Blah's class Class". Class "Class" remains untouched.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文