【问题标题】:determine the context on which a method runs确定方法运行的上下文
【发布时间】:2011-09-06 07:10:09
【问题描述】:
class Class
  def mixin_ancestors(include_ancestors=true)
    ancestors.take_while {|a| include_ancestors || a != superclass }.
    select {|ancestor| ancestor.instance_of?(Module) }
  end
end

class MyTestClass

end

上面的代码取自How do you list included Modules in a Ruby Class?

我有以下问题。

1) 通过上面代码中的“def mixin_ancestors”,我们定义了一个实例方法。但是做 'a = MyTestClass.new ; a.mixin_ancestors' 表示未定义的方法 mixin_ancestors。

2) 所以我做了‘MyTestClass. mixin_ancestors'。它给了我一份清单。

3) 我认为“祖先”是一种方法。 “祖先”方法在哪个上下文中运行。发现我做了'method(ancestors).owner'但得到了错误-method: [MyTestClass, Object, Kernel, BasicObject] is not a symbol (TypeError).从我自己以前的问题Determine the class to which a method belongs in rails得到这个技巧

4) 就像上面代码中的superclass 方法在哪个上下文上运行的第三点一样。

感谢您的帮助

【问题讨论】:

    标签: ruby


    【解决方案1】:

    1 & 2) 我们正在定义Class 的实例方法,这意味着它将是其他对象的类方法。

    3) 它在Class 对象中运行,因此它是Class 或其祖先之一的方法(实际上在BasicObject 中)

    4) 它在Class 对象(或扩展它的对象)的上下文中运行

    【讨论】:

    • 从你的回答中我的理解是。 mixin_ancestors 中的上下文(即 self)指向 MyTestClass,它是 Class 的一个实例。通过在mixin_ancestors 内部调用ancestorssuperclass 之类的方法,我们实际上是在MyTestClass 本身上调用这些方法。 MyTestClass 在其类级别从Class 获得superclass 方法,它应该在实例级别定义。 MyTestClass 在其类级别从 Module 获得 ancestors 方法,它应该在实例级别定义。
    • 这似乎是正确的。关键是要记住类也是 Ruby 中的对象。
    【解决方案2】:

    在 ruby​​ 中,Class 是类对象的类。在您的示例中, MyTestClass 是类 Class 的一个实例。因此,mixin_ancestor 是这些对象的实例方法。

    在 3) 中,您应该使用 method(:ancestors),但您只需调用它 - 它返回一个数组 - 正如您在输出中看到的 - [MyTestClass, Object, Kernel, BasicObject]

    4) 这里的 self 是 Class 的一个实例

    我强烈推荐你购买http://www.amazon.com/Metaprogramming-Ruby-Program-Like-Pros/dp/1934356476——这本书很好地解释了红宝石!

    【讨论】:

    • mixin_ancestor 是我们所有自定义类的类级方法。但是你已经说了它的实例方法。对吗?
    • 是的,是实例方法(在ruby对象模型中),因为class是Class类的实例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    相关资源
    最近更新 更多