state machine and a global variable

tuom.larsen at gmail.com tuom.larsen at gmail.com
Fri Dec 14 18:27:41 EST 2007


On Dec 15, 12:02 am, "Chris Mellon" <arka... at gmail.com> wrote:
> On Dec 14, 2007 4:43 PM,  <tuom.lar... at gmail.com> wrote:
>
>
>
> > On Dec 14, 11:06 pm, Bruno Desthuilliers
> > <bdesth.quelquech... at free.quelquepart.fr> wrote:
> > > tuom.lar... at gmail.com a écrit :
>
> > > > Dear list,
> > > > I'm writing very simple state machine library, like this:
>
> > > > _state = None
>
> > > > def set_state(state):
> > > >     global _state
> > > >     _state = state
>
> > > > def get_state():
> > > >     print _surface
>
> > > NameError here !-)
>
> > > > but I hate to use global variable.
>
> > > <aol />
>
> > > > So, please, is there a better way
> > > > of doing this? All I want is that a user has to type as little as
> > > > possible, like:
>
> > > > from state_machine import *
> > > > set_state(3)
> > > > get_state()
>
> > > > I.e., nothing like:
> > > > import state_machine
> > > > my_machine = state_machine.new_machine()
> > > > my_machine.set_state(3)
> > > > my_machine.get_state()
>
> > > A possible solution:
>
> > > # state_machine.py
> > > class _StateMachine(object):
> > >    def __init__(self):
> > >      self._state = SomethingHere()
> > >    def get_state(self):
> > >      return self._state
> > >    def set_state(self, xxx):
> > >      # etc
>
> > > _s = _StateMachine()
> > > get_state = _s.get_state()
> > > set_state = _s.set_state()
>
> > I guess you meant without the parentheses:
> > get_state = _s.get_state
> > set_state = _s.set_state
>
> > > You still have a global, but at least it's a machine instance, not it's
> > > state !-)
>
> > > Now the question is: why do you think it's so important for your users
> > > to only see functions ? What's so wrong with:
>
> > > from state_machine import *
> > > m = get_state_machine()
> > > m.set_state(42)
>
> > Well, I guess I can see the advantages of using the class instances
> > but ... um ... the world isn't like that! :)
>
> > Consider this: how do you add up some numbers?
> > - "My sum is zero."
> > - "I add 3 to my sum."
> > - "I add 2 to my sum."
>
> > Or:
> > - "Three."
> > - "plus two."
>
> > Implicit context, some people call it. Sometimes it's useful to be as
> > precise as possible ("explicit is better than implict", right?) but
> > sometimes, it seems to me, it's just more natural not to repeat the
> > context all over again.
>
> You're way too hung up on context when you should be hung up on state.
> Implicit state is bad, implicit global state is worse. You've got a
> shared global state, with an interface that's designed to dispatch on
> and mutate that state. It's basically every bad thing you can imagine
> about global state. Using an object means that the state machine is
> *local* state. Local state is good, because you've got a way to attach
> a name to it, to manipulate it explicitly, and to pass it around to
> other places.
>
> Your example presupposes two different use cases anyway, but most
> importantly what you're describing with sum is a mutation of local
> state (a local name binding), which is a very different thing than
> your state machine API.
>
> Honestly, I can't even imagine why you would want to implement a state
> machine *library* this way. If you meant "a library that has internal
> state" it makes a little more sense - I use an approach kind of like
> the one Bruno showed to handle global configuration and logging - but
> if you meant "a library for implementing state machines" you're on
> totally the wrong track.

Now, I very much *apologize*! I'm very sorry, I meant "a library that
has internal state", instead of "a library for implementing state
machines".

Basically, I agree that often the local state is much more useful. It
just seems to me that for some application it's an overkill. Like say,
for Turtle [1] (no jokes, please :) or PostScript [2].

[1] http://en.wikipedia.org/wiki/Logo_turtle
[2] http://en.wikipedia.org/wiki/PostScript



More information about the Python-list mailing list