在 ruby 中定义全局方法的方法
我正在编写一个小 gem,我想定义一个类似 DSL 的方法,与 Rakedesc 和 task
方法几乎相同强>。
Rake 将它们定义为 Rake::DSL 模块中的私有方法,然后
self.extend Rake::DSL
将模块混合到主对象中? (我是新手,错了请笑)
这样做有什么好处?是因为将这些方法设为私有可以阻止任何其他对象使用它们(即阻止类似 some_obj.desc
的东西)吗?
如果我在 Kernel
中定义方法
module Kernel
private
include Rake::DSL
end
会有什么区别吗?
I'm writing a small gem, and I want to define a DSL-like method, pretty much the same as the desc
and task
methods in Rake.
Rake defines them as private methods in the Rake::DSL
module and then
self.extend Rake::DSL
to mix the module into the main object? (I'm a newbie and go ahead laugh if I'm wrong)
what are the benefits by doing so? is it because making these methods private can prevent any other objects to use them (that is, to prevent something like some_obj.desc
) ?
what if I define the methods in Kernel
module Kernel
private
include Rake::DSL
end
Is there any difference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您在
Kernel
模块中定义私有方法,它将在整个项目中可用。您还将重写项目用于定义 rake 任务的desc
方法。但是,如果您在子模块中编写方法,然后在超类或某个模块中扩展它 - 您可以轻松编写任何类型的 DSL lang,就像您在 Rake 或 RSpec 中看到的那样.PS 使方法
private
阻止其他模块或类(但不是子类)使用它们(但不是owerwrite) - 我的意思是模块嵌套层次结构。If you define private method in
Kernel
module it will be available in the whole project. You will also rewritedesc
method that project use to define rake task. But if you write your methods in your submodule and then extend it in superclass or some module - you can easily write any kind of DSL lang like you might saw inRake
orRSpec
.P.S. Making methods
private
prevents other moludes or classes (but not subclasses) to use them (but not owerwrite) - I mean module nesting hierarchy.只是为了扩展 bor1s 给出的关于 private 方法的答案:
在 ruby 中,您有“私有”和“受保护”方法。在谈论“受保护”方法时,bor1s 所说的是正确的。将方法声明为“私有”还可以防止同一类的其他实例使用该方法。
当您调用“私有”方法时,您不能在其前面使用点 - 您甚至不能使用
self.
,即使使用或省略self
通常具有相同的效果影响。如果您在上面的代码中将“private”更改为“protected”,则不会出现错误。
关于模块:
在
Kernel
中定义方法并使用某个模块中定义的方法扩展Kernel
的最终结果是相同的:在两者中情况下该方法是全局的。使用模块只是更优雅一点,因为它将您的更改分组到一个地方,但我想说这是个人品味的问题。
通常,您不会在内核或对象中包含方法(因为这可能有点危险),但您包含(或扩展)需要这些方法的特定类或对象,在这种情况下,您需要您的方法分组在一个模块中。
甚至 Rake 0.9.0 版本也停止在 Object 中包含 DSL 命令:
Just to extend the answer given by bor1s, about the private methods:
In ruby you have "private" and "protected" methods. What bor1s says, is correct when talking about "protected" methods. Declaring a method "private" additionally prevents other instances of the same class from using the method.
When you call a "private" method, you cannot use a dot in front of it - you cannot even use
self.
, even though using or omittingself
has usually the same effect.If you change 'private' to 'protected' in the code above, no error will be raised.
And about modules:
The final result of defining a method in
Kernel
and extendingKernel
with the method defined in some module is the same: in both cases the method is global.Using a module is just a little more elegant, as it groups your changes in one place, but I would say it's a matter of personal taste.
Usually you do not include methods in Kernel or Object (as it may be a little dangerous), but you include (or extend) a specific class or object which needs these methods, and in this case you need your methods grouped in a module.
Even Rake in version 0.9.0 stopped including the DSL commands in Object: