"Mauricio FernŠŌdez" <batsman.geo / yahoo.com> schrieb im Newsbeitrag
news:20030516163808.GA28479 / student.ei.uni-stuttgart.de...
> On Sat, May 17, 2003 at 12:59:44AM +0900, Robert Klemme wrote:
> >
> > "Simon Vandemoortele" <deliriousREMOVEUPPERCASETEXTTOREPLY / atchoo.be>
> > schrieb im Newsbeitrag
news:987xa.4791$1u5.452 / afrodite.telenet-ops.be...
> > > On Fri, 16 May 2003 at 02:59 GMT, Sacha Schlegel wrote:
> > > > Did look at the state pattern in "Desing Patterns, E. Gamma, R.
Helm,
> > R.
> > > > Johnson, J. Vlissides, Addison-Weslay, 1995
> > >
> > > > Do YOU or anyone else have links to "implemented" ruby state
pattern
> > > > code?
> > >
> > > Take a look at http://www.rubygarden.org/ruby?StatePattern
> >
> > I'd prefer to not use the context but make the state changing methods
> > return the new state.  At least in this example I can't see the
advantage
> > of the choosen implementation.  Maybe someone can shed some light in
this.
> > (Don't have the GOF book available.)
>
> You mean this?
>
>  class Client
>    def initialize
>      @state = InitialState.new
>    end
>
>    def method_missing(meth, *args, &block)
>      @state = @state.send(meth, *args, &block)
>      nil # dummy
>    end
>  end

Yes.

> that implies that the methods cannot return useful values, they have to
> give the next method.

Is it reasonable to have a state transition method return anything other
than the new state?  You could put state dependent instance vars into the
state instance.  Hmmm...  Not satisfying, too.

> You can solve that too:
>
>  class Client
>    def initialize
>      @state = InitialState.new
>      @setter = proc { |x| @state = x }
>    end
>
>    def method_missing(meth, *args, &block)
>      @state.send(meth, @setter, *args, &block)
>    end
>  end
>
> and then
> class SomeState
>   def dosomething(set_state, *args)
>     ...
>     set_state[AnotherState.new]
>     ...
>   end
> end
>
> I believe this will be slightly faster than the other solution (gets rid
> of 1 indirection level).
>
> Another possibility is
>
> class SomeState
>   def initialize(setter, *args)
>     @set_state = setter
>   end
>
>   def some_method
>     @set_state[ NewState.new(@set_state) ]
>   end
> end
>
> class Client
>    def initialize
>      @state = InitialState.new( proc { |x| @state = x } )
>    end
>
>    def method_missing(meth, *args, &block)
>      @state.send(meth, *args, &block)
>    end
>
> end
>
> that should be faster as fewer arguments are passed per method call
> (assuming that the state isn't changing constantly).

Yeah, but what bugs me about these is the need for a reference back from
the state to the client.  Isn't there another way to solve this?  I mean,
putting additional state into the state classes might require handing this
state through to the next state instance.  Gee, I guess I'll have to buy
that DP book...

> Wish I had my DP.book_instance at hand too ;-)

:-)

Cheers

    robert