State Pattern Implementation

Hi all,

I’d like to hear what people think: is this a reasonable implementation of
the state pattern? (Apart from the fact, that class Foo is quite useless.
:slight_smile: The other question is, whether rededinition of a method should issue
a warning in verbose mode (suppressed here by Kernel#no_warn()).

BOND$ cat state.rb

module Kernel
def no_warn(&b)
old = $-w
begin
$-w = false
b.call
ensure
$-w = old
end
end
end

class Foo
def initialize
st1
end

def st1
no_warn do
def self.foo; 100; end
def self.bar; 101; end
end
end

def st2
no_warn do
def self.foo; 200; end
def self.bar; 201; end
end
end
end

f = Foo.new

p f.foo
p f.bar

f.st1
p f.foo
p f.bar

f.st2
p f.foo
p f.bar
BOND$ ruby -w state.rb
100
101
100
101
200
201
BOND$

robert

You are representing each state by a number… with the State pattern
isn’t each state supposed to be represented by a class ?

···

On Tue, 13 May 2003 10:11:42 +0200, Robert Klemme wrote:

I’d like to hear what people think: is this a reasonable implementation of
the state pattern?


Simon Strandgaard

Hi Robert and all

I am about to need a ruby state machine. Eg state handling code.

Did look at the state pattern in "Desing Patterns, E. Gamma, R. Helm, R.
Johnson, J. Vlissides, Addison-Weslay, 1995

Will try to do that with ruby.

Do YOU or anyone else have links to “implemented” ruby state pattern
code?

Concrete I have about 7 states and more transitions.

Did look at your solution. I think I would like to seperate the
different states with their own classes as they might get a little bit
bigger.

Sacha

···

On Tue, 2003-05-13 at 15:30, Robert Klemme wrote:

Hi all,

I’d like to hear what people think: is this a reasonable implementation of
the state pattern? (Apart from the fact, that class Foo is quite useless.
:slight_smile: The other question is, whether rededinition of a method should issue
a warning in verbose mode (suppressed here by Kernel#no_warn()).

BOND$ cat state.rb

module Kernel
def no_warn(&b)
old = $-w
begin
$-w = false
b.call
ensure
$-w = old
end
end
end

class Foo
def initialize
st1
end

def st1
no_warn do
def self.foo; 100; end
def self.bar; 101; end
end
end

def st2
no_warn do
def self.foo; 200; end
def self.bar; 201; end
end
end
end

f = Foo.new

p f.foo
p f.bar

f.st1
p f.foo
p f.bar

f.st2
p f.foo
p f.bar
BOND$ ruby -w state.rb
100
101
100
101
200
201
BOND$

robert

Sacha Schlegel

4 Warwick Str, 6102 St. James, Perth, Australia
sacha@schlegel.li www.schlegel.li
public key: www.schlegel.li/sacha.gpg

Hi Robert and all

I am about to need a ruby state machine. Eg state handling code.

Did look at the state pattern in "Desing Patterns, E. Gamma, R. Helm, R.
Johnson, J. Vlissides, Addison-Weslay, 1995

Will try to do that with ruby.

Do YOU or anyone else have links to “implemented” ruby state pattern
code?

Concrete I have about 7 states and more transitions.

Did look at your solution. I think I would like to seperate the
different states with their own classes as they might get a little bit
bigger.

Sacha

···

On Tue, 2003-05-13 at 15:30, Robert Klemme wrote:

Hi all,

I’d like to hear what people think: is this a reasonable implementation of
the state pattern? (Apart from the fact, that class Foo is quite useless.
:slight_smile: The other question is, whether rededinition of a method should issue
a warning in verbose mode (suppressed here by Kernel#no_warn()).

BOND$ cat state.rb

module Kernel
def no_warn(&b)
old = $-w
begin
$-w = false
b.call
ensure
$-w = old
end
end
end

class Foo
def initialize
st1
end

def st1
no_warn do
def self.foo; 100; end
def self.bar; 101; end
end
end

def st2
no_warn do
def self.foo; 200; end
def self.bar; 201; end
end
end
end

f = Foo.new

p f.foo
p f.bar

f.st1
p f.foo
p f.bar

f.st2
p f.foo
p f.bar
BOND$ ruby -w state.rb
100
101
100
101
200
201
BOND$

robert

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com schrieb im
Newsbeitrag news:pan.2003.05.13.11.04.00.160567@sneakemail.com

I’d like to hear what people think: is this a reasonable
implementation of
the state pattern?

You are representing each state by a number… with the State pattern
isn’t each state supposed to be represented by a class ?

Normally, yes. The association with a number is just for the ease of
keying the example in. My main idea was to replace the state instance by
a redefinition of instance methods. Pro is, you safe an instance and a
redirection; on the con side is increased code size for the class since
you have to include code for all states.

I’m curios to know whether anybody did this before. I might be missing
some grave disadvantage.

Regards

robert
···

On Tue, 13 May 2003 10:11:42 +0200, Robert Klemme wrote:

“Sacha Schlegel” schlegel@cs.curtin.edu.au schrieb im Newsbeitrag
news:1053054666.6955.0.camel@gnaraloo.schlegel.li…

Will try to do that with ruby.

Good. (It’s always good seeing people doing something in Ruby. :-))

Do YOU or anyone else have links to “implemented” ruby state pattern
code?

Not actually. I was experimenting a bit with a more declarative approach
to state machines but got distracted along the way. My Idea was to
provide a class which defines some keywords (in fact methods that can be
executed during class definition) that declare states and transitions.
But, as I said I didn’t get far.

Concrete I have about 7 states and more transitions.

Did look at your solution. I think I would like to seperate the
different states with their own classes as they might get a little bit
bigger.

Sounds very reasonable.

Regards

robert

PS: I don’t know whether I am the only one having the problem, but your
message came as an attachment. Maybe you can change your NR’s settings.

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
Don’t forget to look at the ‘delegate’ module which is documented in
‘Programming Ruby’ (http://www.rubycentral.com/book/lib_patterns.html).

Did look at your solution. I think I would like to seperate the
different states with their own classes as they might get a little bit
bigger.

Good, that’s the conventional approach to the state pattern.

Simon

···

On Fri, 16 May 2003 at 02:59 GMT, Sacha Schlegel wrote:


If you want to travel around the world and be invited to speak at a lot of
different places, just write a Unix operating system.

                                                -- Linus Torvalds

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com schrieb im
Newsbeitrag news:pan.2003.05.13.11.04.00.160567@sneakemail.com

I’d like to hear what people think: is this a reasonable
implementation of
the state pattern?

You are representing each state by a number… with the State pattern
isn’t each state supposed to be represented by a class ?

Normally, yes. The association with a number is just for the ease of
keying the example in.

OK.

My main idea was to replace the state instance by
a redefinition of instance methods.

Interesting thought. So instead of having a state variable you redefine
some state-transition-methods. Clever :slight_smile:

Am I understanding you correct ?

Pro is, you safe an instance and a redirection;
on the con side is increased code size for the class since
you have to include code for all states.

Because you don’t have an explicit state variable, the state becomes
implicit. Thus its hard to tell the current state…
Just a thought :slight_smile:

I’m curios to know whether anybody did this before. I might be missing
some grave disadvantage.

Kind of… not tried the same. I have done some state machines from time to
time.

···

On Tue, 13 May 2003 14:04:33 +0200, Robert Klemme wrote:

On Tue, 13 May 2003 10:11:42 +0200, Robert Klemme wrote:


Simon Strandgaard

Probably stupid, but all I can think of right now:

  • easier to screw up things as the state is defined implicitly by the
    singleton methods, so you could probably reach “non-valid states” (if
    you forget to redefine one method)
  • cannot serialize these things, i.e. cannot capture the state of the
    object (related to the latter)

Finally:

  • no clean separation between the place where you define state
    transitions and the state methods/attributes (which can be a good or
    bad thing depending on how you see it)

OTOH, it is clever (extra points!!! ;-), faster than delegation, and
uses singleton methods (we love them, don’t we? :slight_smile:

···

On Tue, May 13, 2003 at 08:11:38PM +0900, Robert Klemme wrote:

I’d like to hear what people think: is this a reasonable
implementation of
the state pattern?

You are representing each state by a number… with the State pattern
isn’t each state supposed to be represented by a class ?

Normally, yes. The association with a number is just for the ease of
keying the example in. My main idea was to replace the state instance by
a redefinition of instance methods. Pro is, you safe an instance and a
redirection; on the con side is increased code size for the class since
you have to include code for all states.

I’m curios to know whether anybody did this before. I might be missing
some grave disadvantage.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Q: What’s the big deal about rm, I have been deleting stuff for years? And
never lost anything… oops!
A: …
– From the Frequently Unasked Questions

“Simon Vandemoortele” deliriousREMOVEUPPERCASETEXTTOREPLY@atchoo.be
schrieb im Newsbeitrag news:987xa.4791$1u5.452@afrodite.telenet-ops.be…

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.)

If a state needs info about its sourroundings, maybe it would make sense
to use a binding instead, which was generated in class Client (or
Context). Just a thought.

Regards

robert
···

On Fri, 16 May 2003 at 02:59 GMT, Sacha Schlegel wrote:

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com schrieb im
Newsbeitrag news:pan.2003.05.13.11.22.58.618215@sneakemail.com

My main idea was to replace the state instance by
a redefinition of instance methods.

Interesting thought. So instead of having a state variable you redefine
some state-transition-methods. Clever :slight_smile:

Am I understanding you correct ?

Not completely. I don’t necessarily redefine the state transition methods
but these methods redefine other methods that are supposed to change their
behavior in different states. Of course, state transition methods could
be redefined as well, but I don’t know how messy this will become…

Pro is, you safe an instance and a redirection;
on the con side is increased code size for the class since
you have to include code for all states.

Because you don’t have an explicit state variable, the state becomes
implicit. Thus its hard to tell the current state…
Just a thought :slight_smile:

The main problem with this is, that you can’t store the current state as
Mauricio pointed out.

I’m curios to know whether anybody did this before. I might be
missing
some grave disadvantage.

Kind of… not tried the same. I have done some state machines from time
to
time.

Most of us did, I guess.

robert

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20030513124716.GA12385@student.ei.uni-stuttgart.de

I’d like to hear what people think: is this a reasonable
implementation of
the state pattern?

You are representing each state by a number… with the State
pattern
isn’t each state supposed to be represented by a class ?

Normally, yes. The association with a number is just for the ease of
keying the example in. My main idea was to replace the state instance
by
a redefinition of instance methods. Pro is, you safe an instance and
a
redirection; on the con side is increased code size for the class
since
you have to include code for all states.

I’m curios to know whether anybody did this before. I might be
missing
some grave disadvantage.

Probably stupid, but all I can think of right now:

  • easier to screw up things as the state is defined implicitly by the
    singleton methods, so you could probably reach “non-valid states” (if
    you forget to redefine one method)

Yeah, sounds reasonable. One can forget do implement a method in a state
class but this might easier show up since the state class can be tested
separately.

  • cannot serialize these things, i.e. cannot capture the state of the
    object (related to the latter)

That’s a major drawback IMHO - at least for applications that need to save
state.

Finally:

  • no clean separation between the place where you define state
    transitions and the state methods/attributes (which can be a good or
    bad thing depending on how you see it)

Yes, states behavior gets mangled back into the class again. That’s kind
of anti state pattern…

OTOH, it is clever (extra points!!! ;-), faster than delegation, and
uses singleton methods (we love them, don’t we? :slight_smile:

Yes, of course! :-))

robert
···

On Tue, May 13, 2003 at 08:11:38PM +0900, Robert Klemme wrote:

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

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

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).

Wish I had my DP.book_instance at hand too :wink:

···

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.)


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Not only Guinness - Linux is good for you, too.
– Banzai on IRC

“as Mauricio pointed out”… It was actually me who pointed it out first :slight_smile:
Compare the id’s of these two threads:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/71317
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/71322

Challenges is good :slight_smile:

···

On Tue, 13 May 2003 16:53:11 +0200, Robert Klemme wrote:

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com schrieb im

Because you don’t have an explicit state variable, the state becomes
implicit. Thus its hard to tell the current state…
Just a thought :slight_smile:

The main problem with this is, that you can’t store the current state as
Mauricio pointed out.


Simon Strandgaard

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20030516163808.GA28479@student.ei.uni-stuttgart.de

“Simon Vandemoortele” deliriousREMOVEUPPERCASETEXTTOREPLY@atchoo.be
schrieb im Newsbeitrag
news:987xa.4791$1u5.452@afrodite.telenet-ops.be…

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 :wink:

:slight_smile:

Cheers

robert
···

On Sat, May 17, 2003 at 12:59:44AM +0900, Robert Klemme wrote:

On Fri, 16 May 2003 at 02:59 GMT, Sacha Schlegel wrote:

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.

As I see it, you simply use an object which goes through internal
transformations (state) depending on the operations you perform and
whatever else. Why should the client get the internal state? It should
be hidden inside the object.

For instance (kinda like the example in the GOF, but cannot really
remember)

socket = TCPConnection.new(“www.somehost.com”, 80)
socket.state # => “offline”
data = socket.receive(100) # on demand connection
socket.state # => “connected”

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 :wink:

My case is worse because I bought it but then left it 1800km away :stuck_out_tongue:

···

On Tue, May 20, 2003 at 01:04:34AM +0900, Robert Klemme wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

ECRC hat keine lynx komp. seiten, sowas MUSS ja pleite gehen ;-)=
– Getty on #LinuxGER

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20030519162147.GA9282@student.ei.uni-stuttgart.de

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.

As I see it, you simply use an object which goes through internal
transformations (state) depending on the operations you perform and
whatever else. Why should the client get the internal state? It should
be hidden inside the object.

For instance (kinda like the example in the GOF, but cannot really
remember)

socket = TCPConnection.new(“www.somehost.com”, 80)
socket.state # => “offline”
data = socket.receive(100) # on demand connection
socket.state # => “connected”

Hm. Maybe I got the state pattern wrong. With your example: if class
Socket had status messages to print for some reason (i.e. they are NOT
part of the state class implementations, maybe because you can set them
from the outside for language customization or whatever). So we have an
offlineMessage and an connectedMessage. Now, if behavior of Socket should
change via a changed state instance I’d implement

class Socket
def statusMessage(); @state.statusMessage; end
end

Now, @state.statusMessage needs to access the Socket it’s attached to. We
can achieve this by

  • recording a ref to socket in state
  • augmenting every method call on state with the socket reference
  • put all socket state info that the state needs (i.e. the two messages)
    in all state classes (clearly not intended by this pattern)
  • ?

I find all these a bit awkward…

My case is worse because I bought it but then left it 1800km away :stuck_out_tongue:

Darn!

robert
···

On Tue, May 20, 2003 at 01:04:34AM +0900, Robert Klemme wrote:

Crap, I don’t remember what should be done w/ shared attributes.
I’ll see if I can get my book sent here :slight_smile:

Ummm, now I remember something about internalizing information and
the applicability of the State DP… really need the book.

···

On Tue, May 20, 2003 at 02:07:41AM +0900, Robert Klemme wrote:

class Socket
def statusMessage(); @state.statusMessage; end
end

Now, @state.statusMessage needs to access the Socket it’s attached to. We
can achieve this by

  • recording a ref to socket in state
  • augmenting every method call on state with the socket reference
  • put all socket state info that the state needs (i.e. the two messages)
    in all state classes (clearly not intended by this pattern)
  • ?

I find all these a bit awkward…


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

“Who is General Failure and why is he reading my hard disk?”
Microsoft spel chekar vor sail, worgs grate !!
– Felix von Leitner, leitner@inf.fu-berlin.de

Why not use the internet? A quick Google search revealed

C# Design Patterns

which has code in C# but should be helpful to you. I’m sure there’s
lots of other sites too.

Regards,
Pit

···

On 20 May 2003 at 2:28, Mauricio Fernández wrote:

Crap, I don’t remember what should be done w/ shared attributes.
I’ll see if I can get my book sent here :slight_smile:

Ummm, now I remember something about internalizing information and
the applicability of the State DP… really need the book.

“Pit Capitain” pit@capitain.de schrieb im Newsbeitrag
news:3ECA8A4E.10891.1BF8A8FC@localhost…

Crap, I don’t remember what should be done w/ shared attributes.
I’ll see if I can get my book sent here :slight_smile:

Ummm, now I remember something about internalizing information and
the applicability of the State DP… really need the book.

Why not use the internet? A quick Google search revealed

C# Design Patterns

which has code in C# but should be helpful to you. I’m sure there’s
lots of other sites too.

Thanks for the link. But honestly, I don’t like the examples - not just
because method names start with uppercase letters and thus decrease
readability. I find it awful that all relevant state info (balance) must be
transferred to the next state instance.

The non realworld example used the “yield the context with every method
call”. But both change the state instance of the Context (Account)
directly. And the state is a public member, which doesn’t fit my
understanding: the state logic should be completely internal IMHO.

Regards

robert
···

On 20 May 2003 at 2:28, Mauricio Fernández wrote: