为什么模块的单例方法在混合的下游特征类中不可见? [英] Why a module's singleton method is not visible in downstream eigenclasses where it gets mixed?

查看:135
本文介绍了为什么模块的单例方法在混合的下游特征类中不可见?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我理解常规方法查找路径,即类,超类/模块,一直到BasicObject 。我认为链的单例版本也是如此,但是当您在元链中混合模块时似乎并非如此。我很感激如果有人能解释为什么在以下示例中 Automobile 模块的 banner 方法被调用而不是单例版本当我把这个模块包含在Vehicle的本征类中时。

I understand the regular method lookup path i.e. class, superclass/module, all the way up to BasicObject. I thought it was true for singleton version of the chain also but doesn't seem the case when you mixin a module in the meta-chain. I'd appreciate if someone can explain why in the following example Automobile module's banner method is called instead of its singleton version when I have included this module in Vehicle's eigenclass.

module Automobile
  def banner
    "I am a regular method of Automobile"
  end

  class << self
    def banner
      "I am a singleton method of Automobile"
    end
  end
end

class Vehicle 
  def banner
    "I am an instance method of Vehicle"
  end

  class << self
    include Automobile
    def banner
      puts "I am a singleton method of Vehicle"
      super
    end
  end
end

class Car < Vehicle
  def banner
    "I am an instance method of Car"
  end

  class << self
    def banner
      puts "I am a singleton method of Car"
      super
    end
  end
end

puts Car.banner

# I am a singleton method of Car
# I am a singleton method of Vehicle
# I am a regular method of Automobile


推荐答案

首先,包括不包括你所期望的本征类方法。考虑:

First of all, include does not include eigenclass methods as you might expect. Consider:

module Foo
  class << self
    def do_something
      puts "Foo's eigenclass method does something"
    end
  end
end

module Bar
  include Foo
end

puts Bar.do_something
# undefined method `do_something' for Bar:Module (NoMethodError)

请注意,这与经典定义的类方法的行为一致:

Note that this is consistent with the behavior of classically defined class methods:

module Foo
  def self.do_something
    puts "Foo's class method does something"
  end
end

module Bar
  include Foo
end

puts Bar.do_something
# undefined method `do_something' for Bar:Module (NoMethodError)

一个常见的习惯用法是在子模块中定义类方法,然后在包含模块时触发对 extend 的调用:

A common idiom is to define the class methods in a submodule and then trigger a call to extend when the module is included:

module Foo
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def do_something
      puts "Foo::ClassMethod's instance method does something"
    end
  end
end

module Bar
  include Foo
end

puts Bar.do_something
# Foo::ClassMethod's instance method does something

要注意的第二件事是,你真的将 Automobile 的实例方法包含在<$ c $的本征类中c> Vehicle ,因此 Automobile 的实例方法变为 Vehicle

The second thing to note is, that you are really including the instance methods of Automobile into the eigenclass of Vehicle, thus the instance methods of Automobile turn into (eigen)class methods of Vehicle.

你的 Car 类基本上与这一切无关。这里唯一需要注意的是,类继承也使类方法可用,而 include 则不然。示例:

Your Car class basically has nothing to do with all this. The only thing to note here is, that class inheritance also makes class methods available, whereas include does not. Example:

class Foo
  def self.do_something
    puts "Foo's class method does something"
  end
end

class Bar < Foo
end

puts Bar.do_something
# "Foo's class method does something"

这篇关于为什么模块的单例方法在混合的下游特征类中不可见?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆