KagemushaでActiveReco
1 singleton method bound for a different object (TypeError)
というエラーが発生するという問題がありました。
- rubyneko - KagemushaとActiveReco
rdの不具合 - KagemushaとActiveReco
rdの不具合(2) - Non free as in air - KagemushaとActiveReco
rdの不具合(2)
このままでは困るので、とりあえず動くようにしてみました。
Unboundにしなければ問題は起こらないと思ったので、
instance_m
の代わりにalias_meth
を使っています。
kagemusha_
1 require 'uuidtools' 2 3 class Kagemusha #:nodoc: 4 def swap #:nodoc: 5 original_class_metho ds = {} 6 original_i nstance_me thods = {} 7 8 @class_meth ods.each { |name, proc| 9 if proc 10 begin 11 # replace method 12 #method = @meta.insta nce_method (name) 13 method = random_nam e 14 @meta.instance_e val { alias_meth od method, name } 15 @meta.instance_e val { define_met hod(name, proc) } 16 original_c lass_metho ds[name] = method 17 rescue NameError 18 # insert method 19 @meta.instance_e val { define_met hod(name, proc) } 20 original_c lass_metho ds[name] = false 21 end 22 else 23 begin 24 # remove method 25 #method = @meta.insta nce_method (name) 26 method = random_nam e 27 @meta.instance_e val { alias_meth od method, name } 28 @meta.instance_e val { undef_meth od(name) } 29 original_c lass_metho ds[name] = method 30 rescue NameError 31 # nop 32 end 33 end 34 } 35 36 @instance_m ethods.each { |name, proc| 37 if proc 38 begin 39 # replace method 40 method = @klass.instance_m ethod(name) 41 @klass.instance_e val { define_met hod(name, proc) } 42 original_i nstance_me thods[name] = method 43 rescue NameError 44 # insert method 45 @klass.instance_e val { define_met hod(name, proc) } 46 original_i nstance_me thods[name] = false 47 end 48 else 49 begin 50 # remove method 51 method = @klass.instance_m ethod(name) 52 @klass.instance_e val { undef_meth od(name) } 53 original_i nstance_me thods[name] = method 54 rescue NameError 55 # nop 56 end 57 end 58 } 59 60 return yield 61 ensure 62 original_c lass_metho ds.each { |name, method| 63 if method 64 # replace method 65 #@meta.insta nce_eval { define_met hod(name, method) } 66 @meta.instance_e val { alias_meth od name, method } 67 @meta.instance_e val { undef_meth od method } 68 else 69 # remove method 70 @meta.instance_e val { undef_meth od(name) } 71 end 72 } 73 original_i nstance_me thods.each { |name, method| 74 if method 75 # replace method 76 @klass.instance_e val { define_met hod(name, method) } 77 else 78 # remove method 79 @klass.instance_e val { undef_meth od(name) } 80 end 81 } 82 end 83 84 private 85 def random_nam e 86 [UUID.random_128 ].pack("m").tr("=\n", '') 87 end 88 end
posted by
genki
on Sun 6 Jul 2008
at 05:22
with
2 comments
こんにちは。Kagemushaの作者のYuyaです。
不具合のご検討、ありがとうございます。 違う方法ではありますが、修正を入れてみました。 もしよろしければ、trunk版をお試し頂けると幸いです。
http://kagemusha.rubyforge.org/svn/trunk/kagemusha/lib/kagemusha/core.rb
おお、どうもありがとうございます。便利に使わせていただいています。 Specのカバレッジを上げるのに重宝しています。