【发布时间】:2011-05-11 23:02:57
【问题描述】:
在 ruby 上,include 是私有的,而 Object#extend 是公开的原因是什么?
【问题讨论】:
标签: ruby metaprogramming language-design access-specifier
在 ruby 上,include 是私有的,而 Object#extend 是公开的原因是什么?
【问题讨论】:
标签: ruby metaprogramming language-design access-specifier
Object#extend 必须公开,否则您将无法使用它。毕竟,它的目的是把一个模块混入一个对象中,所以你通常会称它为obj.extend(Foo),这对于私有方法是不可能的。
Module#include 通常只在模块体内使用,如下所示:
class Bar
include Foo
end
即它通常在没有接收者的情况下调用,因此不必公开。当然,它也没有必须是私有的。
我的猜测是它是私有的原因是它更具侵入性,因为它改变了Bar 的每个 实例的行为,而Object#extend 只改变了一个对象。因此,Module#include 在某种意义上“更危险”,因此被设为私有。
我不知道这是否是真正的原因,但它与Module#define_method等其他类似方法一致。
【讨论】:
obj.send(:extend, Foo),obj.instance_eval{ extend Foo },不包括模块 class Bar; extend Foo; end 的情况
class << obj; extend Foo; end。就像我说的,这只是一个猜测。
Object#extend 必须是公开的,否则你将无法使用它。”
class << obj; extend Foo; end。
Module#include(和 Module#prepend)在 v2.1 中公开。
能够在任何时候运行Foo.include(Bar) 很可能是非常讨厌的错误的来源。
【讨论】:
为了补充 Jörg W Mittag 的回答,Object#extend 也可用于包含要在类级别使用的模块实例方法(该类的所有实例也可以使用):
module Foo
def bar (baz)
end
end
class Qux
extend Foo
bar 'asdf'
end
【讨论】: