Skip to content

Instantly share code, notes, and snippets.

@a2ikm
Created January 12, 2022 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a2ikm/247fe0e5438239121205cdf3e2035e91 to your computer and use it in GitHub Desktop.
Save a2ikm/247fe0e5438239121205cdf3e2035e91 to your computer and use it in GitHub Desktop.
ruby 3.0 から include したモジュールに対する変更が以前に include したモジュールにも反映されるようになったので、 ruby >= 3.0 ならそのモジュールに対して prepend すればオーバーライドできる。それ以前はそのモジュールを module_eval するなどして直接書き換える必要がある
module Mod
module A
def message
"A"
end
end
module B
def message
"B#{super}B"
end
end
module C
def message
"C#{super}C"
end
end
include A
include B
include C
end
class Klass
include Mod
end
p Klass.ancestors
#=> [Klass, Mod, Mod::C, Mod::B, Mod::A, Object, Kernel, BasicObject]
p Klass.new.message
#=> "CBABC"
Mod::A.module_eval do
def message
"O"
end
end
p Klass.new.message
#=> "CBOC"
module Patch
def message
"X"
end
end
Mod::A.prepend(Patch)
p Klass.ancestors
# ruby >= 3.0
#=> [Klass, Mod, Mod::C, Mod::B, Patch, Mod::A, Object, Kernel, BasicObject]
# otherwise
#=> [Klass, Mod, Mod::C, Mod::B, Patch, Mod::A, Object, Kernel, BasicObject]
p Klass.new.message
# ruby >= 3.0
#=> "CBXBC"
# otherwise
#=> "CBOBC"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment