Ruby:Meta-class和Class Variables

Dan*_*ark 3 ruby syntax

我一直在看一些文章,说Ruby中的类变量很糟糕.他们建议使用元类(或单例类).这是我的示例代码

class Joe
  class << self # here we're putting methods in Joe's "meta class" 
    attr_accessor :foo
  end
  def self.foo2
  end
  def self.foo2=value
  end
end

puts Joe.singleton_methods
Run Code Online (Sandbox Code Playgroud)

我知道foo和foo2基本相同,但是没有办法将attr_accesor与foo2一起使用.

我不知道怎么回事class << self syntax.是否有某种连接发生,或者......它是什么?这是某种扩展,继承还是猴子修补?

编辑(奖金):虽然我在这里,有没有办法在视图助手上缓存数据?我已经尝试过使用这个类<< self thing,但帮助器方法找不到访问器.

Jul*_*lik 10

class<< foo语法代表"在类的foo的定义".所以,如果你这样做:

class Foo
   class << self
     # class method defined as INSTANCE method
     # the only instance being Foo (the class)
     def boo
       ...
     end
   end
end
Run Code Online (Sandbox Code Playgroud)

这类似于

class Foo
  def self.boo #class method
  end
end
Run Code Online (Sandbox Code Playgroud)

同样,您可以抓取一个单独的对象并使用方法扩展它

class << some_object
   def something # adds a method to some_object ONLY
   end
end
Run Code Online (Sandbox Code Playgroud)

所以,当你在一个类定义中做"自我类"时,你会"升级"到你的"特征"类(或"元类")的定义,在那里你可以在你的"上下文"中调用东西.作为这件事的一个例子,我在".所以你的类的类方法成为实例方法,可以这样定义和处理,而模块包含会影响类方法而不是实例方法.

对于你的情况:

class Joe
  # here we're putting methods in the "class of class"
  class << self
    include ClassMethodsForJoe
    attr_accessor :foo
  end
end
Joe.foo # this is the method we made
Run Code Online (Sandbox Code Playgroud)


sep*_*p2k 6

class << foo打开单例类的foo,这是类foo是唯一的实例(和含蓄地继承了Foo的"真正的"类).所以它是一种扩展(您将方法添加到一个未由该对象的类定义的特定对象).这不是猴子修补,因为你只影响那个对象,而不是那个类的任何其他对象.

请注意,这def foo.bar只是一个快捷方式

class <<foo
  def bar
Run Code Online (Sandbox Code Playgroud)

即它在幕后做同样的事情.这<<<<方法无关.它只是语法的一部分.