如何通过包含“嵌套"来使方法添加到类中?使用ActiveSupport :: Concern功能时将模块作为该类的实例方法? [英] How to make methods added to a class by including "nested" modules to be instance methods of that class when using the ActiveSupport::Concern feature?

查看:61
本文介绍了如何通过包含“嵌套"来使方法添加到类中?使用ActiveSupport :: Concern功能时将模块作为该类的实例方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Ruby 1.9.2和Ruby on Rails v3.2.2 gem.在我上一个关于如何在使用Ruby on Rails ActiveSupport :: Concern功能时嵌套"包含模块,我想了解应该在哪里声明要添加到类中的方法,方法是包括嵌套"模块以使该类的这些 instance方法.也就是说,我有以下内容:

I am using Ruby 1.9.2 and the Ruby on Rails v3.2.2 gem. After my previous question on how to "nest" the inclusion of modules when using the Ruby on Rails ActiveSupport::Concern feature, I would like to understand where I should state methods added to a class by including "nested" modules in order to make these instance methods of that class. That is, I have the following:

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块中声明? 有什么区别,我应该从中期待什么?

Should I state def my_method ... end in the "body" / "context" / "scope" of MyModuleB or I should state that in the included do ... end block? What is the difference and what I should expect from that?

推荐答案

混入一个类的模块中的方法将成为该类的实例方法.尽管将它们放在included块中可能会起作用,但没有必要这样做.通过扩展,它可以与模块一起使用,因为您可以在ModuleA中包含ModuleB,并且其所有实例方法都将成为ModuleA上的实例方法,并且一旦ModuleA被包含在类Foo中,则其所有实例方法(包括从B中混入的内容)成为Foo上的实例方法.

Methods in modules that get mixed into a class become instance methods on that class. While putting them in the included block would likely work, there's no need to do it. This, by extension, works with modules, since you can include ModuleB in ModuleA and all its instance methods become instance methods on ModuleA, and once ModuleA is included on class Foo, all its instance methods (including those mixed in from B) become instance methods on Foo.

传统"混合看起来像这样:

A "traditional" mix-in looks like this:

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 ::关注只是通过自动包含名为ClassMethods的模块并通过在包含类的上下文中运行included块来稍微修饰一下,所以等效项是:

ActiveSupport::Concern just pretties this up a bit by automatically including a module named ClassMethods and by running the included block in the context of the including class, so the equivalent is:

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>

这篇关于如何通过包含“嵌套"来使方法添加到类中?使用ActiveSupport :: Concern功能时将模块作为该类的实例方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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