From: Robert Klemme Date: 2010-10-21T23:23:14+09:00 Subject: Re: [Q] best practice for redefining methods at runtime? On Wed, Oct 20, 2010 at 8:29 PM, John W Higgins wrote: > Morning Chuck. > > On Wed, Oct 20, 2010 at 8:31 AM, Chuck Remes wrote: > >> I have a class that I would like to "freeze" when it reaches a particular >> state so that it becomes read-only. I do *not* want to use the existing >> #freeze method because it raises an exception when there is an attempted >> mutation on a frozen object and I want the attempt to be silent. It appears >> that the best way to enforce this (state machine pattern) is by redefining >> the accessors and other methods that cause mutations to be no ops. >> >> What is the preferred practice for doing that? >> >> > You could in the alternative have the ops that mutate do an "unless" at the > top of the method to bake the freeze into the method as opposed to > redefining > > Using your example > > > class Foo >  attr_accessor :frozen >  attr_reader :bar, :baz, :quxxo > >  def bar= new_bar >   unless @frozen @bar = new_bar >  end > >  def baz= new_baz >   unless @frozen @baz = new_baz >  end > >  def quzzo= new_quzzo >   unless @frozen @quzzo = new_quzzo >  end > end > > It's a little more work and a slight amount of overhead for the unless > check. But it does eliminate the need to redefine your methods. It also very > clearly spells out what you are freezing. But why do this if you can simply use #freeze and #frozen? as they are defined? The advantage of the regular #freeze method is that you will immediately notice if you try to modify a frozen instance. All approaches present here will silently eat the method call and do nothing thus making the caller believe the method has worked regularly while it hasn't. I think this approach to freezing is error prone and likely to create hard to detect bugs. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/