Hi -- On Sat, 16 Jun 2007, Giles Bowkett wrote: >> > Why should this inspire fear? >> >> Code injection attack to own a RoR site possibly? That would be my guess. > > Sort of. I'm trying to use it to build a Rails plugin called > acts_as_fox, which overrides every method on a model to return "chunky > bacon!" (It's not really that terrifying, I just kind of had a Dr. > Frankenstein moment, drunk on power type thing.) > > Unfortunately, applying Rick's code directly to an ActiveRecord model > doesn't quite accomplish this, because it's missing the superclass > methods, but applying it to ActiveRecord::Base doesn't work either. I > did get it to work by doing it twice, both on the actual model and on > ActiveRecord::Base itself, but that's very unsatisfying, because I > solved the problem by cutting and pasting. (I think I understand why > it worked; ActiveRecord::Base attaches a lot of methods to its > subclasses, instead of having them inherited directly.) It also fails > to really accomplish what I want to do, because it means that making > one model acts_as_fox destroys all the other models. (I also need to > attach a method_missing to return "chunky bacon!" but that part's > obviously trivial.) > > Really the quickest way to accomplish this would be to simply pop the > model out of its inheritance hierarchy - redefine the model not to > have any superclass except Object - but I don't know if that's > possible. Trying it in the most obvious way (class Foo < Object; end, > where Foo was already defined Foo < ActiveRecord::Base) results in a > TypeError with the message "superclass mismatch." I do sometimes wonder what would happen if the ancestry array were writeable. It could be interesting. I haven't thought through the possible pitfalls. > But there must be a clean way to open up the class, grab all its > methods, including those derived from superclasses, and simply > reassign them. Something like > > Foo.instance_methods(true).each{|m| Foo.instance_eval("alias > :chunky_bacon " + m)} Here's a little demo that does pretty much that (sparing the _ methods like __send__): class Object def mask puts "I'm masking a method" end end class C def x puts "x" end def y puts "y" end end class D < C def z puts "z" end end class D instance_methods.reject {|m| /^_/.match(m) }.each do |m| alias_method m, :mask end end C.new.x # x D.new.x # I'm masking a method D.new.z # I'm masking a method David -- * Books: RAILS ROUTING (new! http://safari.awprofessional.com/9780321509246) RUBY FOR RAILS (http://www.manning.com/black) * Ruby/Rails training & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)