NoMethodError:未定义的方法`喵?'为# - ruby mixin失败了吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NoMethodError:未定义的方法`喵?'为# - ruby mixin失败了吗?相关的知识,希望对你有一定的参考价值。

我正在玩一些ruby mixins的基础知识,并且由于某种原因无法访问我的模块中的行为。

在Ruby Fiddle上运行它:

module Cats
  MEOW = "meow meow meow"

  def Cats.meow?
    return Cats::MEOW
  end
end

class Example
  include Cats

  def sample
    return "it's a sample"
  end
end

e = Example.new
puts e.sample
puts e.meow?

这使得NoMethodError: undefined method 'meow?' for #不断回归

我对如何使用tutorialspoint的mixins的理解让我觉得我应该能够有效地调用e.meow?,并获得与调用Cats.meow?相同的结果。

这是RubyFiddle中的代码。

令人难以置信的基本,但任何想法,我在这里跌倒?

答案

事实证明,在定义Cats.meow?时我过于具体。如果要将模块用作mixin,则需要更一般地定义方法,而不是针对其特定的模块命名空间。

而不是

def Cats.meow?
  ...
end

应该是的

def meow?
  ...
end 

这使您可以调用e.meow?,因为方法定义不再仅限于Cats命名空间。

哎呦。

另一答案

作为在Ruby中使用includeextend的一般规则:

如果要将模块用作命名空间

module Outer
  module Inner
    def self.my_method
      "namespaced method!"
    end
  end
end

你使用它像Outer::Inner::my_methodOuter::Inner.my_method

如果你想将模块用作mixin:

# In some cases it makes sense to use names ending in -able, since it expreses
# what kind of messages you can send to an instance or class that mixes
# this module in.
# Like Devise's Recoverable module: https://github.com/plataformatec/devise/blob/f39c6fd92774cb66f96f546d8d5e8281542b4e78/lib/devise/models/recoverable.rb#L24

module Fooable
  def foo
    "#{self} has been foo'ed!"
  end
end

然后你可以include它(Something的实例获得#foo):

class Something
  include Fooable # Now Something.new can receive the #foo message.
end

Something.new.foo
=> "#<Something:0x0055c2dc104650> has been foo'ed!"

或者你可以扩展它(Something本身将#foo作为类消息获得):

class Something
  extend Fooable # Now Something can receive the #foo message.
end

Something.foo
=> "Something has been foo'ed!"

以上是关于NoMethodError:未定义的方法`喵?'为# - ruby mixin失败了吗?的主要内容,如果未能解决你的问题,请参考以下文章

NoMethodError:AjaxDatatablesRails:Module 的未定义方法“配置”

NoMethodError:升级到 rake 11 后未定义方法“last_comment”

Rails - RSpec NoMethodError:未定义的方法

Rails 类给出 NoMethodError 未定义的方法“每个”

Rspec 测试:NoMethodError - nil.Nilclass 的未定义方法“id”

NoMethodError:未定义的方法“has_attached_file”