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

时间:2018-03-04 16:59:44

标签: ruby module mixins

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

在Ruby Fiddle上运行:

<html>

<head>
  <meta charset="UTF-8">
  <title>Untitled Document</title>
</head>

<body>
  <div class="gallery" align="center">
    <div class="gallery-item">
      <img src="https://media.springernature.com/full/nature-static/assets/v1/image-assets/531S56a-i1.jpg">
      <div class="img-overlay">
        <div class="gallery-text">
          <div class="gallery-title">FASHION MODELS</div>
          <div class="gallery-tags">Mobile, Web</div>
        </div>
      </div>
    </div>
    <div class="gallery-item">
      <img src="http://www.samoaobserver.ws/images/cache/600x400/crop/images%7Ccms-image-000009332.jpg">
      <div class="img-overlay">
        <div class="gallery-text">
          <div class="gallery-title">FASHION MODELS</div>
          <div class="gallery-tags">Mobile, Web</div>
        </div>
      </div>
    </div>
    <div class="gallery-item">
      <img src="http://www.worddive.com/blog/wp-content/uploads/2014/06/nature-and-environment-course.jpg">
      <div class="img-overlay">
        <div class="gallery-text">
          <div class="gallery-title">FASHION MODELS</div>
          <div class="gallery-tags">Mobile, Web</div>
        </div>
      </div>
    </div>
  </div>

</body>

</html>

这会不断返回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?

我对mixin应该如何运作tutorialspoint的理解让我觉得我应该能够有效地调用NoMethodError: undefined method 'meow?' for #,并获得与调用e.meow?时相同的结果。

以下是RubyFiddle中的代码。

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

2 个答案:

答案 0 :(得分:1)

事实证明,在定义spring.data.mongodb.host=<server_address> spring.data.mongodb.port=27017 spring.data.mongodb.user=<username> 时,我过于具体。如果你想将模块用作mixin,你会想要更一般地定义你的方法,而不是关于它们的特定模块命名空间。

所以而不是

Cats.meow?

应该是

def Cats.meow?
  ...
end

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

糟糕。

答案 1 :(得分:1)

作为在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!"