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

Tao*_*Tao 7 ruby global

我正在写一个小宝石,我要定义一个DSL样方法,几乎是一样的desc,并task在方法.

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

self.extend Rake::DSL
Run Code Online (Sandbox Code Playgroud)

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

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

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

module Kernel
  private

  include Rake::DSL
end
Run Code Online (Sandbox Code Playgroud)

有什么区别吗?

bor*_*r1s 5

如果在Kernel模块中定义私有方法,它将在整个项目中可用.您还将重写desc项目用于定义rake任务的方法.但是,如果你写你在你的子模块的方法,然后将其在超类或某些模块扩展-你可以很容易地编写任何一种DSL郎就像你可能在看到RakeRSpec.
PS制作方法private可以防止其他moludes或类(但不是子类)使用它们(但不是owerwrite) - 我的意思是模块嵌套层次结构.


Ars*_*en7 3

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

在 ruby​​ 中,您有“私有”和“受保护”方法。在谈论“受保护”方法时,bor1s 所说的是正确的。将方法声明为“私有”还可以防止同一类的其他实例使用该方法。

当您调用“私有”方法时,您不能在其前面使用点 - 您甚至不能使用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
Run Code Online (Sandbox Code Playgroud)

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

关于模块:

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

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

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

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

==版本0.9.0

  • 不兼容的*更改*:Rake DSL 命令(“任务”、“文件”等)不再是对象中的私有方法。如果您需要在类中调用“task :xzy”,请将 Rake::DSL 包含到类中。DSL 在顶级范围内仍然可用(通过扩展 Rake::DSL 的顶级对象)。