Home > Archive > PERL POE > April 2008 > Accessors
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
|
|
| John R. 2008-04-08, 7:58 pm |
| From the 1.0 documentation (very good by the way):
"call() returns the value returned by the EVENT_NAME handler. It can do
this because the handler is invoked before call() returns. call() can
therefore be used as an accessor, although there are better ways to
accomplish simple accessor behavior."
(from POE::Kernel)
I don't see reference to the better ways so they probably are standard
perlish ways of doing things that I am having difficulty figuring out.
What other ways are there to accomplish accessors that provide access to
POE things like the heap? I am doing calls within a session and between
sessions. Should I pass the heap, kernel, etc as arguments to regular
sub calls?
Thanks,
John
| |
| Rocco Caputo 2008-04-09, 8:20 pm |
| My favorite method (har) is to wrap the session in an object that acts
as its interface and also its storage.
POE::Component::Client::KeepAlive is implemented this way.
In brief, new() creates the object and spawns a hidden POE::Session.
object_states map events to private methods on the new object. Public
methods on the object act as accessors and mutators, and can be used
to send commands into the hidden session.
sub new {
my $class = shift;
my $self = bless { }, $class;
POE::Session->create(
object_states => {
_start => "_poe_start_handler",
lala_changed => "_poe_lala_changed",
do_something => "_poe_do_something",
...,
}
);
return $self;
}
The session's _start handler sets its alias to be the stringified
object reference. More on this later.
sub _poe_start_handler {
$_[KERNEL]->alias_set("$_[OBJECT]");
}
From event handlers:
sub _poe_handler {
my ($self, $heap) = @_[OBJECT, HEAP];
$self->{lala} = 123; # visible from $object->accessor()
$heap->{lala} = "abc"; # not visible from the OO interface
}
From accessors:
sub accessor {
my $self = shift;
return $self->{lala};
}
Mutators can trigger POE events by calling "$self" (stringified object
reference). This is the alias set in _poe_start_handler().
sub mutator {
my ($self, $new_lala) = @_;
$self->{lala} = $new_lala;
$poe_kernel->call("$self", lala_changed => $new_lala);
return $new_lala;
}
sub _poe_lala_changed {
my $new_lala = $_[ARG0];
my $other_new_lala = $_[OBJECT]{lala};
# do something here
}
And "command" methods can call "$self" without setting members.
sub do_something {
my $self = shift;
$poe_kernel->call("$self", do_something => @_);
}
sub _poe_do_something {
# don't just stand there!
return "result";
}
....
This isn't a best practice, however. It implies a 1:1 ration of
sessions to objects, which isn't ideal. The ideal, best way is to
implement a dispatcher that lets many objects share a smaller set of
sessions. POE::Stage is implemented this way, but it's not ready for
production yet.
A compromise: Embed POE sessions in I/O objects, and use regular Perl
objects for everything else.
--
Rocco Caputo - rcaputo@pobox.com
On Apr 8, 2008, at 20:04, John R. wrote:
> From the 1.0 documentation (very good by the way):
>
> "call() returns the value returned by the EVENT_NAME handler. It
> can do
> this because the handler is invoked before call() returns. call() can
> therefore be used as an accessor, although there are better ways to
> accomplish simple accessor behavior."
>
> (from POE::Kernel)
>
> I don't see reference to the better ways so they probably are
> standard perlish ways of doing things that I am having difficulty
> figuring out. What other ways are there to accomplish accessors that
> provide access to POE things like the heap? I am doing calls within
> a session and between sessions. Should I pass the heap, kernel, etc
> as arguments to regular sub calls?
>
> Thanks,
>
> John
| |
| John R. 2008-04-09, 8:20 pm |
| Rocco Caputo wrote:
[snipped all sorts of great stuff]
Thanks! This helps clarify quite a bit for me.
John
| |
| Rohan Almeida 2008-04-10, 6:02 am |
|
For simple accessors, you can also use Class::Accessor
package PoeWithAccessors;
use strict;
use warnings;
use base qw/ Class::Accessor /;
use POE::Session;
__PACKAGE__->mk_accessors(
qw/
state
connection
client_ip
/
);
sub spawn
{
my ( $class, $params_ref ) = @_;
my $self = {};
bless $self, $class;
# initial state
$self->state('CONNECTED');
# client IP address
$self->client_ip( $params_ref->{client_ip} );
# Create a new POE Session
POE::Session->create(
object_states => [
$self => [
qw/
_start got_data logged_out _stop
/
]
],
heap => {
%{$params_ref},
},
);
return 1;
}
sub got_data
{
my ( $kernel, $heap, $session, $self )
= @_[ KERNEL, HEAP, SESSION, OBJECT ];
$self->state('GOT_DATA');
}
Hope the above example makes sense :) Note OBJECT which gives you
your blessed ref in your event handlers.
--
Rohan
John R. wrote:
> From the 1.0 documentation (very good by the way):
>
> "call() returns the value returned by the EVENT_NAME handler. It can do
> this because the handler is invoked before call() returns. call() can
> therefore be used as an accessor, although there are better ways to
> accomplish simple accessor behavior."
>
> (from POE::Kernel)
>
> I don't see reference to the better ways so they probably are standard
> perlish ways of doing things that I am having difficulty figuring out.
> What other ways are there to accomplish accessors that provide access to
> POE things like the heap? I am doing calls within a session and between
> sessions. Should I pass the heap, kernel, etc as arguments to regular
> sub calls?
>
> Thanks,
>
> John
>
| |
| Pedro Melo 2008-04-10, 6:02 am |
|
On Apr 9, 2008, at 10:22 PM, Rocco Caputo wrote:
> My favorite method (har) is to wrap the session in an object that
> acts as its interface and also its storage.
> POE::Component::Client::KeepAlive is implemented this way.
>
> In brief, new() creates the object and spawns a hidden
> POE::Session. object_states map events to private methods on the
> new object. Public methods on the object act as accessors and
> mutators, and can be used to send commands into the hidden session.
+1. All my POE code works this way. I think it's the best match
between POE and OO-Perl.
Best regards,
--
Pedro Melo
Blog: http://www.simplicidade.org/notes/
XMPP ID: melo@simplicidade.org
Use XMPP!
|
|
|
|
|