Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any difference between &$func($arg) and $func->($arg)?

Tags:

perl

While trying to understand closures, reading thru perl-faq and coderef in perlref found those examples:

sub add_function_generator {
    return sub { shift() + shift() };
}
my $add_sub = add_function_generator();
my $sum = $add_sub->(4,5);

and

sub newprint {
    my $x = shift;
    return sub { my $y = shift; print "$x, $y!\n"; };
}
$h = newprint("Howdy");
&$h("world");

here are two forms of calling a function stored in a variable.

&$func($arg)
$func->($arg)

Are those totally equivalent (only syntactically different) or here are some differences?

like image 262
novacik Avatar asked Dec 12 '22 08:12

novacik


1 Answers

There is no difference. Proof: the opcodes generated by each version:

$ perl -MO=Concise -e'my $func; $func->()'
8  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
3     <0> padsv[$func:1,2] vM/LVINTRO ->4
4     <;> nextstate(main 2 -e:1) v:{ ->5
7     <1> entersub[t2] vKS/TARG ->8
-        <1> ex-list K ->7
5           <0> pushmark s ->6           
-           <1> ex-rv2cv K ->-           
6              <0> padsv[$func:1,2] s ->7
$ perl -MO=Concise -e'my $func; &$func()'
8  <@> leave[1 ref] vKP/REFC ->(end)     
1     <0> enter ->2                      
2     <;> nextstate(main 1 -e:1) v:{ ->3 
3     <0> padsv[$func:1,2] vM/LVINTRO ->4
4     <;> nextstate(main 2 -e:1) v:{ ->5 
7     <1> entersub[t2] vKS/TARG ->8      
-        <1> ex-list K ->7               
5           <0> pushmark s ->6           
-           <1> ex-rv2cv sKPRMS/4 ->-    
6              <0> padsv[$func:1,2] s ->7

… wait, there are actually slight differences in the flags for - <1> ex-rv2cv sKPRMS/4 ->-. Anyways, they don't seemt to matter, and both forms behave the same.

But I would recommend to use the form $func->(): I perceive this syntax as more elegant, and you can't accidentally forget to use parens (&$func works but makes the current @_ visible to the function, which is not what you'd usually want).

like image 89
amon Avatar answered Jan 05 '23 10:01

amon