【问题标题】:Instance variable in ruby acting like class variableruby 中的实例变量类似于类变量
【发布时间】:2013-11-26 08:12:03
【问题描述】:

@ - 实例变量 @@ - 类变量。

因此,如果没有创建实例,则不应共享实例变量值。但是:

class Add

  def self.add(what)
    if not defined? @a
      @a = 0
    end
    @a += what
    puts @a.to_s
  end
end

Add.add(4)
Add.add(4)

结果:

$ruby main.rb

4
8

为什么?

【问题讨论】:

  • 旁白:@a ||= 0 是if not defined? @a... 的常用替代品。前者是@a = @a || 0 的简写,就像x += 1 是x = x + 1 一样。

标签: ruby variables instance-variables class-variables


【解决方案1】:

Ruby 中的每个类也是一个对象,是Class 类的实例。因此,您的 @a 只是 Add 类的实例变量。

【讨论】:

  • 好吧,那么为什么 Add.add(4) 第二次运行结果为 8。@a 不是全局的
  • @user665967 这是因为@a 是Add 类的实例变量。当您修改某个对象的实例变量值,并且该对象保持不变时,它的实例变量也会保持不变。
  • 如果我错了,请纠正我,所以基本上Class方法中的@variables是实例变量但自动成为Object级别的Class变量
  • @user665967 没有。关键是,在 Ruby 中,每个类也是具有所有后果的对象。这些后果之一是它有自己的实例变量。因此,如果您定义“类方法”并在其中使用实例变量,则该实例变量属于该类实例。而且,重要的是,它不是一个类变量,这是一个有点不同的概念。
  • Marek,我怎么联系你? :)
【解决方案2】:

你在singleton method中所指的@a是Add类的实例变量。

当您将方法定义为def self.add 而不是def add 时,您有效地将方法声明的范围更改为特征类。

【讨论】:

  • 为什么是“特征类”?它是对象本身的实例变量(Add 类),而不是其特征类:(class << Add; self end).instance_variable_get(:@a) # => nil
  • @MarekLipka 请阅读第二个链接中有关类方法的部分,您可能会重新考虑否决票。 tl;dr:所有类方法都包含在特定 Class 实例的 eigenclass 中。
  • 这与“类方法”无关(当然,它们被放置在特定 Class 实例的 eigenclassess 中)。这是关于实例变量的。请考虑我的例子。
  • @MarekLipka - 我明白了,你是对的。留下反对票,这是应得的。谢谢你这一刻的启蒙:)我将删除特征类。
猜你喜欢
  • 2013-03-24
  • 2014-09-21
  • 2014-08-20
  • 2021-07-29
  • 1970-01-01
  • 2015-08-13
  • 2014-10-23
  • 1970-01-01
相关资源
最近更新 更多