2009-08-13 42 views
3

我一直在看一些文章,说0123'。他们建议使用元类(或单例类)。这是我的示例代码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 

据我所知,foo和foo2的基本上是相同的,虽然没有办法与foo2的使用attr_accesor。

我不明白class << self syntax。是否有某种连接发生,或者......它是什么?这是一种扩展,继承或猴子修补吗?

编辑(奖金):虽然我在这里,有什么办法缓存视图助手的数据?我曾尝试使用这个类< <自己的事情,但辅助方法找不到访问器。

+0

就意识到我不得不关闭级高速缓存,以获得佣工缓存类瓦尔他们的价值观。比我想象的容易。 – 2009-08-13 14:31:09

回答

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 

这类似于

class Foo 
    def self.boo #class method 
    end 
end 

本着同样的精神,你可以抓住一个单独的对象与方法扩展它

class << some_object 
    def something # adds a method to some_object ONLY 
    end 
end 

所以,当你在类定义中做“自我内部类”,你可以跳到“一级” 到你的“特征”类(或“元类”)的定义中,你可以在上下文中调用东西 你的“班级作为我所处的这个东西的一个实例”。所以你的类的 类方法成为实例方法并且可以被定义和对待,并且 模块包含将影响类方法的实例方法。

对于您的情况:

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 
+0

WOW。这是我需要的答案。 – 2009-08-13 18:59:56

+0

很好的答案。你从一开始,'“class << foo”代表“在foo的定义中”。 @ sepp2k在他的回答中说:“class << foo'打开foo的单例类...”(人们经常看到的表达式)。这些对我来说都有点模糊。难道说“阶级”foo使自己等于foo的单身阶级“是否更准确? – 2013-10-04 19:10:02

+0

我已经这样做了,因为一旦你知道什么是“特征类”或“单身类”,你不会问这样的问题。我发现这两个概念只对那些已经知道他们在Ruby中意味着什么的人有用 - 而且我发现他们在解释整个Class类构造时没有帮助。 – Julik 2013-10-05 20:32:47

6

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

注意def foo.bar仅仅是

class <<foo 
    def bar 

即,它在幕后同样的事情的捷径。 <<<<方法无关。这只是语法的一部分。

+0

很酷,谢谢。我用奖金编辑了这个问题(真的不用在另一个问题中再次解释我自己了)......我怎么能在视图助手中使用它。 – 2009-08-13 12:40:51

1

说到在视图帮助器中缓存数据,您可以使用memoization

+0

我现在明白了。但更重要的是,我需要关闭配置中的缓存。 – 2009-08-13 14:25:52