ts said:
No, this is because #initialize is a private method. Try it with
private_method_defined?
Well, it was still a pain, as the 'initialize' methods seems always be
defined:
fery@domesticus:~$ irb1.8
irb(main):001:0> class A
irb(main):002:1> puts "init?: #{private_method_defined?
initialize)}"
irb(main):003:1> end
init?: true
So I decided to always re-hack a method when it is added to a class,
anyway, it is a logical thing to do.
Below is my solution, as this list do not accept even ascii attachments,
and wait for the simpler/shorter implementations, as I am always happy
to learn.
I hope the long rows will not break...
Ferenc
PS: I have looked aspectR, but its source was too long (9K
, so I
didn't look into its implementation details.
---------------------------------------->8---- before.rb
#!/usr/bin/env ruby
def debug(*args)
$stderr.puts(args[0])
end
# Extension of Module to define methods in modules which run before the
# appropriate method in the class which mixes the module.
class Module
def before_init
@before = []
end
def before(*method_names)
before_init() if !@before
@before += method_names
debug "#{self}.@before==#{@before}", :before
end
def before_get_before() @before end
def before_check_new_method(mod,aSymbol)
if !(mod.before_get_before.nil?) && (mod.before_get_before.include?
aSymbol)
debug "#{self}.before_check_new_method(#{mod},#{aSymbol}):
#{aSymbol} is in #{mod}.@before.", :before
debug "Executing
beforehack_insertBeforeWrapper(#{self},#{aSymbol})", :before
mod.beforehack_insertBeforeWrapper(self,aSymbol)
end
end
alias pre_beforehack_append_features append_features
def append_features(klass)
before_init() if !@before
@before.each {|method_name|
#~ if klass.method_defined?(method_name) ||
klass.private_method_defined?(method_name) # Only with ruby 1.8
if klass.method_defined?(method_name) ||
klass.private_instance_methods.include?(method_name.id2name) # The
method is already defined
debug "#{self}.append_features(#{klass}): checking method
'#{method_name}': exists.", :before
debug "Executing
beforehack_insertBeforeWrapper(#{klass},#{method_name})", :before
beforehack_insertBeforeWrapper(klass,method_name)
else
debug "#{self}.append_features(#{klass}): checking method
'#{method_name}': do not exist.", :before
end
}
pre_beforehack_append_features(klass)
end
def beforehack_insertBeforeWrapper(klass,method_name)
debug "beforehack_insertBeforeWrapper: hacking
#{klass}.#{method_name} to exec #{method_name}_#{self}", :before
klass.module_eval <<-END_OF_ADVICE
@before_in_beforehack_semaphore=true
alias pre_include_#{self}_#{method_name} #{method_name}
def #{method_name}(*args,&block)
#{method_name}_#{self}(*args,&block)
pre_include_#{self}_#{method_name}(*args,&block)
end
@before_in_beforehack_semaphore=false
END_OF_ADVICE
end
alias pre_beforehack_method_added method_added if self.respond_to?
:method_added
def method_added(aSymbol)
if !@before_in_beforehack_semaphore
self.included_modules.each {|mod|
before_check_new_method(mod,aSymbol)
}
end
self.pre_beforehack_method_added if self.respond_to?
re_beforehack_method_added
end
end
# Usage example:
module Mod
before :fnname
def fnname_Mod
puts "fnname_Mod called"
end
end
class Klass
include Mod
def fnname
puts "fnname called"
end
end
k=Klass.new
k.fnname