问题描述
我正在写一个小宝石,我想定义一个类似于DSL的方法,与 Rake 中的desc
和task
方法几乎相同.
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在Rake::DSL
模块中,然后在
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)
这样做有什么好处?是因为将这些方法设为私有可以阻止其他任何对象使用它们(也就是说,防止类似some_obj.desc
的东西)?
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
) ?
如果在Kernel
module Kernel
private
include Rake::DSL
end
有什么区别吗?
推荐答案
只是为了扩展bor1s给出的关于 private 方法的答案:
Just to extend the answer given by bor1s, about the private methods:
在红宝石中,您有私有"和受保护"的方法.当谈论保护"方法时,bor1s所说的是正确的.将方法声明为私有"还可以防止同一类的其他实例使用该方法.
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.
调用私有"方法时,不能在其前面使用圆点-甚至不能使用self.
,即使使用或省略self
通常具有相同的效果.
When you call a "private" method, you cannot use a dot in front of it - you cannot even use self.
, even though using or omitting self
has usually the same effect.
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
如果在上面的代码中将专用"更改为受保护",则不会出现任何错误.
If you change 'private' to 'protected' in the code above, no error will be raised.
关于模块:
在Kernel
中定义方法并使用某些模块中定义的方法扩展Kernel
的最终结果是相同的:在两种情况下,该方法都是全局的.
The final result of defining a method in Kernel
and extending Kernel
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.
0.9.0版中的Rake甚至停止了在Object中包含DSL命令:
Even Rake in version 0.9.0 stopped including the DSL commands in Object:
- 不兼容 *更改*:Rake DSL命令(任务",文件"等)是 不再是Object中的私有方法.如果您需要在内部调用"task:xzy" 您的课程中,将Rake :: DSL包含在课程中. DSL仍然可以在以下位置使用 顶层范围(通过扩展Rake :: DSL的顶层对象).
- Incompatible *change*: Rake DSL commands ('task', 'file', etc.) are no longer private methods in Object. If you need to call 'task :xzy' inside your class, include Rake::DSL into the class. The DSL is still available at the top level scope (via the top level object which extends Rake::DSL).
这篇关于在Ruby中定义全局方法的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!