From: "Jesús Gabriel y Galán" Date: 2010-03-27T05:39:16+09:00 Subject: Re: changing method behavior depending on context On Fri, Mar 26, 2010 at 5:11 PM, Marat Kamenschikov wrote: > Assume there is class A with method save which takes one param with > default value (e.g. true). Class A instance gets save and behaves > depending on true value. > Assume there is class B with a field of type A. Calling save on this > field it should behave as if save(false) was called. > Outside of class B scope save method should behave originally. > Something like override, but just inside of one scope. > > Here is some piece of code: > class A >  def save(validate = true) >    validate? «INVALID»: «VALID» >  end > end > > class B >  # something very crazy >  def initialize >    @a = A.new >  end >  def save >    @a.save >  end > end > > A.new.save # => «INVALID» > B.new.save # => «VALID» > A.new.save # => «INVALID» > > It is meant to be used in Rails application with ActiveRecord objects, > but it really doesn't matter much. > The most simple way here is probably examining caller list, but is there > a way to redef a method inside of other class' scope? I have no clue if this works or not with ActiveRecord objects, but in case it does, I would do this: irb(main):006:0> class A irb(main):007:1> def save(validate=true) irb(main):008:2> validate ? "INVALID" : "VALID" irb(main):009:2> end irb(main):010:1> end => nil irb(main):011:0> class B irb(main):012:1> def initialize irb(main):013:2> @a = A.new irb(main):014:2> def @a.save(validate=true) irb(main):015:3> super false irb(main):016:3> end irb(main):017:2> end irb(main):018:1> def save irb(main):019:2> @a.save irb(main):020:2> end irb(main):021:1> end => nil irb(main):022:0> B.new.save => "VALID" irb(main):023:0> A.new.save => "INVALID" Although if this works for you, you could also change the save method in class B to pass a false... irb(main):001:0> class A irb(main):002:1> def save(validate=true) irb(main):003:2> validate ? "INVALID" : "VALID" irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> class B irb(main):007:1> def initialize irb(main):008:2> @a = A.new irb(main):009:2> end irb(main):010:1> def save irb(main):011:2> @a.save false irb(main):012:2> end irb(main):013:1> end => nil irb(main):014:0> A.new.save => "INVALID" irb(main):015:0> B.new.save => "VALID" Jesus.