For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > July 2005 > Indirect method invocation









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]

 

Author Indirect method invocation
Jan Eden

2005-07-27, 5:02 pm

Hi,

it does not seem to be possible to use indirect method invocation with anyt=
hing but a scalar. While this works:

my $mode =3D $parameters{mode};
$item->$mode();

I cannot seem to find a proper bracketing to make this work:

$item->$parameters{mode}();

Is my assumption correct?

My other problem is that the cookbook quotes (something like) the following=
code as an example for storing method names:

my %actions =3D (
display =3D> $item->display(),
move_picture =3D> $item->move_picture($item->{id}, $item->{parameters}->{po=
sition}),
commit =3D> $item->commit()
);

Now I thought I could use

$actions{$parameter{mode}};

to invoke the proper method, but I get a "Useless use of hash element in a =
void context" error.

I can see why I get that error - but why would someone want to build a hash=
like %actions then, which just maps names to method invocations, without a=
way to actually get to those method invocations?

In other words, I would like to have something like the %actions hash to co=
nstruct a more flexible version of the $item->$mode() construct, where I ca=
n pass different additional parameters to each method.

Thanks,

Jan

I have known more men destroyed by the desire to have wife and child and t=
o keep them in comfort than I have seen destroyed by drink and harlots. - W=
=2EB. Yates
Jan Eden

2005-07-27, 5:02 pm

Hi,

Jan Eden wrote on 27.07.2005:

>In other words, I would like to have something like the %actions
>hash to construct a more flexible version of the $item->$mode()
>construct, where I can pass different additional parameters to each
>method.


I finally came up with something myself:

my %actions =3D (
display =3D> sub { $item->display() },
move_picture =3D> sub { $item->move_picture($item->{id}, $item->{parame=
ters}->{position}) },
commit =3D> sub { $item->commit() }
);

$actions{$parameters{mode}}->();

Thanks,

Jan
--=20
I used to have a Heisenbergmobile. Every time I looked at the speedometer, =
I got lost.
Xavier Noria

2005-07-27, 5:02 pm

On Jul 27, 2005, at 17:21, Jan Eden wrote:

> My other problem is that the cookbook quotes (something like) the
> following code as an example for storing method names:
>
> my %actions = (
> display => $item->display(),
> move_picture => $item->move_picture($item->{id}, $item->
> {parameters}->{position}),
> commit => $item->commit()
> );


Are you sure? $item->display() returns whatever the display() method
returns, which might be a coderef, but looks unlikely.

Since you can't get a reference to a method (bound to an instance) as
you do with regular subroutines, the technique normally is to wrap
them in an anonyomus closure like this:

package Foo;

sub new { bless {}, shift }
sub method { print "Moo!" }

package main;

my $foo = Foo->new;
my %actions = (foo => sub { $foo->method(@_) } );
$actions{foo}(); # prints "Moo!"

-- fxn


Randal L. Schwartz

2005-07-27, 5:02 pm

>>>>> "Jan" == Jan Eden <lists@janeden.org> writes:

Jan> I finally came up with something myself:

But that's no longer a method call.

You can do an indirect method call, but it needs to be a simple scalar:

my $method = $parameters{mode};
$object->$methods(@args);

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com