2010-11-18 58 views

回答

10

Object#extend已将公开,否则您将无法使用它。毕竟,它的目的是将一个模块混合到一个对象中,所以你通常将它称为obj.extend(Foo),这对于私有方法来说是不可能的。

Module#include通常只使用的模块体的内部,像这样:

class Bar 
    include Foo 
end 

即它通常被称为没有接收器,所以它不必公开。当然,也不是也是私有的。

我的猜测是,为什么它是私有的是,它是更具侵入性的原因,因为它改变了Bar实例的行为,而Object#extend只改变一个对象。因此,Module#include在某种意义上是“更危险的”,因此是私人的。

我不知道这是否是实际原因,但它与其他类似方法如Module#define_method一致。

+0

它不*有*。如果它是私有的,你可以使用它:'obj.send(:extend,Foo)','obj.instance_eval {extend Foo}',不包括模块class Bar的情况;延伸Foo;结束' – 2012-06-02 20:39:17

+0

@ Marc-AndréLafortune:或者'class << obj;延伸Foo;当然了。就像我说的,这只是一个猜测。 – 2012-06-02 22:26:26

+0

我回复你的第一句话:“Object#extend'必须是公开的,否则你将无法使用它。” – 2012-06-02 23:43:02

1

为了能够在任何时候运行Foo.include(Bar)很可能是非常讨厌的错误的来源。

1

为了补充约尔格W¯¯米塔格的回答,对象#扩展也可用于包括模块的实例方法的类等级中使用(这也将提供给该类的所有实例):

module Foo 
    def bar (baz) 
    end 
end 

class Qux 
    extend Foo 

    bar 'asdf' 
end 
相关问题