From: Christoph Rippel Date: 2001-01-16T07:40:03+09:00 Subject: [ruby-talk:9346] Re: Redefining singleton methods & C - function pointers "ts" wrote in message news:200101131757.f0DHv4J04461@orsay1.moulon.inra.fr... ... > You write a delegator, *warning* this is just an example not fully tested > > pigeon% cat b.rb > #!/usr/bin/ruby > module DM > CODE = <<-'EOT' > for method in singleton_methods > next if method == "append_features" > mod.module_eval <<-EOS > def #{mod.name}.#{method}(*args, &block) > begin > #{name}.send(:#{method}, *args, &block) > rescue > $@[0,2] = nil > raise > end > end > EOS > end > EOT > def DM.append_features(mod) > mod.module_eval <<-EOS > def #{mod.name}.append_features(mod) > DM.append_features(mod) > #{CODE} > end > EOS > end > end > > module A > include DM > def A.a(a) > puts "A.a #{a}" > end > end > > module B > def B.b > puts "B.b" > end > include A > end > > module C > include B > def C.c > puts "C.c" > end > end > > p A.singleton_methods > p B.singleton_methods > p C.singleton_methods > pigeon% > > pigeon% b.rb > ["a", "append_features"] > ["a", "append_features", "b"] > ["c", "b", "a", "append_features"] > pigeon% > > > Guy Decoux Nice - I definitely keep this one in my archive! I have couple questions and comments and your solutions starting with the simplest one why you put the rescue clause? > rescue > $@[0,2] = nil > raise > end You need to add a call to #super somewhere otherwise regular instance_methods are not mixed in. I am sure your are aware of the fact that this does not work (the mixed in function have the wrong behavior) for nuance functions like module A def A.sm1 id end def A.sm2 to_s end end The way your code handles arity is problematic - functions relying on argument separation like def A.s (left,*right) p left p right end won't work correctly. Also right now things do not work if you retroactively add a new singleton methods - i.e. something like this include DM end module Y include X end def X.s end p Y.singleton_methods # [] won't work. To do this you need to change the behavior of #method_added as well. Christoph