Implementing State pattern
Justin_BSI
created: 2006-05-02 19:15:17
I was playing around with classes within Perl and trying to implement some of the patterns I've used in the past when I hit a road block. I'm still relatively new to Perl, and I can't seem to figure out what is going on here with this State pattern.
#### a driver for the car
{ package Driver;
    sub new {
        my $class = shift;
        my $vars = {};
        $vars->{ALERTNESS} = 0;
        $vars->{STATE} = dstatenorm->new();
        bless ($vars, $class);
        return $vars; }

    sub alertness {
        my $vars = shift;
        my $state = $vars->{STATE};
        if(@_) { $vars->{ALERTNESS} = shift; }
        return $state->alertness( $vars->{ALERTNESS} ); }

    1; }

#### driver state normal
{ package dstatenorm;
    sub new {
        my $class = shift;
        my $vars = {};
        $vars->{"NAME"} = "Normal";
        bless ($vars, $class);
        return $vars; }

    sub alertness ($) {
        my $curAlertness = shift;
        return $curAlertness; }

    1; }
When I call the "alertness" routine on the driver, I get dstatenorm=HASH(0x1832734). It looks like I'm getting close to the return I want, but I'm not sure where or how or if I have to dereference to make this work. Thanks in advance!

Update: Found it. I was shifting and the first value is the class itself. Shifting twice did the trick, so I guess I have to access @_ directly?

Re: Implementing State pattern
created: 2006-05-02 19:25:13

You didn't include an accessor in dstatenorm to fetch the NAME.

package dstatenorm;
...
sub name {
    my $self = shift @_;
    return $self->{NAME};
}

Then in your code, request the name of the state.

print $driver->alertness->name

PS: don't use prototypes especially when writing object oriented code.

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re^2: Implementing State pattern
created: 2006-05-02 19:39:46
I'm not actually looking for the name of the state in the "alertness" routine, instead I am expecting a reply of the driver's alertness value. In the State pattern, the state makes modifications to (or performs functions on) the values of the "owning" class. For instance, if I made a state for the driver that was called "dstatetired" I could have the alertness routine return $curAlertness - 2;. I would set the current state through routines in the driver class.

That being said, thank you for reminding me about the accessor and I will quit prototyping in my OO code (I'm used to Java, so pardon me.)

Re: Implementing State pattern
created: 2006-05-02 19:57:44
You're calling alertness as a method, on the $state object. That means alertness() the sub receives $state the object as its first argument. You shift that into $curAlertness, and return it. You're also not doing anything with the other parameter that you pass in ($vars->{ALERTNESS}), so the $state object never gets updated.

I suspect you want something like this for the implementation of alertness:

sub alertness {
    my $self = shift;

    if( @_ ) {
       $self->{STATE} = shift;
    }

    return $self->{STATE};
}

perlmonks.org content © perlmonks.org and diotalevi, Justin_BSI, rhesa

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03