Ruby中的模块函数定义
我正在学习1.9.3版的Ruby,遵循关于LearnRubythHardway的教程 似乎在Ruby中的模块函数定义,ruby,Ruby,我正在学习1.9.3版的Ruby,遵循关于LearnRubythHardway的教程 似乎在模块中定义函数时,必须在函数名前面加上模块名,如下所示: module MyStuff def MyStuff.apple() puts "I AM APPLES!" end end MyStuff.apple() 为什么你不能这样做: module MyStuff def apple() puts "I AM APPLES!" end
模块中定义函数时,必须在函数名前面加上模块名,如下所示:
module MyStuff
def MyStuff.apple()
puts "I AM APPLES!"
end
end
MyStuff.apple()
为什么你不能这样做:
module MyStuff
def apple()
puts "I AM APPLES!"
end
end
MyStuff.apple() # this does not work
在Ruby文档中,有一个
我做错了什么?在第一种情况下,您创建了一个类级方法,这意味着您可以直接在类/模块上调用它:MyStuff.apple
。在第二个示例中,您创建了一个实例级方法,这意味着您需要一个实例来访问该方法:
class MyKlazz
include MyStuff
end
obj=MyKlazz.new
obj.apple
模块是将方法、类和常量组合在一起的一种方式。模块为您带来两大好处:
模块提供名称空间并防止名称冲突。
模块实现了mixin功能
摘自
您可以改为:
module MyStuff
def self.apple
puts "I AM APPLES!"
end
end
MyStuff.apple # "I AM APPLES!"
第一个例子
module MyStuff
def MyStuff.apple()
puts "I AM APPLES!"
end
end
。。。之所以有效,是因为您在模块上而不是在模块中定义方法,这就是您在第二个示例中所做的:
module MyStuff
def apple()
puts "I AM APPLES!"
end
end
这类似于你上了一节课,做了同样的事情:
class Conrad
def Conrad.apple()
puts "I AM APPLES"
end
end
您还可以使用def self.apple()
,其含义相同:
class Conrad
def self.apple()
puts "I AM APPLES"
end
end
在这两种情况下,您都是在类本身上定义方法,而不是在该类的实例上定义方法
在一个模块的情况下,如果您扩展了一个类(即Conrad.apple
)或者包含了该类的实例(即Conrad.new.apple
),则定义了该类可用的方法。这是因为您将apple
定义为MyStuff上的实例方法,而且由于MyStuff本身不是一个实例,因此您不能在其上调用apple
要调用苹果
,您有几个选项:
- 明确定义
MyStuff
上的方法,如下所示:
module MyStuff
def MyStuff.apple
puts "I AM APPLES!"
end
end
MyStuff.apple #=> "I AM APPLES!"
但您不必如此明确,可以使用self
而不是MyStuff
:
module MyStuff
def self.apple
puts "I AM APPLES!"
end
end
MyStuff.apple #=> "I AM APPLES!"
- 您可以
将
MyStuff包含到类中,并在该类的实例上调用该方法:
module MyStuff
def apple
puts "I AM APPLES!"
end
end
class Foo; include MyStuff; end
Foo.new.apple #=> "I AM APPLES!"
- 您可以
将
MyStuff扩展到一个类或模块中,包括MyStuff本身:
module MyStuff
extend self
def apple
puts "I AM APPLES!"
end
end
MyStuff.apple #=> "I AM APPLES!"
module OtherStuff; extend MyStuff; end
OtherStuff.apple #=> "I AM APPLES!"
这与类的工作方式非常相似。例如,这也不起作用:
class Foo
def bar; 42; end
end
Foo.bar #=> #<NoMethodError: undefined method `bar' for Foo:Class>
只是因为它是一个模块,没有类。你可能在寻找工厂模式?@BenjaminM将MyStuff设置为类而不是模块不会改变这种行为。
class Foo
def bar; 42; end
def self.bar; 24; end
end
Foo.bar #=> 24
Foo.new.bar #=> 42