ruby-on-rails - 使用 ActiveSupport::Concern 功能时,如何通过将 "nested"模块包含为该类的实例方法来将方法添加到类中?

标签 ruby-on-rails ruby methods module nested

我正在使用 Ruby 1.9.2 和 Ruby on Rails v3.2.2 gem。在我之前关于 how to “nest” the inclusion of modules when using the Ruby on Rails ActiveSupport::Concern feature 的问题之后,我想了解应该在哪里通过包含“嵌套”模块来声明添加到类中的方法,以便创建该类的这些实例方法。也就是说,我有以下内容:

class MyClass < ActiveRecord::Base
  include MyModuleA
end

module MyModuleA
  extend ActiveSupport::Concern

  included do
    include MyModuleB
  end
end

module MyModuleB
  extend ActiveSupport::Concern

  included do
    # def my_method
    #   ...
    # end
  end

  # def my_method
  #   ...
  # end
end

应该我应该在MyModuleB的“body”/“context”/“scope”中声明def my_method ... end还是我应该在 included do ... end block 中声明这一点吗? 有什么区别以及我应该从中期待什么?

最佳答案

混合到类中的模块中的方法将成为该类的实例方法。虽然将它们放入 included block 中可能会起作用,但没有必要这样做。通过扩展,这适用于模块,因为您可以将 ModuleB 包含在 ModuleA 中,并且其所有实例方法都成为 ModuleA 上的实例方法,并且一旦ModuleA 包含在 Foo 类中,它的所有实例方法(包括从 B 混合而来的)都成为 Foo 上的实例方法。

“传统”混合看起来像这样:

module Mixin
  def self.included(klass)
    klass.send :extend, ClassMethods
    klass.some_class_method
  end

  module ClassMethods
    def some_class_method
      puts "I am a class method on #{self.inspect}"
    end
  end

  def some_instance_method
    puts "I am an instance method on #{self.inspect}"
  end
end

class Foo
  include Mixin
end

Foo.new.some_instance_method

# Output:
# I am a class method on Foo
# I am an instance method on #<Foo:0x00000002b337e0>

ActiveSupport::Concern 只是通过自动包含名为 ClassMethods 的模块并在包含类的上下文中运行 included block 来美化这一点,因此等价的是:

module Mixin
  extend ActiveSupport::Concern

  included do
    some_class_method
  end

  module ClassMethods
    def some_class_method
      puts "I am a class method on #{self.inspect}"
    end
  end

  def some_instance_method
    puts "I am an instance method on #{self.inspect}"
  end
end

class Foo
  include Mixin
end

Foo.new.some_instance_method

# Output:
# I am a class method on Foo
# I am an instance method on #<Foo:0x000000034d7cd8>

关于ruby-on-rails - 使用 ActiveSupport::Concern 功能时,如何通过将 "nested"模块包含为该类的实例方法来将方法添加到类中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13110749/

相关文章:

ruby - 具有双高清和 "space in name"错误的 RVM

ruby-on-rails - 是否有适用于 Ruby 或 Rails 的类似 iPython 的 shell?

scala - 成员函数默认为虚函数

ruby-on-rails - 模型可以访问 Rails 中的文本文件吗?

javascript - Google map V3 InvalidValueError Rails 5

mysql - Activerecord 对 sql 的转换不正确

ruby-on-rails - 为什么在一个日期上加上和减去 2 个月不会返回相同的日期?

ruby - 负对象 ID

class - 检查一个圆是否包含在另一个圆中

c# - 有没有一种巧妙、有效的方法可以用两个不同的参数调用同一个方法两次?