Hi -- On Thu, 24 Sep 2009, MaggotChild wrote:
> > > > On Sep 24, 12:34 am, Frederick Cheung <[email protected]> > wrote: >> On Sep 23, 11:27 pm, MaggotChild <[email protected]> wrote: >> >>> Could someone explain this? >> >> At a quick glance it is probably because after AttributeMethods is >> included in ActiveRecord::Base, write_attribute is aliased & >> overwridden (eg the change tracking module). You then change >> write_attribute on AttributeMethods but it is too late - the aliasing >> that occured in Dirty is pointing at the previous implementation. When >> you alias a method ruby does keep track of what the aliased method was >> at the time alias_method was called, for example: >> >> class Foo >> def to_be_aliased >> "implementation 1" >> end >> alias_method :old_implementation, :to_be_aliased >> end >> >> class Foo >> def to_be_aliased >> "implementation 2" >> end >> end >> >> Foo.new.old_implementation #=> "implementation 1" > > > Hi Fred, > > Thanks for your response. I think you're on to something and I'll have > to take a look a the Dirty module (amongst others). But, even if the > module was aliasing the original write_attribute, I don't see how this > would interfere with my redefinition. > > write_attribute is at the top of the call stack so I'd think it's > going to use the most recent definition. Unless some other module > redefined write_attribute within the scope of active AR::Base (as > apposed to including it via a module) -which is possible. > > > Using your example, I believe the case is more like the following: > > class Foo > def to_be_aliased > p "implementation 1" > end > alias_method :old_implementation, :to_be_aliased > end > > class Foo > def to_be_aliased > p "implementation 2" > end > end > > Foo.new.to_be_aliased #implementation 2 It involves alias_method_chain, so it's somewhat like this: module AR module M def x; puts "M#x"; end def self.included(base) base.alias_method_chain(:x, :y) end end class Base def x_with_y; puts "x_with_y"; end p Base.instance_methods(false).sort # does not include "x" include M p Base.instance_methods(false).sort # does include "x" end end AR::Base.new.x After alias_method_chain, AR::Base has an "x" method, so overriding the one in AR::M won't affect what happens when you call x. I stripped it down to the bare bones (and then some, perhaps :-) but I think this represents what happens. See the file dirty.rb, which is where the alias_method_chain call is. David -- David A. Black, Director Ruby Power and Light, LLC (http://www.rubypal.com) Ruby/Rails training, consulting, mentoring, code review Book: The Well-Grounded Rubyist (http://www.manning.com/black2) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---

