method reference - repost

N

Neil Shadrach

[ Apologies for reposting this - my local news server has been unwell
and 1 day on it hasn't appeared in Google and I've seen no reply so
I'm assuming it didn't get out to the wider world ]

If both

my $m=@{$o->{lst}}[0];

and

my $m=$t->[0];

successfully set $m to a reference to a method such that

$o->$m( 20 );

calls the method for the instance $o

how could it be called without creating the intermediate $m ?

Nothing depends on this - I'm just curious as to how a single
statement would be written.
Apologies if the terminology isn't correct

Thanks in advance
 
U

Uri Guttman

NS> If both

NS> my $m=@{$o->{lst}}[0];

ever heard of white space? try to use some. and even in examples, don't
use single char names.

and did you try that code with warnings enabled? you are doing a slice
with a single index and that is not good code.

and if you want the first element of the list then use the simpler code:

my $meth = $obj->{lst}[0] ;

NS> and

NS> my $m=$t->[0];

NS> successfully set $m to a reference to a method such that

NS> $o->$m( 20 );

NS> calls the method for the instance $o

NS> how could it be called without creating the intermediate $m ?

can't be done. it has nothing to do with how you get the dynamic
method. the method slot of a call must be a single scalar variable or
bareword. it can't be an expression.

uri
 
F

fifo

[snip]
my $meth = $obj->{lst}[0] ;

NS> and

NS> my $m=$t->[0];

NS> successfully set $m to a reference to a method such that

NS> $o->$m( 20 );

NS> calls the method for the instance $o

NS> how could it be called without creating the intermediate $m ?

can't be done. it has nothing to do with how you get the dynamic
method. the method slot of a call must be a single scalar variable or
bareword. it can't be an expression.

Though if you really want to I believe you can cheat some somewhat. The
following should work:

$o->${ \$o->{lst}[0] }();
$o->${ \$t->[0] }();
 
B

Ben Morrow

Uri Guttman said:
NS> If both

NS> my $m=@{$o->{lst}}[0];

my $meth = $obj->{lst}[0] ;

NS> and

NS> my $m=$t->[0];

NS> successfully set $m to a reference to a method such that
^^^^^^^^^^^^^^^^^^^^^
No such thing. Do you mean a subref, or a method name? If you mean a
subref, you can simply call it:
$obj->{lst}[0]->($obj, 20);
..
NS> $o->$m( 20 );

NS> calls the method for the instance $o

NS> how could it be called without creating the intermediate $m ?

can't be done. it has nothing to do with how you get the dynamic
method. the method slot of a call must be a single scalar variable or
bareword. it can't be an expression.

Howsabout (not exactly clear, but...:)
$obj->can($obj->{lst}[0])->($obj, 20);
?

Ben
 
A

Anno Siegel

Uri Guttman said:
[...]

NS> $o->$m( 20 );

NS> calls the method for the instance $o

NS> how could it be called without creating the intermediate $m ?

can't be done. it has nothing to do with how you get the dynamic
method. the method slot of a call must be a single scalar variable or
bareword. it can't be an expression.

Well, it can, but the expression would have to return a coderef, not the
method name. I don't think that is what the OP had in mind.

Anno
 
U

Uri Guttman

f> Though if you really want to I believe you can cheat some somewhat. The
f> following should work:

f> $o->${ \$o->{lst}[0] }();
f> $o->${ \$t->[0] }();

have you tested that?

perl -e '$o=bless {}; $o->${'xyz'}()'
Can't locate object method "" via package "main" (perhaps you forgot to load "main"?) at -e line 1.

the problem is that perl parses that at $o->( ${'xyz'}() ).

like i said, the method has to be a bareword or a single scalar
VARIABLE. this is documented (but not worded strongly enough IMO) in
perlobj

Sometimes you want to call a method when you don't know the
method name ahead of time. You can use the arrow form,
replacing the method name with a simple scalar variable
containing the method name or a reference to the function.

$method = $fast ? "findfirst" : "findbest";
$fred->$method(@args); # call by name

uri
 
U

Uri Guttman

NS> how could it be called without creating the intermediate $m ?
BM> Howsabout (not exactly clear, but...:)
BM> $obj->can($obj->{lst}[0])->($obj, 20);
BM> ?

that isn't selecting the method but getting back a code ref. not the
same thing. and i am not even sure that will be a method call there
since there is no method being used in the final call. try it out and i
bet it is just a sub call. you would need to store the result of can in
a var and call it like a normal method call with that var in the method
slot.

uri
 
U

Uri Guttman

AS> Well, it can, but the expression would have to return a coderef, not the
AS> method name. I don't think that is what the OP had in mind.

see my other posts on this. the syntax requires a literal method or a
scalar variable in the method slot. you can put a code ref value in
there but there can't be an expression in that slot.

uri
 
F

fifo

f> Though if you really want to I believe you can cheat some somewhat. The
f> following should work:

f> $o->${ \$o->{lst}[0] }();
f> $o->${ \$t->[0] }();

have you tested that?

perl -e '$o=bless {}; $o->${'xyz'}()'
Can't locate object method "" via package "main" (perhaps you forgot to load "main"?) at -e line 1.

I had in mind something like

perl -e '$o=bless{me=>"Hi"}; $t->[0]=sub{my $self = shift; print $self->{me}}; $o->${\$t->[0]}()'

which seems to work.
 
B

Ben Morrow

Uri Guttman said:
NS> how could it be called without creating the intermediate $m ?
BM> Howsabout (not exactly clear, but...:)
BM> $obj->can($obj->{lst}[0])->($obj, 20);
BM> ?

that isn't selecting the method but getting back a code ref. not the
same thing. and i am not even sure that will be a method call there
since there is no method being used in the final call.

What difference does it make? I thought that $obj->meth(@args) was
equivalent to Class::meth($obj, @args) once the method lookup has been
done (which is what can() does). Am I wrong?

(If I am wrong then yes, clearly that is a sub rather than a method
call...)

Ben
 
U

Uri Guttman

BM> Howsabout (not exactly clear, but...:)
BM> $obj->can($obj->{lst}[0])->($obj, 20);
BM> ?

BM> What difference does it make? I thought that $obj->meth(@args) was
BM> equivalent to Class::meth($obj, @args) once the method lookup has been
BM> done (which is what can() does). Am I wrong?

you lose inheritance with Class::meth($obj, @args). yes, you did get
inheritance with the can() call above but that is so fugly as to be just
fun code and not real. it still doesn't really solve the syntax issue
where only a literal method or single scalar var can be in the method
slot. no one will use your code and they will complain about not being
able to use an expression for the method without a temp var. now, i was
one of those who fell into this very trap and learned my lesson a few
years ago.

BM> (If I am wrong then yes, clearly that is a sub rather than a method
BM> call...)

well, it is a sub (code ref) call on a method looked up with can. i just
won't let it be called a real method call. :)

uri
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
anuragag27

Latest Threads

Top