E
Evan Senter
Hi,
I've been having a little trouble the past couple days getting an
alias_method_chain working on the initialize method via a module getting
mixed into a class. For example:
- - - - -
module Dsl
def self.included(base)
base.instance_eval do
include InstanceMethods
alias_method :initialize_without_block_support, :initialize
alias_method :initialize, :initialize_with_block_support
end
end
module InstanceMethods
def initialize_with_block_support
p "initialize_with_block_support"
initialize_without_block_support
end
end
end
class Something
include Dsl
def initialize
p "initialize_without_block_support"
end
end
Something.new #=> prints "initialize_without_block_support", should
print "initialize_with_block_support" as well.
- - - - -
The problem in this contrived example (I believe) is that initialize is
redefined in the Something class body after the module is mixed in, thus
negating the alias_method_chain that was set up previously. So one
option is to just include modules after the initialize method is
defined, but that's not at all elegant, so I've been trying to find a
better way.
The next possibility I considered was using the method_added hook.
Something that would work like the following:
- - - - -
module Dsl
def self.included(base)
base.extend ClassMethods
base.instance_eval { include InstanceMethods }
end
module ClassMethods
def method_added(name)
if name == :initialize && !@redefining_initialize
@redefining_initialize = :stop_those_infinite_loops!
alias_method :initialize_without_block_support, :initialize
alias_method :initialize, :initialize_with_block_support
remove_instance_variable redefining_initialize
end
end
end
module InstanceMethods
def initialize_with_block_support
p "initialize_with_block_support"
initialize_without_block_support
end
end
end
class Something
include Dsl
def initialize
p "initialize_without_block_support"
end
end
Something.new
- - - - -
This works, but feels pretty hackety. If you happen to have any
experience doing something like this and have an alternative solution,
or feedback on this implementation using method_added, I'd appreciate
hearing it. As a note, the @redefining_initialize guard is necessary
because alias_method triggers the method_added hook.
Thanks for your time!
I've been having a little trouble the past couple days getting an
alias_method_chain working on the initialize method via a module getting
mixed into a class. For example:
- - - - -
module Dsl
def self.included(base)
base.instance_eval do
include InstanceMethods
alias_method :initialize_without_block_support, :initialize
alias_method :initialize, :initialize_with_block_support
end
end
module InstanceMethods
def initialize_with_block_support
p "initialize_with_block_support"
initialize_without_block_support
end
end
end
class Something
include Dsl
def initialize
p "initialize_without_block_support"
end
end
Something.new #=> prints "initialize_without_block_support", should
print "initialize_with_block_support" as well.
- - - - -
The problem in this contrived example (I believe) is that initialize is
redefined in the Something class body after the module is mixed in, thus
negating the alias_method_chain that was set up previously. So one
option is to just include modules after the initialize method is
defined, but that's not at all elegant, so I've been trying to find a
better way.
The next possibility I considered was using the method_added hook.
Something that would work like the following:
- - - - -
module Dsl
def self.included(base)
base.extend ClassMethods
base.instance_eval { include InstanceMethods }
end
module ClassMethods
def method_added(name)
if name == :initialize && !@redefining_initialize
@redefining_initialize = :stop_those_infinite_loops!
alias_method :initialize_without_block_support, :initialize
alias_method :initialize, :initialize_with_block_support
remove_instance_variable redefining_initialize
end
end
end
module InstanceMethods
def initialize_with_block_support
p "initialize_with_block_support"
initialize_without_block_support
end
end
end
class Something
include Dsl
def initialize
p "initialize_without_block_support"
end
end
Something.new
- - - - -
This works, but feels pretty hackety. If you happen to have any
experience doing something like this and have an alternative solution,
or feedback on this implementation using method_added, I'd appreciate
hearing it. As a note, the @redefining_initialize guard is necessary
because alias_method triggers the method_added hook.
Thanks for your time!