ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> ruby-talk
ruby-talk
Re: class destruction (evil genius metaprogramming)
by dblack other posts by this author
Jun 16 2007 3:32AM messages near this date
Re: class destruction (evil genius metaprogramming) | Re: class destruction (evil genius metaprogramming)
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)
Thread:
Giles Bowkett
Rick DeNatale
dblack
Robert Dober
dblack
Robert Dober
Giles Bowkett
dblack
Stephen Smith
Nathan Taylor-Hoover
Giles Bowkett
dblack
Giles Bowkett
Rick DeNatale
dblack
Devin Mullins
dblack
Gregory Brown
Giles Bowkett

Privacy Policy | Email Opt-out | Feedback | Syndication
© 2004 ActiveState, a division of Sophos All rights reserved