-
-
Save rkh/2720016 to your computer and use it in GitHub Desktop.
Possible for a module included somewhere to override a class's instance method?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Base | |
def call | |
'call' | |
end | |
end | |
p Base.new.call #=> "call" | |
# Monkeypatching "works" but doesn't provide access to #super | |
class Base | |
def call | |
'monkeypatched' | |
end | |
end | |
module Prepending | |
def append_features(base) | |
return super unless base.is_a? Class | |
prepend = self | |
base.extend Module.new { define_method(:new) { |*| super.extend(prepend) }} | |
end | |
end | |
p Base.new.call #=> "monkeypatched" | |
# This is the spirit of what I'd like, but methods defined on the class will be | |
# preferred over those in ancestors. | |
module Override | |
extend Prepending | |
def call | |
[ 'overridden', super ] | |
end | |
end | |
class Base | |
include Override | |
end | |
p Base.new.call #=> ["overridden", "monkeypatched"] | |
# This works but I don't have access to the class instances to apply this method. | |
instance = Base.new | |
class << instance | |
def call | |
[ 'overridden', super ] | |
end | |
end | |
p instance.call #=> ["overridden", ["overridden", "monkeypatched"]] |
No, |*|
is a shorthand syntax for I don't care about the arguments. super
without args and parens will automatically send any arguments passed to the original call and a block, if there is one (missing from your code). So { |*| super }
is equivalent to { |*args, &block| super(*args, &block) }
.
👍 thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What's "_" in
base.extend Module.new { define_method(:new) { |_| super.extend(prepend) }}
?Shouldn't it look like this instead?
base.extend Module.new { define_method(:new) { |*args| super(*args).extend(prepend) }}