http://www.perlmonks.org?node_id=430051

m-rau has asked for the wisdom of the Perl Monks concerning the following question:

I have a POE question. POE sessions can be implemented object-oriented. Question is, how to access overwritten methods?
sub new { # object creation my $class = shift; my $self = { }; bless ($self, $class); # session creation POE::Session -> create( object_states => [ $self => { _start => 'client_start', }, ], ); return $self; } sub client_start { # this is an overwritten method!!! my ($self, $kernel, $heap, $session) = @_[ OBJECT, KERNEL, HEAP, S +ESSION ]; # child code goes here # [...] # now, access the overwritten parent method $self -> SUPER::client_start( @_ ); }

This does not work, since $self -> SUPER::client_start pushes $self on to @_, I guess.

Replies are listed 'Best First'.
Re: POE OO sessions - accessing overwritten methods
by Tanktalus (Canon) on Feb 11, 2005 at 15:06 UTC

    You need to always shift off $self if you're going to use @_ again.:

    sub client_start { my $self = shift; # this is an overwritten method!!! my ($kernel, $heap, $session) = @_[ KERNEL, HEAP, SESSION ]; # child code goes here # [...] # now, access the overwritten parent method $self -> SUPER::client_start( @_ ); }
    $self has to be the first param, so your OBJECT is kinda redundant, IMO

      Thanks for your advice. But from my point of view, there is a problem with this solution.

      Designing client_start like this breaks down the regular call of the parent's client_start. In OO design, the OBJECT constant contains 0 and the KERNEL constant contains 1. If I remove $self from @_, KERNEL still refers to 1 and I cannot access it utilizing my ($self, $kernel, $heap, $session) = @_[ OBJECT, KERNEL, HEAP, SESSION ];.

      But I found the solution in http://poe.perl.org/?POE_Cookbook/Object_Methods:

      Disadvantages * Some people don't like OO. * Because @_ has so much in it, one has to do silly things like shift(@_)->SUPER::subroutine(@_); to call parent POE-related methods.
      With this rational to access overwritten parent methods, client_start can keep my ($self, $kernel, $heap, $session) = @_[ OBJECT, KERNEL, HEAP, SESSION ];.

      The solution is in sync with your advice and with holli's very general comment, too. Problem is, that both advices do not really reflect the special POE object design :-)

        Thanks for the update ... although I have to say, I like OO, and I don't like this. I've thought about investigating POE in the past - but something like this would drive me completely away from it. I would rather get named parameters than this. In fact, named parameters would be faster than this, too. I'm really not sure what they're trying to do with this - it's unintuitive, it's ugly, and it's slow. (Funny how that works in perl - often the intuitive, clean solutions are pretty darned close to the fastest, too.)

        Given all that POE has to do, This design decision seems crazy unintuitive to me.

        Update:Typo fixed, changing the way the benchmark worked. Still find it ugly :-)

Re: POE OO sessions - accessing overwritten methods
by holli (Abbot) on Feb 11, 2005 at 16:06 UTC
    Wisdom from the fabulous perlboot:
    The invocation of: Class->method(@args) attempts to invoke subroutine Class::method as: Class::method("Class", @args); (If the subroutine can't be found, ``inheritance'' kicks in, but we'll get to that later.) This means that we get the class name as the first parameter (the only parameter, if no arguments are given).
    holli, /regexed monk/