Если мы добавим некоторые отладочные в вашем коде, мы увидим, что порядок определения и включения модулей является то, как показано ниже:
Defined => Default
Defined => Bar
Defined => ClassMethods
Included => Default
Included => Bar
41
Поскольку событие включения модуля Default
происходит после определения модуля Bar
, определение недействительного foo
, которое является недействительным, определено в блоке included
модуля Default
.
код отладочные заявления добавил
require "rails"
module Default
extend ActiveSupport::Concern
puts "Defined => Default"
included do
define_singleton_method :foo do
41
end
puts "Included => Default"
end
end
module Bar
extend ActiveSupport::Concern
puts "Defined => Bar"
module ClassMethods
puts "Defined => ClassMethods"
def foo
42
end
end
included do
puts "Included => Bar"
end
end
class Foo
include Default
include Bar
end
p Foo.foo
Если вы хотите foo
определение Bar
быть в действительности, то вы можете либо определить его тоже в included
блоке Bar
как ниже:
require "rails"
module Default
extend ActiveSupport::Concern
puts "Defined => Default"
included do
define_singleton_method :foo do
41
end
puts "Included => Default"
end
end
module Bar
extend ActiveSupport::Concern
puts "Defined => Bar"
module ClassMethods
puts "Defined => ClassMethods"
def foo
42
end
end
included do
puts "Included => Bar"
define_singleton_method :foo do
42
end
end
end
class Foo
include Default
include Bar
end
p Foo.foo
Выпуск вышеуказанной программы
Defined => Default
Defined => Bar
Defined => ClassMethods
Included => Default
Included => Bar
42