在ruby中定义全局方法的方法

我正在写一个小gem,我想定义类似DSL的方法,与Rake中desctask方法几乎相同。

Rake将它们定义为Rake::DSL模块中的私有方法然后

 self.extend Rake::DSL 

将模块混合到主对象中? (我是个新手,如果我错了就继续笑)

这样做有什么好处? 是因为将这些方法设为私有可以阻止任何其他对象使用它们(也就是说,为了防止像some_obj.desc这样的some_obj.desc )?

如果我在Kernel定义方法怎么办?

 module Kernel private include Rake::DSL end 

有什么区别吗?

只是为了扩展bor1s给出的答案,关于私有方法:

在ruby中,你有“私人”和“受保护”的方法。 在讨论“受保护”方法时,bor1s所说的是正确的。 声明方法“private”还会阻止同一类的其他实例使用该方法。

当你调用“私人”方法时,你不能在它前面使用一个点 – 你甚至不能使用self. 即使使用或省略self通常具有相同的效果。

 class Xyzzy private def foo puts "Foo called" end public def do_it foo # <= Is OK self.foo # <= raises NoMethodError end end Xyzzy.new.do_it 

如果您在上面的代码中将“private”更改为“protected”,则不会引发任何错误。

关于模块:

Kernel中定义方法并使用某个模块中定义的方法扩展Kernel的最终结果是相同的:在这两种情况下,该方法都是全局的。

使用模块只是更优雅,因为它将您的更改分组到一个地方,但我会说这是个人品味的问题。

通常,您不在Kernel或Object中包含方法(因为它可能有点危险),但您包含(或扩展)需要这些方法的特定类或对象,在这种情况下,您需要将您的方法分组到模块中。

甚至版本0.9.0中的Rake也停止在Object中包含DSL命令:

==版本0.9.0

  • 不兼容 *更改*:Rake DSL命令('task','file'等)不再是Object中的私有方法。 如果你需要在课堂上调用'task:xzy',请在课程中加入Rake :: DSL。 DSL仍然可以在顶级范围内使用(通过扩展Rake :: DSL的顶级对象)。

如果在Kernel模块中定义私有方法,它将在整个项目中可用。 您还将重写项目用于定义rake任务的desc方法。 但是如果你在你的子模块中编写你的方法,然后在超类或某个模块中扩展它 – 你可以轻松编写任何类型的DSL lang,就像你在RakeRSpec看到的那样。
PS使方法private防止其他moludes或类(但不是子类)使用它们(但不是owerwrite) – 我的意思是模块嵌套层次结构。