将模块包含到ruby方法中

将模块包含到ruby方法中,ruby,methods,module,include,Ruby,Methods,Module,Include,我已经使用模块来扩展类功能。但是我突然想知道,如果我将模块直接包含到类的方法中,而不是像这样包含到类中,是否可以: 原始用途: 型号: class Baby include CommunicationSkills def initialize(name) @name = name end end 模块: module CommunicationSkills def greet "Hi" end end module GreetLanguages de

我已经使用模块来扩展类功能。但是我突然想知道,如果我将模块直接包含到类的方法中,而不是像这样包含到类中,是否可以:

原始用途:

型号:

class Baby
  include CommunicationSkills

  def initialize(name)
    @name = name
  end
end
模块:

module CommunicationSkills
  def greet
    "Hi"
  end
end
module GreetLanguages
  def spanish
    "Hola"
  end

  def english
     "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 CommunicationSkills
  def greet
    "Hi"
  end
end
module GreetLanguages
  def spanish
    "Hola"
  end

  def english
     "Hi"
  end
end
因此:

我知道这是可能的,但从概念上讲是对的

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”
,而是代表字符串
“西班牙语”
“英语”
的变量语言

所以,
include
没有直接的接收器,所以它基本上是在
self
上调用它。在类
Baby
的实例方法中使用
include
时,您将模块添加到
ivan
的实例中,这没有任何意义

extend
将模块添加为类方法,因此实例本身可以调用该方法。因此,我们正在将模块添加到
ivan
的实例中,现在我们可以调用
greet


我真的看不出有什么理由这么做,最好在课堂上使用
include

该模块包含两个实例方法。您希望将它们发送到一个实例,而不是类,因此您需要
包含模块(使用),而不是
扩展它。要从实例方法中调用
include
self
作为实例),必须将
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(:西班牙语)

如果希望在将模块中的实例方法转换为类方法时将它们引入类中,则可以使用

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
是不常见的。我不知道人们为什么要这样做。

我无法重现这一点。我在include行得到一个错误:
>ivan.greet('spanish')NoMethodError:undefined method
include'for#`是的,关于@davidhu2000,我更新了代码。很抱歉。
greet
方法在
Baby
的实例上抛出了一个错误。我正在调用
greet(西班牙语)
,我得到的错误是:
未定义的局部变量或方法
spanish'作为main:Object(NameError)`。您需要在引号中加上西班牙语,比如
greet('spanish')
,因为您传递的是字符串,不是一个变量,但是,如果调用模块需要很多时间,那么我想在方法内部验证之后使用它,而不是针对类的每个实例。我的意思是,在验证实例方法内部的某些内容之后,是否要使用此方法@davidhu2000是否已添加到每个实例的singleton类中?