Camel book: why invoke in the manner @{[&whowasi]}?

S

Suresh Govindachar

#!/use/bin/perl
BEGIN {(*STDERR = *STDOUT) || die;}
use diagnostics;
use warnings;
use strict;

=head
Hello,

In the 'Tying Hashes' section of the Camel book (pg 378+),
a subroutine called whowasi is invoked in the
following two ways,

1) @{[&whowasi]}
and 2) &whowasi

I could not figure out what the first method of
invocation does and so wrote this code to see
the difference in results. But I find no
difference in the results of the two invocations!
(The output is given below after the __END__.)

Please explain what the first method of invocation
is all about.

Thanks,

--Suresh
=cut

use Carp;
sub whowasi { (caller(1))[3] . "()" }
my $DEBUG = 0;
sub debug { $DEBUG = @_ ? shift : 1 }

sub the_place
{
print "\n",'carp "usage: @{[ &whowasi ]} [USER [DOTDIR]]";',"\n";
carp "usage: @{[ &whowasi ]} [USER [DOTDIR]]";

print "\n", 'carp "@{[&whowasi]}: ";', "\n";
carp "@{[&whowasi]}: ";

print "\n", 'carp &whowasi if $DEBUG;' ,"\n";
carp &whowasi if $DEBUG;

debug();
print "\nafter setting DEBUG:\n";
carp &whowasi if $DEBUG;

print "\n",'croak "usage: @{[ &whowasi ]} [USER [DOTDIR]]";',"\n";
croak "usage: @{[ &whowasi ]} [USER [DOTDIR]]";
print "\nshould NOT see this\n";
}

sub the_caller
{
the_place(53);
}

sub the_sub
{
the_caller();
}

print "in main:\n";
the_sub();

__END__
Output is as follows:

in main:

carp "usage: @{[ &whowasi ]} [USER [DOTDIR]]";
usage: main::the_place() [USER [DOTDIR]] at ..\tms\drafts\current line 40
main::the_place(53) called at ..\tms\drafts\current line 59
main::the_caller() called at ..\tms\drafts\current line 64
main::the_sub() called at ..\tms\drafts\current line 68

carp "@{[&whowasi]}: ";
main::the_place(): at ..\tms\drafts\current line 43
main::the_place(53) called at ..\tms\drafts\current line 59
main::the_caller() called at ..\tms\drafts\current line 64
main::the_sub() called at ..\tms\drafts\current line 68

carp &whowasi if $DEBUG;

after setting DEBUG:
main::the_place() at ..\tms\drafts\current line 50
main::the_place(53) called at ..\tms\drafts\current line 59
main::the_caller() called at ..\tms\drafts\current line 64
main::the_sub() called at ..\tms\drafts\current line 68

croak "usage: @{[ &whowasi ]} [USER [DOTDIR]]";
Uncaught exception from user code:
usage: main::the_place() [USER [DOTDIR]] at ..\tms\drafts\current line 53
main::the_place(53) called at ..\tms\drafts\current line 59
main::the_caller() called at ..\tms\drafts\current line 64
main::the_sub() called at ..\tms\drafts\current line 68
main::the_place(53) called at ..\tms\drafts\current line 59
main::the_caller() called at ..\tms\drafts\current line 64
main::the_sub() called at ..\tms\drafts\current line 68
 
G

Gunnar Hjalmarsson

Suresh said:
In the 'Tying Hashes' section of the Camel book (pg 378+), a
subroutine called whowasi is invoked in the following two ways,

1) @{[&whowasi]}
and 2) &whowasi

I could not figure out what the first method of invocation does

It gets interpolated in a doublequoted context.
Please explain what the first method of invocation is all about.

sub foo { "Now foo() was interpolated!" }
print "foo()\n";
print "@{ [foo()] }\n";
 
A

Alan Stewart

#!/use/bin/perl
BEGIN {(*STDERR = *STDOUT) || die;}
use diagnostics;
use warnings;
use strict;

=head
Hello,

In the 'Tying Hashes' section of the Camel book (pg 378+),
a subroutine called whowasi is invoked in the
following two ways,

1) @{[&whowasi]}
and 2) &whowasi

I could not figure out what the first method of
invocation does and so wrote this code to see
the difference in results. But I find no
difference in the results of the two invocations!
(The output is given below after the __END__.)

Please explain what the first method of invocation
is all about.

Thanks,

--Suresh
=cut

use Carp;
sub whowasi { (caller(1))[3] . "()" }
my $DEBUG = 0;
sub debug { $DEBUG = @_ ? shift : 1 }

sub the_place
{
print "\n",'carp "usage: @{[ &whowasi ]} [USER [DOTDIR]]";',"\n";
carp "usage: @{[ &whowasi ]} [USER [DOTDIR]]";

Interpolated into a string.
print "\n", 'carp "@{[&whowasi]}: ";', "\n";
carp "@{[&whowasi]}: ";
Interpolated.


print "\n", 'carp &whowasi if $DEBUG;' ,"\n";
carp &whowasi if $DEBUG;

Not interpolated.
debug();
print "\nafter setting DEBUG:\n";
carp &whowasi if $DEBUG;

Not interpolated.
print "\n",'croak "usage: @{[ &whowasi ]} [USER [DOTDIR]]";',"\n";
croak "usage: @{[ &whowasi ]} [USER [DOTDIR]]";
print "\nshould NOT see this\n";
}

sub the_caller
{
the_place(53);
}

sub the_sub
{
the_caller();
}

print "in main:\n";
the_sub();

__END__

Variables will interpolate into strings but functions will not. This
is a well known trick to get a function into a quoted string.
Functions will execute to get the value of an item in a list, so
[$whowasi] produces an anonymous list reference which is de-referenced
by @{ } to an array that will interpolate.

Back up a page to Camel pg 377 for the other way !

Alan
 
B

Brian McCauley

Suresh said:
In the 'Tying Hashes' section of the Camel book (pg 378+),
a subroutine called whowasi is invoked in the
following two ways,

1) @{[&whowasi]}
and 2) &whowasi

Function calls do not interpolate into double-quoted strings so if you
want to put the result of a function call into the middle a string you
can either use explicit concatenation or use the @{[...]} trick.

See FAQ: How do I expand function calls in a string?

If you ever see the @{[ somefunc ]} construct not in an interpolative
context then it may be being used for it's other effect of 'uncoupling'
values in the situation where somefunc returns lvalues.

Calling the function call syntax with a leading & and without any ()
supresses all the @_ handling. The @_ seen inside the whowasi function
is the caller's @_. (See perlsub). This is occasionaly really useful
in advanced programming but more often is just done as a (possibly
premature) optomisation or through ignorance.
 

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
473,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top