Upgrade to Pro — share decks privately, control downloads, hide ads and more …

extend ActiveSupport::Concernの魔術を理解する

yukihirop
January 08, 2017

extend ActiveSupport::Concernの魔術を理解する

rails/activesupport-4.1.0に使われている
extend ActiveSupport::Concernの機能を全て図解した。

yukihirop

January 08, 2017
Tweet

Other Decks in Programming

Transcript

  1. "DUJWF4VQQPSU$PODFSOϞδϡʔϧ module ActiveSupport module Concern class MultipleIncludedBlocks < StandardError #:nodoc:

    def initialize super "Cannot define multiple 'included' blocks for a Concern" end end def self.extended(base) #:nodoc: base.instance_variable_set(:@_dependencies, []) end def append_features(base) if base.instance_variable_defined?(:@_dependencies) base.instance_variable_get(:@_dependencies) << self return false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) end end def included(base = nil, &block) if base.nil? raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block) @_included_block = block else super end end end end
  2. module ActiveSupport module Concern class MultipleIncludedBlocks < StandardError #:nodoc: def

    initialize super "Cannot define multiple 'included' blocks for a Concern" end end def self.extended(base) #:nodoc: base.instance_variable_set(:@_dependencies, []) end def append_features(base) if base.instance_variable_defined?(:@_dependencies) base.instance_variable_get(:@_dependencies) << self return false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) end end def included(base = nil, &block) if base.nil? raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block) @_included_block = block else super end end end end ϙΠϯτ͸ͭ "DUJWF4VQQPSU$PODFSOΛFYUFOEͨ͠ ޙɺ.ϞδϡʔϧͷΠϯελϯεม਺ʹɺ !@EFQFOEFODJFT<> ͕อ࣋͞ΕΔɻ TFMG"DUJWF4VQQPSU$PODFSO CBTF. module M extend ActiveSupport::Concern end  FYUFOEͨ͠Ϟδϡʔϧ͸Πϯελϯεม਺!@EFQFODEFDJFTΛอ࣋ .Ϟδϡʔϧ . !@EFQFOEFODJFT<>
  3. module ActiveSupport module Concern class MultipleIncludedBlocks < StandardError #:nodoc: def

    initialize super "Cannot define multiple 'included' blocks for a Concern" end end def self.extended(base) #:nodoc: base.instance_variable_set(:@_dependencies, []) end def append_features(base) … end def included(base = nil, &block) … end end end ϙΠϯτ͸ͭ  FYUFOEͨ͠Ϟδϡʔϧ͸Ϋϥε֦ுʹΑΓɺ "DUJWF4VQQPSU$PODFSOϞδϡʔϧʹॴଐ͍ͯ͠Δ BQQFOE@GFBUVSFTͱJODMVEFEΛΫϥεɾϝιουͰ ݺͼग़ͤΔΑ͏ʹͳΔɻ TJOHMFUPO@DMBTT "DUJWF4VQQPSU$PODFSO Ϟδϡʔϧ . JODMVEFE BQQFOE@GFBUVSFT BODFTUPST .FYUFOE"DUJWF4VQQPSU$PODFSO .ಛҟΫϥε ˌ$ JODMVEFE BQQFOE@GFBUVSFT ˒ ˒ ˒Ϋϥε֦ுͷͨΊݺ΂Δ .Ϟδϡʔϧ . !@EFQFOEFODJFT<> module M extend ActiveSupport::Concern end
  4. ࢖͍ํɹ ػೳ͸̏ͭ͋Δ Πϯελϯεɾϝιου֦ு Ϋϥεɾϝιου֦ு module M1 extend ActiveSupport::Concern def m1_instance_method;

    end; end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end module M1 extend ActiveSupport::Concern def m1_instance_method; end; module ClassMethods def m1_extend_method; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; module ClassMethods def m2_extend_method; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end ·ͣ͸͜͜ͷ આ໌Λ͢Δ ϝιου࣮ߦɾ஫ೖ JODMVEF͞Εͨޙʹ࣮ߦ module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; included do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ࣮ࡍʹ࣮ߦ͞ΕΔ FYUFOE"DUJWF4VQQPSU$PODFSO ͍ͯ͠Δ͔Β࢖͑Δ FYUFOE"DUJWF4VQQPSU$PODFSO ͍ͯ͠Δ͔Β࢖͑Δ FYUFOE"DUJWF4VQQPSU$PODFSO ͍ͯ͠Δ͔Β࢖͑Δ
  5. ࢖͍ํɹ େ͖̎ͭ͘ͷܕɺ௚ྻܕͱฒྻܕ͕͋Δ ௚ྻܕ ฒྻܕ module M1 extend ActiveSupport::Concern def m1_instance_method;

    end; end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end module M1 extend ActiveSupport::Concern def m1_instance_method; end; end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 include M1 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end
  6. ࢖͍ํɹ େ͖̎ͭ͘ͷܕɺ௚ྻܕͱฒྻܕ͕͋Δ ௚ྻܕ ฒྻܕ .Ϟδϡʔϧ !@EFQFOEFODJFT .Ϟδϡʔϧ !@EFQFOEFODJFT<. .>JODMVEF͢Δॱ൪Ͱ.BODFTUPSTͷ݁Ռ͕มΘΔ .Ϟδϡʔϧ

    !@EFQFOEFODJFT<> .Ϟδϡʔϧ !@EFQFOEFODJFT<> ٙࣅJODMVEF ٙࣅJODMVEF JODMVEF FY FY FY .Ϟδϡʔϧ !@EFQFOEFODJFT<.> .Ϟδϡʔϧ !@EFQFOEFODJFT .Ϟδϡʔϧ !@EFQFOEFODJFT<.> .Ϟδϡʔϧ !@EFQFOEFODJFT<> ٙࣅJODMVEF ٙࣅJODMVEF JODMVEF FY FY FY "DUJWF4VQQPSU$PODFSOͰFYUFOEͨ͠Ϟδϡʔϧ FY
  7. ࢖͍ํɹ ฒྻܕ͸݁ہɺ݁Ռతʹ௚ྻܕʹม׵͞ΕΔ ฒྻܕ ௚ྻܕ .Ϟδϡʔϧ !@EFQFOEFODJFT JODMVEF .Ϟδϡʔϧ !@EFQFOEFODJFT<. .>

    FY .Ϟδϡʔϧ !@EFQFOEFODJFT<> FY .Ϟδϡʔϧ !@EFQFOEFODJFT<> FY .Ϟδϡʔϧ !@EFQFOEFODJFT ٙࣅJODMVEF ٙࣅJODMVEF JODMVEF .Ϟδϡʔϧ !@EFQFOEFODJFT<> FY .Ϟδϡʔϧ !@EFQFOEFODJFT<> FY .Ϟδϡʔϧ !@EFQFOEFODJFT JODMVEF͢Δॱ൪Ͱ.BODFTUPSTͷ݁Ռ͕มΘΔ !@EFQFOEFODJFT<. .>ͷॱ൪ͳΒ JODMVEF.ͷJODMVEFͷํ͕ઌ FY ٙࣅJODMVEF ٙࣅJODMVEF ฒྻ㱺௚ྻม׵ FY "DUJWF4VQQPSU$PODFSOͰFYUFOEͨ͠Ϟδϡʔϧ
  8. ࢖͍ํ BQQFOE@GFBUVSFTͷجຊͷػೳ͚ͩ࢖͏ʣ௚ྻܕ module M1 extend ActiveSupport::Concern def m1_instance_method; end; end

    module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end جຊతͳྲྀΕ͸ "DUJWF4VQQPSU$PODFSOϞδϡʔϧΛFYUFOEͨ͠.Ϟ δϡʔϧΛ.Ϟδϡʔϧ͕JODMVEF͢Δ͜ͱͰ.Ϟδϡʔϧ ͕Ϋϥε֦ுͰಘͨBQQFOE@GFBUVSFTΛணՐɻ ͜ΕΛ܁Γฦ͠࠷ޙɺNPEVMF.ʹJODMVEF.͞Εͨ࣌ʹɺ ͲͷΑ͏ʹ֤NPEVMF͕JODMVEF͞Ε͍ͯ͘ͷ͔ݟΔɻ ݁࿦͸͜͏ͳΔ ͜Ε͸Ͳ͏͍͏͜ͱͳͷ͔ͦΕΛཧղ͍͖͍ͯͨ͠ɻ include Mˎ extend ActiveSupport::Concern ॱ൪ٯͰ΋ྑ͍ɻ
  9. module ActiveSupport module Concern class MultipleIncludedBlocks < StandardError #:nodoc: def

    initialize super "Cannot define multiple 'included' blocks for a Concern" end end def self.extended(base) #:nodoc: base.instance_variable_set(:@_dependencies, []) end def append_features(base) if base.instance_variable_defined?(:@_dependencies) base.instance_variable_get(:@_dependencies) << self return false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) end end def included(base = nil, &block) if base.nil? raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block) @_included_block = block else super end end end end ͜͜ͷ෦෼ͷػೳΛݟ͍ͯ͘
  10. "DUJWF4VQQPSU$PODFSOΛFYUFOEͨ͠ޙɺ.ϞδϡʔϧͷΠϯελ ϯεม਺ʹɺ!@EFQFOEFODJFT<>͕อ࣋͞ΕΔɻ ActiveSupport::ConcernͷΠϯελϯεɾϝιου͕M1Ϟδϡʔϧ ͷΫϥεɾϝιουʹͳΔɻ(Ϋϥε֦ு) module M1 extend ActiveSupport::Concern def m1_instance_method;

    end; end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end
  11. "DUJWF4VQQPSU$PODFSOΛFYUFOEͨ͠ޙɺ.ϞδϡʔϧͷΠϯελ ϯεม਺ʹɺ!@EFQFOEFODJFT<>͕อ࣋͞ΕΔɻ "DUJWF4VQQPSU$PODFSOͷΠϯελϯεɾϝιου͕.Ϟδϡʔϧͷ ΫϥεɾϝιουʹͳΔɻ Ϋϥε֦ு module M1 extend ActiveSupport::Concern def

    m1_instance_method; end; end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end
  12. module M1 extend ActiveSupport::Concern def m1_instance_method; end; end module M2

    extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end JODMVEF.Λ͢Δͱɺ.BQQFOE@GFBUVSFT . ͕ணՐɻ .Ϟδϡʔϧ͸!@EFQFOEFODJFT͕ఆٛ͞Ε͍ͯΔ͔Βͦ͜ʹ.Φϒ δΣΫτΛ֨ೲ
  13. module M1 extend ActiveSupport::Concern def m1_instance_method; end; end module M2

    extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end "DUJWF4VQQPSU$PODFSOΛFYUFOEͨ͠ޙɺ.ϞδϡʔϧͷΠϯελ ϯεม਺ʹɺ!@EFQFOEFODJFT<>͕อ࣋͞ΕΔɻ "DUJWF4VQQPSU$PODFSOͷΠϯελϯεɾϝιου͕.Ϟδϡʔϧͷ ΫϥεɾϝιουʹͳΔɻ Ϋϥε֦ு
  14. module M1 extend ActiveSupport::Concern def m1_instance_method; end; end module M2

    extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end .Ϟδϡʔϧ͕JODMVEF.Λ͢Δͱɺ.BQQFOE@GFBUVSFT . ͕ ணՐɻ.Ϟδϡʔϧ͸!@EFQFOEFODJFT͕ఆٛ͞Ε͍ͯΔ͔Β ͦ͜ʹ.ΦϒδΣΫτΛ֨ೲ .Ϟδϡʔϧ͕JODMVEF.Λ͢Δͱɺ.BQQFOE@GFBUVSFT . ͕ ணՐɻ.Ϟδϡʔϧ͸!@EFQFOEFODJFT͕ఆٛ͞Ε͍ͯΔ͔Β ͦ͜ʹ.ΦϒδΣΫτΛ֨ೲ ௚ྻܕ
  15. module ActiveSupport module Concern class MultipleIncludedBlocks < StandardError #:nodoc: def

    initialize super "Cannot define multiple 'included' blocks for a Concern" end end def self.extended(base) #:nodoc: base.instance_variable_set(:@_dependencies, []) end def append_features(base) if base.instance_variable_defined?(:@_dependencies) base.instance_variable_get(:@_dependencies) << self return false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) end end def included(base = nil, &block) if base.nil? raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block) @_included_block = block else super end end end end ͜͜ͷ෦෼ͷػೳΛݟ͍ͯ͘
  16. module M1 extend ActiveSupport::Concern def m1_instance_method; end; end module M2

    extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end .Ϟδϡʔϧ͕JODMVEF.Λ͢Δͱɺ.BQQFOE@GFBUVSFT . ͕ணՐɻ.Ϟ δϡʔϧ͸!@EFQFOEFODJFT͕ఆٛ͞Ε͍ͯͳ͍͔Β . TFMG ͷ!@EFQFOEFODJFT<.>ʹରͯ͠ɺJODMVEF.͕CBTF . ʹରͯ͠ ݺ͹ΕΔɻͭ·Γɺ.BQQFOE@GFBUVSFT . ͕ணՐ͢ΔɻҎԼɺ܁Γฦ͠ ௚ྻܕ  .Ϟδϡʔϧ͕JODMVEF.̎Λ͢Δͱɺ.̎BQQFOE@GFBUVSFT . ͕ணՐɻ.Ϟ δϡʔϧ͸!@EFQFOEFODJFT͕ఆٛ͞Ε͍ͯͳ͍͔Β . TFMG ͷ!@EFQFOEFODJFT<.>ʹରͯ͠ɺJODMVEF.͕CBTF . ʹରͯ͠ ݺ͹ΕΔɻͭ·Γɺ.BQQFOE@GFBUVSFT . ͕ணՐ͢ΔɻҎԼɺ܁Γฦ͠ .Ϟδϡʔϧ͕JODMVEF.Λ͢Δͱɺ.BQQFOE@GFBUVSFT . ͕ணՐɻ.Ϟ ɾɾɾɾ ɾɾɾɾ
  17. module M1 extend ActiveSupport::Concern def m1_instance_method; end; end module M2

    extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ  NϞδϡʔϧ ͔Βࢀরͨ࣌͠ ͚ͩBODFTUPST ݁࿦͸.Ϟδϡʔϧʹ.ɾ.ɾ.͕JODMVEF͞ΕΔ͕ɺ ͱͳΔɻ
  18. ·ͱΊ BQQFOE@GFBUVSFTͷجຊͷػೳ͚ͩ࢖͏ʣ௚ྻܕ module M1 extend ActiveSupport::Concern def m1_instance_method; end; end

    module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end FYUFOE"DUJWF4VQQPSU$PODFSO͕ͳ͞ΕͨNPEVMFͷ JODMVEFΛޙճ͠ʹͰ͖ΔɻӈͷྫͳΒ FYUFOE"DUJWF4VQQPSU$PODFSO͕ͳ͞ΕͨNPEVMFͷ JODMVEFΛޙճ͠ʹͰ͖ΔͨΊɺதؒNPEVMF .ɾ.ͳͲ ͰͷJODMVEF͕ൃੜͤͣɺΦʔόʔϔου͕ආ͚ΒΕΔɻ ݁࿦ ௕ॴ ୹ॴ
  19. ࢖͍ํ $MBTT.FUIPETͷػೳͷ෦෼Λ࢖͏ʣ௚ྻܕ module M1 extend ActiveSupport::Concern def m1_instance_method; end; module

    ClassMethods def m1_extend_method; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; module ClassMethods def m2_extend_method; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end جຊతͳྲྀΕ͸ "DUJWF4VQQPSU$PODFSOϞδϡʔϧΛFYUFOEͨ͠.Ϟ δϡʔϧΛ.Ϟδϡʔϧ͕JODMVEF͢Δ͜ͱͰ.Ϟδϡʔϧ ͕Ϋϥε֦ுͰಘͨBQQFOE@GFBUVSFTΛணՐɻ ͜ΕΛ܁Γฦ͠࠷ޙɺNPEVMF.ʹJODMVEF.͞Εͨ࣌ʹɺ ͲͷΑ͏ʹ֤NPEVMF͕JODMVEF͞Ε͍ͯ͘ͷ͔ݟΔɻ ݁࿦͸͜͏ͳΔ ͜Ε͸Ͳ͏͍͏͜ͱͳͷ͔ͦΕΛཧղ͍͖͍ͯͨ͠ɻ
  20. module ActiveSupport module Concern class MultipleIncludedBlocks < StandardError #:nodoc: def

    initialize super "Cannot define multiple 'included' blocks for a Concern" end end def self.extended(base) #:nodoc: base.instance_variable_set(:@_dependencies, []) end def append_features(base) if base.instance_variable_defined?(:@_dependencies) base.instance_variable_get(:@_dependencies) << self return false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) end end def included(base = nil, &block) if base.nil? raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block) @_included_block = block else super end end end end ͜͜ͷ෦෼ͷػೳΛݟ͍ͯ͘
  21. module M1 extend ActiveSupport::Concern def m1_instance_method; end; module ClassMethods def

    m1_extend_method; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; module ClassMethods def m2_extend_method; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ .Ϟδϡʔϧ͕JODMVEF.Λ͢Δͱɺ.BQQFOE@GFBUVSFT . ͕ணՐɻ.Ϟ δϡʔϧ͸!@EFQFOEFODJFT͕ఆٛ͞Ε͍ͯͳ͍͔Β . TFMG ͷ!@EFQFOEFODJFT<.>ʹରͯ͠ɺ. CBTF FYUFOE.͕࣮ߦ͞ΕΔɻ ҎԼɺ܁Γฦ͠ .Ϟδϡʔϧ͕JODMVEF.̎Λ͢Δͱɺ.̎BQQFOE@GFBUVSFT . ͕ணՐɻ.Ϟ δϡʔϧ͸!@EFQFOEFODJFT͕ఆٛ͞Ε͍ͯͳ͍͔Β . TFMG ͷ!@EFQFOEFODJFT<.>ʹରͯ͠ɺ. CBTF FYUFOE.͕࣮ߦ͞ΕΔɻ ҎԼɺ܁Γฦ͠ .Ϟδϡʔϧ͕JODMVEF.Λ͢Δͱɺ .BQQFOE@GFBUVSFT . ͕ணՐɻ.Ϟ ɾɾɾɾ ɾɾɾɾ
  22. ·ͱΊ $MBTT.FUIPETͷػೳͷ෦෼Λ࢖͏ʣ௚ྻܕ module M1 extend ActiveSupport::Concern def m1_instance_method; end; module

    ClassMethods def m1_extend_method; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; module ClassMethods def m2_extend_method; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end FYUFOE"DUJWF4VQQPSU$PODFSO͕ͳ͞ΕͨNPEVMFͷ FYUFOEΛޙճ͠ʹͰ͖ΔͨΊɺதؒNPEVMF .ɾ.ͳͲ ͰͷFYUFOE͕ൃੜͤͣɺΦʔόʔϔου͕ආ͚ΒΕΔɻ ௕ॴ ୹ॴ FYUFOE"DUJWF4VQQPSU$PODFSO͕ͳ͞ΕͨNPEVMFͷ FYUFOEΛޙճ͠ʹͰ͖ΔɻӈͷྫͳΒ ݁࿦
  23. module ActiveSupport module Concern class MultipleIncludedBlocks < StandardError #:nodoc: def

    initialize super "Cannot define multiple 'included' blocks for a Concern" end end def self.extended(base) #:nodoc: base.instance_variable_set(:@_dependencies, []) end def append_features(base) if base.instance_variable_defined?(:@_dependencies) base.instance_variable_get(:@_dependencies) << self return false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) end end def included(base = nil, &block) if base.nil? raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block) @_included_block = block else super end end end end ͜͜ͷ෦෼ͷػೳΛݟ͍ͯ͘ DMBTT@FWBMʹ౉͢CMPDL࣍ୈͰ ᶃϝιουΛCBTFʹఆٛͨ͠Γ ᶄϝιουΛCBTFͰ࣮ߦͨ͠Γ Ͱ͖Δ ϙΠϯτ͸̎ͭ  M.class_eval do def self.method_injected_by_m1; end; end M.class_eval do self.method_injected_by_m2 end ΫϥεɾϝιουNFUIPE@JOKFDUFE@CZ@N Λ.ʹఆٛ͢Δ ΫϥεɾϝιουNFUIPE@JOKFDUFE@CZ@N Λ.Ͱ࣮ߦ͢Δ
  24. module ActiveSupport module Concern class MultipleIncludedBlocks < StandardError #:nodoc: def

    initialize super "Cannot define multiple 'included' blocks for a Concern" end end def self.extended(base) #:nodoc: base.instance_variable_set(:@_dependencies, []) end def append_features(base) if base.instance_variable_defined?(:@_dependencies) base.instance_variable_get(:@_dependencies) << self return false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) end end def included(base = nil, &block) if base.nil? raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block) @_included_block = block else super end end end end ͜͜ͷ෦෼ͷػೳΛݟ͍ͯ͘ JODMVEFEEPʜFOE͸ɺͦΕ͕ ᶃNPEVMFʹॻ͔Ε͍ͯͨΒɺCBTF͕OJMͰݺ͹ΕΔɻ ᶄNPEVMFʹॻ͔Ε͍ͯΔNPEVMFΛJODMVEFͨ͠ΒɺCBTF ݺͼग़͠ Ͱݺ͹ΕΔɻ ͜ͷ̎ͭͷύλʔϯ͕͋Δɻ͔ͩΒ৚݅෼ذ͍ͯ͠Δɻ ϙΠϯτ͸̎ͭ  ᶃ.ʹॻ͔Ε͍ͯͨΒɺCBTF͕OJMͰݺ͹ΕΔɻ ᶄ.ʹJODMVEFEϒϩοΫ͕ॻ͔Ε͓ͯΓɺͦΕΛ ɹJODMVEFͨ͠ΒɺCBTF . Ͱݺ͹ΕΔɻ module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end
  25. ࢖͍ํ JODMVEFEͷػೳͷ෦෼Λ࢖͏ʣ௚ྻܕ جຊతͳྲྀΕ͸ "DUJWF4VQQPSU$PODFSOϞδϡʔϧΛFYUFOEͨ͠.Ϟ δϡʔϧΛ.Ϟδϡʔϧ͕JODMVEF͢Δ͜ͱͰ.Ϟδϡʔϧ ͕Ϋϥε֦ுͰಘͨBQQFOE@GFBUVSFTΛணՐɻ ͜ΕΛ܁Γฦ͠࠷ޙɺNPEVMF.ʹJODMVEF.͞Εͨ࣌ʹɺ ͲͷΑ͏ʹ֤NPEVMF͕JODMVEF͞Ε͍ͯ͘ͷ͔ݟΔɻ ݁࿦͸͜͏ͳΔ ͜Ε͸Ͳ͏͍͏͜ͱͳͷ͔ͦΕΛཧղ͍͖͍ͯͨ͠ɻ

    module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end
  26. module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def

    self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end .ϞδϡʔϧʹJODMVEFEEPʜFOEϒϩοΫ͕͋ Δ͔ΒɺCBTF OJM Ͱݺͼग़͞ΕΔɻ݁Ռɺ.Ϟ δϡʔϧʹ !@JODMVEFE@CMPDL1SPD͕อ࣋͞ΕΔɻ
  27. module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def

    self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ .Ϟδϡʔϧʹ.Ϟδϡʔϧ͸࣮ࡍʹJODMVEF ͞Εͳ͍ͷͰԿ΋͓͖ͳ͍
  28. module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def

    self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ .ϞδϡʔϧʹJODMVEFEEPʜFOEϒϩοΫ͕͋ Δ͔ΒɺCBTF OJM Ͱݺͼग़͞ΕΔɻ݁Ռɺ.Ϟ δϡʔϧʹ !@JODMVEFE@CMPDL1SPD͕อ࣋͞ΕΔɻ
  29. module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def

    self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ .Ϟδϡʔϧʹ.Ϟδϡʔϧ͸࣮ࡍʹJODMVEF ͞Εͳ͍ͷͰԿ΋͓͖ͳ͍
  30. module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def

    self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ .ϞδϡʔϧʹJODMVEFEEPʜFOEϒϩοΫ͕͋ Δ͔ΒɺCBTF OJM Ͱݺͼग़͞ΕΔɻ݁Ռɺ.Ϟ δϡʔϧʹ !@JODMVEFE@CMPDL1SPD͕อ࣋͞ΕΔɻ
  31. module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def

    self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ M.class_eval do self.method_injected_by_m1 self.method_injected_by_m2 end ͕࣮ߦ͞ΕΔɻ
  32. module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def

    self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ M.class_eval do def self.method_injected_by_m2 end end ͕࣮ߦ͞ΕɺMʹΫϥεɾϝιουʹ஫ೖ͞ΕΔ
  33. module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def

    self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ௚ྻܕ M.class_eval do def self.method_injected_by_m2 end end ͕࣮ߦ͞ΕɺMʹΫϥεɾϝιουʹ஫ೖ͞ΕΔ
  34. ࢖͍ํ JODMVEFEͷػೳͷ෦෼Λ࢖͏ʣ௚ྻܕ module M1 extend ActiveSupport::Concern def m1_instance_method; end; included

    do def self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; ɹincluded do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end FYUFOE"DUJWF4VQQPSU$PODFSO͕ͳ͞ΕͨNPEVMFͷ FYUFOEΛޙճ͠ʹͰ͖ΔͨΊɺதؒNPEVMF .ɾ.ͳͲ ͰͷFYUFOE͕ൃੜͤͣɺΦʔόʔϔου͕ආ͚ΒΕΔɻ ௕ॴ ୹ॴ ϞδϡʔϧΛJODMVEFͨ࣌͠ʹɺΫϥεɾϝιουΛఆٛͨ͠ Γɺ ݺͼग़ͨ͠Ϟδϡʔϧʹ஫ೖͨ͠Γ ࣮ߦͨ͠ΓͰ͖Δɻ ݁࿦
  35. ࢖͍ํɹ ػೳ͸̏ͭ͋Δ Πϯελϯεɾϝιου֦ு Ϋϥεɾϝιου֦ு module M1 extend ActiveSupport::Concern def m1_instance_method;

    end; end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end module M1 extend ActiveSupport::Concern def m1_instance_method; end; module ClassMethods def m1_extend_method; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; module ClassMethods def m2_extend_method; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end ϝιου࣮ߦɾ஫ೖ JODMVEF͞Εͨޙʹ࣮ߦ module M1 extend ActiveSupport::Concern def m1_instance_method; end; included do def self.method_injected_by_m1; end; end end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; included do def self.method_injected_by_m2; end; end end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; included do self.method_injected_by_m1 self.method_injected_by_m2 end end module M extend ActiveSupport::Concern include M3 end ࣮ࡍʹ࣮ߦ͞ΕΔ FYUFOE"DUJWF4VQQPSU$PODFSO ͍ͯ͠Δ͔Β࢖͑Δ FYUFOE"DUJWF4VQQPSU$PODFSO ͍ͯ͠Δ͔Β࢖͑Δ FYUFOE"DUJWF4VQQPSU$PODFSO ͍ͯ͠Δ͔Β࢖͑Δ
  36. ࢖͍ํɹ େ͖̎ͭ͘ͷܕɺ௚ྻܕͱฒྻܕ͕͋Δ ௚ྻܕ ฒྻܕ module M1 extend ActiveSupport::Concern def m1_instance_method;

    end; end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end module M1 extend ActiveSupport::Concern def m1_instance_method; end; end module M2 extend ActiveSupport::Concern include M1 def m2_instance_method; end; end module M3 extend ActiveSupport::Concern include M2 include M1 def m3_instance_method; end; end module M extend ActiveSupport::Concern include M3 end ॻ࣌͘͸͕͍͍ͬͪ͜
  37. ϝιου໊ ෼ྨ ॴ༗ऀ ݺͼग़͠Մೳ N@JOTUBODF@NFUIPE Πϯελϯεɾϝιου ֦ு . .ɾ. N@JOTUBODF@NFUIPE

    Πϯελϯεɾϝιου ֦ு . .ɾ. N@JOTUBODF@NFUIPE Πϯελϯεɾϝιου ֦ு . .ɾ. N@FYUFOE@NFUIPE Ϋϥεɾϝιου ֦ு .$MBTT.FUIPET .TJOHMFUPO@DMBTT ɾ.$MBTT.FUIPET N@FYUFOE@NFUIPE Ϋϥεɾϝιου ֦ு .$MBTT.FUIPET .TJOHMFUPO@DMBTT ɾ.$MBTT.FUIPET NFUIPE@JOKFDUFE@CZ@N ϝιου࣮ߦɾ஫ೖ .TJOHMFUPO@DMBTT . NFUIPE@JOKFDUFE@CZ@N ϝιου࣮ߦɾ஫ೖ .TJOHMFUPO@DMBTT . ಛ௃ BODFTUPST΍ϝιουͷ৔ॴ