【问题标题】:Variables declared within `class << self`在 `class << self` 中声明的变量
【发布时间】:2013-05-12 22:48:06
【问题描述】:

我应该如何考虑在任何方法定义之外的class &lt;&lt; self 块中声明的@variable?看看这个脚本的最后一部分:

class VarDemo
  @@class_var_1 = "This is @@class_var_1"
  @class_i_var = "This is a @class_i_var"

  attr_accessor :ivar_1
  attr_accessor :ivar_2

  def initialize(ivar_1: "base_ivar_1", ivar_2: "base_ivar_2")
    @@class_var_2 = "This is @@class_var_2, defined within an instance method"
    @ivar_1 = ivar_1
    @ivar_2 = ivar_2
    VarDemo.class_i_var_2 = "class_i_var_2 defined through accessor on the class object"
  end

  def print_vars
    puts "from within an instance method. here 'self' is: #{self}"

    # test instance variables
    puts "@ivar_1: #{@ivar_1}"
    puts "@ivar_2: #{@ivar_2}"
    puts "self.ivar_1: #{self.ivar_1}"
    puts "self.ivar_2: #{self.ivar_2}"
    puts "ivar_1: #{ivar_1}"
    puts "ivar_2: #{ivar_2}"

    # test class variables
    puts "@@class_var_1: #{@@class_var_1}"
    puts "@@class_var_2: #{@@class_var_2}"

    # test class instance variables (ivars on the class object)
    puts "VarDemo.class_i_var: #{VarDemo.class_i_var}"
    puts "VarDemo.class_i_var_2: #{VarDemo.class_i_var_2}"
    puts "@class_i_var: #{@class_i_var} (should be empty, as it doesn't exist in the instance"

    puts "self.class_i_var: #{self.class_i_var}"
  rescue Exception => ex
    puts "self.class_i_var is not defined in this scope (self is an instance)"
  end

  # open the class object
  class << self
    attr_accessor :class_i_var
    attr_accessor :class_i_var_2

    @what_about_this = "what would this be?"

    attr_accessor :what_about_this

    def print_what_about_this
      puts "@what_about_this: #{@what_about_this}" # is empty
      puts "VarDemo.what_about_this: #{VarDemo.what_about_this}" # is empty
    end
  end

end

@what_about_this 是什么?它在哪里定义?它只是解释器让我做的事情,但没有任何实际用途吗?我以为它是在Class 上定义的,但事实并非如此。

【问题讨论】:

  • 你好安德鲁。感谢您的链接!我已经知道从根 Exception 进行救援由于某些原因(阻止 unix 信号)是不好的,并且在“实际使用”代码中,我通常对错误采取更细粒度的控制......但你链接的答案非常确实有用。我不知道eval 问题...很高兴知道。
  • 在非“实际使用”代码中执行此操作只会使其更有可能在“实际”代码中意外执行此操作,或者稍后忘记更改。

标签: ruby oop


【解决方案1】:

class &lt;&lt;self 实际上并没有打开 self 的类;它打开了 self 的 singleton 类。 (描述为here。)

class Foo
  class << self
    @bar = "baz"   # not really inside Class here.
  end
end

Foo.singleton_class.instance_eval { @bar }  #baz

Yehuda Katz 有一个很好的article,它描述了这里真正发生的事情。

【讨论】:

  • 是的,我知道。它会打开当前范围内 self 所指的任何单例类。如果在类 (MyClass) 主体中使用,self 等效于 MyClass。任何类(StringMyClass、ecc)都只是Class 类的一个实例,这样您就可以在类上声明类实例变量……因为它们也是对象。
  • 不管怎样,你知道@what_about_this这个变量吗?
  • 您询问了实例变量的去向。我告诉过你 - 它在你班级的单例班(也就是它的 eigenclass)上,它与Class 本身相同。
  • VarDemo.singleton_class.instance_eval { @what_about_this } 瞧!
  • 谢谢马克。 Katz 的链接非常有用。
猜你喜欢
  • 2016-11-05
  • 2015-04-28
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 2014-03-19
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多