将模块包含到方法ruby中
我已经使用模块来扩展类功能。但突然间我不知道它是确定的,如果我直接包括模块插入类的方法,而不是为这样的类:将模块包含到方法ruby中
原来使用:
型号:
class Baby
include CommunicationSkills
def initialize(name)
@name = name
end
end
模块:
module CommunicationSkills
def greet
"Hi"
end
end
所以我们可以:
ivan = Baby.new('Iván')
ivan.greet
=> "Hi"
但如果我有直接的方法里面的方法:
class Baby
def initialize(name)
@name = name
end
def greet(language)
extend GreetLanguages
send(language)
end
end
模块:
module GreetLanguages
def spanish
"Hola"
end
def english
"Hi"
end
end
这样:
ivan = Baby.new('Iván')
ivan.greet('spanish')
=> "Hola"
ivan.greet('english')
=> "Hi"
我知道这是更多钞票,但在概念上它是对?
该模块包含两个实例方法。你想把它们发送给一个实例,而不是类,所以你需要include
该模块(使用Module#include),而不是extend
它。要从实例方法(实例为self
)内调用include
,必须将include
发送到self.class
。因此您需要编写以下内容。
class Baby
def initialize(name)
@name = name
end
def greet(language)
self.class.include GreetLanguages
send(language)
end
end
ivan = Baby.new('Iván')
ivan.greet('spanish')
#=> "Hola"
Baby.instance_methods.include?(:english) && Baby.instance_methods.include?(:spanish)
#=> true
ivan.greet('english')
#=> "Hi"
您也可以写ivan.greet(:spanish)
。
如果您希望将模块中的实例方法转换为类方法,并将它们带入类中,则可以使用Object#extend。
class Baby
def initialize(name)
@name = name
end
def extend_mod
self.class.extend GreetLanguages
end
end
Baby.new('Iván').extend_mod
Baby.methods.include?(:spanish) && Baby.methods.include?(:english) #=> true
Baby.spanish
#=> "Hola"
Baby.english
#=> "Hi"
是不寻常的,从一个实例方法中调用include
或extend
。我不知道为什么要这样做。
module GreetLanguages
def spanish
"Hola"
end
def english
"Hi"
end
end
class Baby
def initialize(name)
@name = name
end
def greet(language)
extend GreetLanguages
send(language)
end
end
所以,我设法使用extend
得到这个代码工作。此外,在您的send
函数中,您需要删除引号,因为您没有发送字符串"language"
,所以发送代表字符串"spanish"
或"english"
的变量语言。
因此,include
没有直接的接收器,所以它基本上调用它在self
。当您在类Baby
的实例方法中使用include
时,您正在将模块添加到ivan
的实例,这没有任何意义。
extend
将该模块添加为类方法,因此实例本身可以调用该方法。所以,我们将模块添加到ivan
的实例中,现在我们可以调用greet
。
我真的看不出有什么理由要这样做,所以最好在课堂上使用include
。
'greet'方法在'Baby'的一个实例上抛出一个错误。 –
错误是什么?并告诉我你的代码 – davidhu2000
我打电话给'问候(西班牙语)',我得到的错误是:未定义的局部变量或方法'西班牙语为主:对象(NameError)'。 –
我不能重现这一点。 –
我在include行发现错误:'> ivan.greet('spanish') NoMethodError:undefined方法'include'for#' –
Ryan
是的,关于@ davidhu2000我更新了代码。对不起。 –