@{[times[}

P

Patrick Flaherty

Hi,

Started using @{[times]} recently for measuring run (execution) time. (I'm
aware that there's also a Benchmark module).

To figure out what was going on here, I first looked up times in perlvar - not
there. Then thought to try perlfunc. Ah.

So what's the magic, in particular in {[...]}, that converts the return array
into an array-on-the-fly?

I understand that @ refers to arrays and [] also. But what still has me a
little mystified is how, evaluating from in-to-out, when you go from [ to { and
then @, you start at a function and its return value (an array [or list?]) and
end up where you do.

Looked this up in the Nutshell _Perl Programming_ but didn't find an answer.

thanx.

pat
 
G

Gunnar Hjalmarsson

Patrick said:
Started using @{[times]} recently for measuring run (execution)
time. (I'm aware that there's also a Benchmark module).

To figure out what was going on here, I first looked up times in
perlvar - not there. Then thought to try perlfunc. Ah.

So what's the magic, in particular in {[...]}, that converts the
return array into an array-on-the-fly?

I understand that @ refers to arrays and [] also. But what still
has me a little mystified is how, evaluating from in-to-out, when
you go from [ to { and then @, you start at a function and its
return value (an array [or list?]) and end up where you do.

perldoc -q "expand function"
 
P

Paul Lalli

Gunnar Hjalmarsson said:
Patrick said:
Started using @{[times]} recently for measuring run (execution)
time. (I'm aware that there's also a Benchmark module).

To figure out what was going on here, I first looked up times in
perlvar - not there. Then thought to try perlfunc. Ah.

So what's the magic, in particular in {[...]}, that converts the
return array into an array-on-the-fly?

I understand that @ refers to arrays and [] also. But what still
has me a little mystified is how, evaluating from in-to-out, when
you go from [ to { and then @, you start at a function and its
return value (an array [or list?]) and end up where you do.

perldoc -q "expand function"

Unfortunately the FAQ doesn't actually answer the question of *how* this
works, just that it does.

Work backwards. Start with the function call. The function will return
a value or list of values, depending in part on context. The [ ] is a
construct to create an anonymous array reference. It therefore imposes
a list context. So the function will return a list of values. (That
list can, of course, contain only one or even zero items). That list of
items is used to populate the anonymous array created by (and referenced
by) the [ ]. So you have an anonymous array reference. Finally, @{ }
is the syntax used to take whatever is enclosed by { } and dereference
that as an array. If, for example, $ref is an array reference, @{$ref}
is the array referenced by $ref.. So @{ [ ... ] } is the array
referenced by [ ... ].

This is primarily used as a work-around to interpolate function calls.
Ordinarily, function calls do not interpolate inside doublequoted
strings. That is, you cannot do this:

sub fctn {
return 5;
}
print "Function returns: fctn()\n"; #WRONG - ERROR

Instead, you must do:
print "Function returns: ", fctn(), "\n"; #list context for fctn
or
print "Function returns: " . fctn() . "\n"; #scalar context.

Using this work-around, however, perl will analyize the @{[...]}
construct before it starts looking at the string. By the time it's
done, it sees the construct as an ordinary array - which does indeed
interpolate. You are then allowed to do:

print "Function returns: @{[fctn()]}\n";

Note the caveat that this will always force fctn() to be called in a
list context. Note more importantly that most people would agree this
syntax is far uglier than the standard conventions of either separating
the strings as above, or of assigning the return value of the function
to a variable and then interpolating that variable.

Hope this helps,
Paul Lalli
 
P

Patrick Flaherty

That was an excellent explanation.

Thanx Paul.

pat


Gunnar Hjalmarsson said:
Patrick said:
Started using @{[times]} recently for measuring run (execution)
time. (I'm aware that there's also a Benchmark module).

To figure out what was going on here, I first looked up times in
perlvar - not there. Then thought to try perlfunc. Ah.

So what's the magic, in particular in {[...]}, that converts the
return array into an array-on-the-fly?

I understand that @ refers to arrays and [] also. But what still
has me a little mystified is how, evaluating from in-to-out, when
you go from [ to { and then @, you start at a function and its
return value (an array [or list?]) and end up where you do.

perldoc -q "expand function"

Unfortunately the FAQ doesn't actually answer the question of *how* this
works, just that it does.

Work backwards. Start with the function call. The function will return
a value or list of values, depending in part on context. The [ ] is a
construct to create an anonymous array reference. It therefore imposes
a list context. So the function will return a list of values. (That
list can, of course, contain only one or even zero items). That list of
items is used to populate the anonymous array created by (and referenced
by) the [ ]. So you have an anonymous array reference. Finally, @{ }
is the syntax used to take whatever is enclosed by { } and dereference
that as an array. If, for example, $ref is an array reference, @{$ref}
is the array referenced by $ref.. So @{ [ ... ] } is the array
referenced by [ ... ].

This is primarily used as a work-around to interpolate function calls.
Ordinarily, function calls do not interpolate inside doublequoted
strings. That is, you cannot do this:

sub fctn {
return 5;
}
print "Function returns: fctn()\n"; #WRONG - ERROR

Instead, you must do:
print "Function returns: ", fctn(), "\n"; #list context for fctn
or
print "Function returns: " . fctn() . "\n"; #scalar context.

Using this work-around, however, perl will analyize the @{[...]}
construct before it starts looking at the string. By the time it's
done, it sees the construct as an ordinary array - which does indeed
interpolate. You are then allowed to do:

print "Function returns: @{[fctn()]}\n";

Note the caveat that this will always force fctn() to be called in a
list context. Note more importantly that most people would agree this
syntax is far uglier than the standard conventions of either separating
the strings as above, or of assigning the return value of the function
to a variable and then interpolating that variable.

Hope this helps,
Paul Lalli
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top