Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Deep structure access and temp variable

24 views
Skip to first unread message

Adrien BARREAU

unread,
Jun 13, 2013, 10:55:18 AM6/13/13
to
Hi all.


A simple question, but I have no clue about it:

# Version 1
my $A = $stuff->{a}{b}{c}{d}{e};
my $B = $stuff->{a}{b}{c}{d}{f};
my $C = $stuff->{a}{b}{c}{d}{g};

# Version 2

my $tmp = $stuff->{a}{b}{c}{d};
my $A = $tmp->{e};
my $B = $tmp->{f};
my $C = $tmp->{g};


What is the most efficient?
What appears to be the most idiomatic?


I don't have the knowledge about Perl guts to properly guess here.
Of course, it does not have be only HASHes refs in the structure.


Adrien.

Rainer Weikusat

unread,
Jun 13, 2013, 11:18:11 AM6/13/13
to
Adrien BARREAU <adrien....@live.fr> writes:
> A simple question, but I have no clue about it:
>
> # Version 1
> my $A = $stuff->{a}{b}{c}{d}{e};
> my $B = $stuff->{a}{b}{c}{d}{f};
> my $C = $stuff->{a}{b}{c}{d}{g};
>
> # Version 2
>
> my $tmp = $stuff->{a}{b}{c}{d};
> my $A = $tmp->{e};
> my $B = $tmp->{f};
> my $C = $tmp->{g};
>
>
> What is the most efficient?

This depends on the relative cost of the additional assignment versus
that of the dereferencing chain. I usually follow the rule of thumb
that using an intermediate variable only makes sense if it is going to
be used for at least three times.

But there's a more important concern: Readiblity of the code and the
ease with which it can be modified: Both suffer in case of 'obnoxious
repetition', as in your first example. Also, the intermediate variable
could have a more sensible name than $tmp which could communicate its
nature better the $stuff->{a}{b}{c}{d}.

> What appears to be the most idiomatic?

Is you're asking about "what everyone else does" you can rest assured
that no problem which can be solved with copy'n'paste will be solved
with anything but copy'n'paste because this minimizes that time of
each individual 'trivial work unit' (also, people greatly prefer
moving over thingking).

Ben Morrow

unread,
Jun 13, 2013, 11:55:36 AM6/13/13
to

Quoth Adrien BARREAU <adrien....@live.fr>:
>
> A simple question, but I have no clue about it:
>
> # Version 1
> my $A = $stuff->{a}{b}{c}{d}{e};
> my $B = $stuff->{a}{b}{c}{d}{f};
> my $C = $stuff->{a}{b}{c}{d}{g};
>
> # Version 2
>
> my $tmp = $stuff->{a}{b}{c}{d};
> my $A = $tmp->{e};
> my $B = $tmp->{f};
> my $C = $tmp->{g};
>
> What is the most efficient?

Who cares? (Seriously, unless you've determined that you have a
performance problem and that this bit of code is responsible, it's not
worth compromising readability.)

> What appears to be the most idiomatic?

The second. One of the more important rules of programming is DRY:
'Don't Repeat Yourself'. The first repeats a whole lot of stuff
unnecessarily.

Ben

Jürgen Exner

unread,
Jun 13, 2013, 12:06:20 PM6/13/13
to
Adrien BARREAU <adrien....@live.fr> wrote:
>A simple question, but I have no clue about it:
>
># Version 1
>my $A = $stuff->{a}{b}{c}{d}{e};
>my $B = $stuff->{a}{b}{c}{d}{f};
>my $C = $stuff->{a}{b}{c}{d}{g};
>
># Version 2
>
>my $tmp = $stuff->{a}{b}{c}{d};
>my $A = $tmp->{e};
>my $B = $tmp->{f};
>my $C = $tmp->{g};
>
>What is the most efficient?

Most efficient in regard to what? No, I'm not joking but I really mean
it. I'm guessing you are referring to runtime but that is by no means
the rule-it-all. Actually, if you program is so slow that you have to
optimize on this micro-level, then you should look for a better
algorithm or a different programming language.

Having said that I would guess the runtime depends upon how large $tmp
is. In version 2 you are creating a copy of the data. This can be 'slow'
for large data. If you want a trustworthy answer you will have to
benchmark both versions using your(!) live date.

But that really doesn't matter that much because ....

>What appears to be the most idiomatic?

... much more important than runtime micro-optimization is
maintainability of your code. And assuming that you can find a more
meaningful name than $tmp, then the second version wins hands-down in
that department.
And that kind of efficiency wins in the long run.

jue

Adrien BARREAU

unread,
Jun 13, 2013, 12:10:27 PM6/13/13
to
On 06/13/2013 05:55 PM, Ben Morrow wrote:
>
> Quoth Adrien BARREAU<adrien....@live.fr>:
>>
>> A simple question, but I have no clue about it:
>>
[cut]
>>
>> What is the most efficient?
>
> Who cares? (Seriously, unless you've determined that you have a
> performance problem and that this bit of code is responsible, it's not
> worth compromising readability.)
>

Well, I do. I would not ask if I were not, would I?
I'm working on some piece of code which must run as fast as possible (in
Perl limits), hence the question.
And a bit of curiosity, too.

>> What appears to be the most idiomatic?
>
> The second. One of the more important rules of programming is DRY:
> 'Don't Repeat Yourself'. The first repeats a whole lot of stuff
> unnecessarily.

I agree.
That what I do for now. That was just in case.


Thanks :).


Adrien.

Adrien BARREAU

unread,
Jun 13, 2013, 12:13:46 PM6/13/13
to
On 06/13/2013 05:18 PM, Rainer Weikusat wrote:

>> What is the most efficient?
>
> This depends on the relative cost of the additional assignment versus
> that of the dereferencing chain. I usually follow the rule of thumb
> that using an intermediate variable only makes sense if it is going to
> be used for at least three times.
>
> But there's a more important concern: Readiblity of the code and the
> ease with which it can be modified: Both suffer in case of 'obnoxious
> repetition', as in your first example. Also, the intermediate variable
> could have a more sensible name than $tmp which could communicate its
> nature better the $stuff->{a}{b}{c}{d}.
>
>> What appears to be the most idiomatic?
>
> Is you're asking about "what everyone else does" you can rest assured
> that no problem which can be solved with copy'n'paste will be solved
> with anything but copy'n'paste because this minimizes that time of
> each individual 'trivial work unit' (also, people greatly prefer
> moving over thingking).


ACK.

Thanks :).

Adrien.

Adrien BARREAU

unread,
Jun 13, 2013, 12:14:07 PM6/13/13
to
[cut]

>> What is the most efficient?
>
> Most efficient in regard to what? No, I'm not joking but I really mean
> it. I'm guessing you are referring to runtime but that is by no means
> the rule-it-all. Actually, if you program is so slow that you have to
> optimize on this micro-level, then you should look for a better
> algorithm or a different programming language.
>
> Having said that I would guess the runtime depends upon how large $tmp
> is. In version 2 you are creating a copy of the data. This can be 'slow'
> for large data. If you want a trustworthy answer you will have to
> benchmark both versions using your(!) live date.
>
> But that really doesn't matter that much because ....
>
>> What appears to be the most idiomatic?
>
> ... much more important than runtime micro-optimization is
> maintainability of your code. And assuming that you can find a more
> meaningful name than $tmp, then the second version wins hands-down in
> that department.
> And that kind of efficiency wins in the long run.
>

ACK.

Thanks :).

Adrien.

Jim Gibson

unread,
Jun 13, 2013, 1:09:02 PM6/13/13
to
In article <kpcm7k$ra8$1...@dont-email.me>, Adrien BARREAU
There is no need to guess. Perl has the Benchmark module that makes
doing these kind of comparisons relatively easy:

#!/usr/bin/perl
use warnings;
use strict;
use Benchmark qw(cmpthese);

my $stuff = { a => { b => { c => { d => { e => 1, f => 2, g => 3 }}}}};

cmpthese( 1_000_000, {
'Deep' => sub {
my $x = $stuff->{a}{b}{c}{d}{e};
my $y = $stuff->{a}{b}{c}{d}{f};
my $z = $stuff->{a}{b}{c}{d}{g};
},
'Temp' => sub {
my $tmp = $stuff->{a}{b}{c}{d};
my $x = $tmp->{e};
my $y = $tmp->{f};
my $z = $tmp->{g};
}});
__END__

Results from five runs:

41% perl barreau.pl
Rate Deep Temp
Deep 591716/s -- -63%
Temp 1612903/s 173% --
42% perl barreau.pl
Rate Deep Temp
Deep 621118/s -- -32%
Temp 917431/s 48% --
43% perl barreau.pl
Rate Deep Temp
Deep 854701/s -- -20%
Temp 1063830/s 24% --
44% perl barreau.pl
Rate Deep Temp
Deep 740741/s -- -24%
Temp 970874/s 31% --
45% perl barreau.pl
Rate Deep Temp
Deep 793651/s -- -17%
Temp 961538/s 21% --

That is a lot of variation from run to run, but the Temp approach is
clearly faster, which I would expect. It requires seven hash lookups
instead of fifteen.

As far as "idiomatic", I wouldn't worry about it. One person's
idiomatic is another person's idiotic.

--
Jim Gibson

Jürgen Exner

unread,
Jun 13, 2013, 2:05:31 PM6/13/13
to
Jim Gibson <jimsg...@gmail.com> wrote:
>In article <kpcm7k$ra8$1...@dont-email.me>, Adrien BARREAU
><adrien....@live.fr> wrote:
>
>> A simple question, but I have no clue about it:
>>
>> # Version 1
>> my $A = $stuff->{a}{b}{c}{d}{e};
>> my $B = $stuff->{a}{b}{c}{d}{f};
>> my $C = $stuff->{a}{b}{c}{d}{g};
>>
>> # Version 2
>>
>> my $tmp = $stuff->{a}{b}{c}{d};
>> my $A = $tmp->{e};
>> my $B = $tmp->{f};
>> my $C = $tmp->{g};
>>
>> What is the most efficient?
>> What appears to be the most idiomatic?
>>
>> I don't have the knowledge about Perl guts to properly guess here.
>> Of course, it does not have be only HASHes refs in the structure.
>
>There is no need to guess. Perl has the Benchmark module that makes
>doing these kind of comparisons relatively easy:
>
[...]

A very good example for "Wer mißt mißt Mist" (literal: "who measures,
measures manure").

>That is a lot of variation from run to run, but the Temp approach is
>clearly faster, which I would expect. It requires seven hash lookups
>instead of fifteen.

Completely irrelevant because your sample code is not using the OPs
actual live data or at the very least a representative sample of his
live data.
And depending on the size of $tmp this will make a big difference.

jue

Peter J. Holzer

unread,
Jun 13, 2013, 4:51:44 PM6/13/13
to
On 2013-06-13 16:06, Jürgen Exner <jurg...@hotmail.com> wrote:
> Adrien BARREAU <adrien....@live.fr> wrote:
>>A simple question, but I have no clue about it:
>>
>># Version 1
>>my $A = $stuff->{a}{b}{c}{d}{e};
>>my $B = $stuff->{a}{b}{c}{d}{f};
>>my $C = $stuff->{a}{b}{c}{d}{g};
>>
>># Version 2
>>
>>my $tmp = $stuff->{a}{b}{c}{d};
>>my $A = $tmp->{e};
>>my $B = $tmp->{f};
>>my $C = $tmp->{g};
>>
>>What is the most efficient?
>
> Most efficient in regard to what? No, I'm not joking but I really mean
> it. I'm guessing you are referring to runtime but that is by no means
> the rule-it-all. Actually, if you program is so slow that you have to
> optimize on this micro-level, then you should look for a better
> algorithm or a different programming language.

Agreed (mostly).


> Having said that I would guess the runtime depends upon how large $tmp
> is. In version 2 you are creating a copy of the data.

$tmp is reference, so it's always the same size.

hp


--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | Sysadmin WSR | Man feilt solange an seinen Text um, bis
| | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel

Ivan Shmakov

unread,
Jun 13, 2013, 5:04:05 PM6/13/13
to
>>>>> Adrien BARREAU <adrien....@live.fr> writes:

[...]

> # Version 2

> my $tmp = $stuff->{a}{b}{c}{d};
> my $A = $tmp->{e};
> my $B = $tmp->{f};
> my $C = $tmp->{g};

> What is the most efficient? What appears to be the most idiomatic?

FWIW (and now that the experts have said their word), my
personal preference would be to write it as follows:

my $tmp = $stuff->{a}{b}{c}{d};
my ($A, $B, $C) = @$tmp{qw (e f g)};

[...]

--
FSF associate member #7257

Ben Morrow

unread,
Jun 13, 2013, 5:40:19 PM6/13/13
to

Quoth Jürgen Exner <jurg...@hotmail.com>:
> Adrien BARREAU <adrien....@live.fr> wrote:
> >
> >my $tmp = $stuff->{a}{b}{c}{d};
> >my $A = $tmp->{e};
> >my $B = $tmp->{f};
> >my $C = $tmp->{g};
> >
> >What is the most efficient?
[...]
>
> Having said that I would guess the runtime depends upon how large $tmp
> is.

$tmp is a reference, so it's as small as a Perl value can be (SV
overhead plus one 4- or 8-byte pointer).

Ben

Jürgen Exner

unread,
Jun 13, 2013, 5:58:13 PM6/13/13
to
Ben Morrow <b...@morrow.me.uk> wrote:
>
>Quoth J?Exner <jurg...@hotmail.com>:
Ahmm, well, aehhh, it goes against all my intuition, but you are right.
A reference by any other name is still a humble reference, even if the
referenced item is a gigantic data set.

I stand corrected.

jue

Tim McDaniel

unread,
Jun 13, 2013, 8:11:57 PM6/13/13
to
In article <87y5adg...@violet.siamics.net>,
Ivan Shmakov <onei...@gmail.com> wrote:
> FWIW (and now that the experts have said their word), my
> personal preference would be to write it as follows:
>
>my $tmp = $stuff->{a}{b}{c}{d};
>my ($A, $B, $C) = @$tmp{qw (e f g)};

I had to write a test program and check "man perlref" to make sure it
parses OK. (I had been expecting $tmp{...} to be interpreted as a
hashref before @ was applied.) I would have written, and still
prefer, what I think is clearer:

my ($A, $B, $C) = @{$tmp}{qw (e f g)};

Pity that it does not permit $tmp->{qw (e f g)}, but man perlref says
that -> is for single-element access only.

--
Tim McDaniel, tm...@panix.com

Charles DeRykus

unread,
Jun 14, 2013, 2:05:20 AM6/14/13
to
On 6/13/2013 5:11 PM, Tim McDaniel wrote:
> In article <87y5adg...@violet.siamics.net>,
> Ivan Shmakov <onei...@gmail.com> wrote:
>> FWIW (and now that the experts have said their word), my
>> personal preference would be to write it as follows:
>>
>> my $tmp = $stuff->{a}{b}{c}{d};
>> my ($A, $B, $C) = @$tmp{qw (e f g)};
>
> I had to write a test program and check "man perlref" to make sure it
> parses OK. (I had been expecting $tmp{...} to be interpreted as a
> hashref before @ was applied.) I would have written, and still
> prefer, what I think is clearer:
>
> my ($A, $B, $C) = @{$tmp}{qw (e f g)};

I suspect most would agree. And {} would be required anyway if the hash
ref is anything but a simple scalar.

A nice reference cheat sheet by Tye McQueen:
http://www.perlmonks.org/?node=References%20quick%20reference

>
> Pity that it does not permit $tmp->{qw (e f g)}, but man perlref says
> that -> is for single-element access only.
>

Lots agree including the cheat sheet author.


--
Charles DeRykus

Dr.Ruud

unread,
Jun 14, 2013, 3:20:33 AM6/14/13
to
On 14/06/2013 02:11, Tim McDaniel wrote:
> Ivan Shmakov <onei...@gmail.com> wrote:

>> my ($A, $B, $C) = @$tmp{qw (e f g)};
>
> [..] I would have written, and still
> prefer, what I think is clearer:
>
> my ($A, $B, $C) = @{$tmp}{qw (e f g)};

Many styles possible. I like to write it as:

@{ $tmp }{qw/ e f g /};

One space before the first item and after the last, 2 spaces in between.

With qw, I often use the slash as separator, but () as well:

use POSIX qw(
nice
strftime
);

(and the imports in alphabetical order please :)

--
Ruud

Rainer Weikusat

unread,
Jun 14, 2013, 6:42:41 AM6/14/13
to
Charles DeRykus <der...@gmail.com> writes:
> On 6/13/2013 5:11 PM, Tim McDaniel wrote:
>> In article <87y5adg...@violet.siamics.net>,
>> Ivan Shmakov <onei...@gmail.com> wrote:
>>> FWIW (and now that the experts have said their word), my
>>> personal preference would be to write it as follows:
>>>
>>> my $tmp = $stuff->{a}{b}{c}{d};
>>> my ($A, $B, $C) = @$tmp{qw (e f g)};
>>
>> I had to write a test program and check "man perlref" to make sure it
>> parses OK. (I had been expecting $tmp{...} to be interpreted as a
>> hashref before @ was applied.) I would have written, and still
>> prefer, what I think is clearer:
>>
>> my ($A, $B, $C) = @{$tmp}{qw (e f g)};
>
> I suspect most would agree. And {} would be required anyway if the
> hash ref is anything but a simple scalar.
>
> A nice reference cheat sheet by Tye McQueen:
> http://www.perlmonks.org/?node=References%20quick%20reference

This is incomplete. It doesn't mention code references,

perl -e '$s = sub { print("What about me?\n") }; $s->();'

doesn't mention an important special-case about glob references/ <>,

perl -e 'my $fh; open($fh, "<", "/etc/services"); print <$fh>, "\n";'

versus

perl -e 'my $fh; open($fh, "<", "/etc/services"); print <{$fh}>, "\n";'

and the

If the reference is in a hash or an array (and you are getting
back a scalar), then you can drop the -> between the adjacent
[0] and/or {KEY} parts:

is inaccurate: Everything stored in a 'Perl container object' is a
scalar.


Tim McDaniel

unread,
Jun 14, 2013, 10:29:38 AM6/14/13
to
In article <8738sld...@sapphire.mobileactivedefense.com>,
Rainer Weikusat <rwei...@mssgmbh.com> wrote:
>doesn't mention an important special-case about glob references/ <>,
>
>perl -e 'my $fh; open($fh, "<", "/etc/services"); print <$fh>, "\n";'
>
>versus
>
>perl -e 'my $fh; open($fh, "<", "/etc/services"); print <{$fh}>, "\n";'

Or print <${fh}>

It would have been a kindness to explain the problem for those of us
who were unfamiliar with it. It took me a little while to find the
explanation.

"man perlop", towards the end of the I/O Operators section (in the
Perl version I checked):

If what the angle brackets contain is a simple scalar variable
(e.g., <$foo>), then that variable contains the name of the
filehandle to input from, or its typeglob, or a reference to
the same. For example:

$fh = \*STDIN;
$line = <$fh>;

If what's within the angle brackets is neither a filehandle nor
a simple scalar variable containing a filehandle name,
typeglob, or typeglob reference, it is interpreted as a
filename pattern to be globbed, and either a list of filenames
or the next filename in the list is returned, depending on
context. This distinction is determined on syntactic grounds
alone. That means "<$x>" is always a readline() from an
indirect handle, but "<$hash{key}>" is always a glob(). That's
because $x is a simple scalar variable, but $hash{key} is
not--it's a hash element. Even "<$x >" (note the extra space)
is treated as "glob("$x ")", not "readline($x)".

One level of double-quote interpretation is done first, but you
can't say "<$foo>" because that's an indirect filehandle as
explained in the previous paragraph. (In older versions of
Perl, programmers would insert curly brackets to force
interpretation as a filename glob: "<${foo}>". These days,
it's considered cleaner to call the internal function directly
as "glob($foo)", which is probably the right way to have done
it in the first place.)

So on this system,
>perl -e 'my $fh; open($fh, "<", "/etc/services"); print <$fh>, "\n";'
outputs the contents of the file /etc/services, but

>perl -e 'my $fh; open($fh, "<", "/etc/services"); print <{$fh}>, "\n";'
outputs one line,
GLOB(0xbb5061d0)

I didn't know that. Thank you.

--
Tim McDaniel, tm...@panix.com

Rainer Weikusat

unread,
Jun 14, 2013, 10:42:21 AM6/14/13
to
tm...@panix.com (Tim McDaniel) writes:
> In article <8738sld...@sapphire.mobileactivedefense.com>,
> Rainer Weikusat <rwei...@mssgmbh.com> wrote:
>>doesn't mention an important special-case about glob references/ <>,
>>
>>perl -e 'my $fh; open($fh, "<", "/etc/services"); print <$fh>, "\n";'
>>
>>versus
>>
>>perl -e 'my $fh; open($fh, "<", "/etc/services"); print <{$fh}>, "\n";'
>
> Or print <${fh}>
>
> It would have been a kindness to explain the problem for those of us
> who were unfamiliar with it.

https://groups.google.com/forum/?hl=en-GB&fromgroups#!original/comp.lang.perl.misc/NcPfYj-gvi8/dSG-ORBMJ-wJ

?

Charles DeRykus

unread,
Jun 14, 2013, 11:59:37 AM6/14/13
to
On 6/14/2013 3:42 AM, Rainer Weikusat wrote:
> Charles DeRykus <der...@gmail.com> writes:
>> On 6/13/2013 5:11 PM, Tim McDaniel wrote:
>>> In article <87y5adg...@violet.siamics.net>,
>>> Ivan Shmakov <onei...@gmail.com> wrote:
>>>> FWIW (and now that the experts have said their word), my
>>>> personal preference would be to write it as follows:
>>>>
>>>> my $tmp = $stuff->{a}{b}{c}{d};
>>>> my ($A, $B, $C) = @$tmp{qw (e f g)};
>>>
>>> I had to write a test program and check "man perlref" to make sure it
>>> parses OK. (I had been expecting $tmp{...} to be interpreted as a
>>> hashref before @ was applied.) I would have written, and still
>>> prefer, what I think is clearer:
>>>
>>> my ($A, $B, $C) = @{$tmp}{qw (e f g)};
>>
>> I suspect most would agree. And {} would be required anyway if the
>> hash ref is anything but a simple scalar.
>>
>> A nice reference cheat sheet by Tye McQueen:
>> http://www.perlmonks.org/?node=References%20quick%20reference
>
> This is incomplete. It doesn't mention code references,
>
> perl -e '$s = sub { print("What about me?\n") }; $s->();'
>
> doesn't mention an important special-case about glob references/ <>,
>
> perl -e 'my $fh; open($fh, "<", "/etc/services"); print <$fh>, "\n";'
>
> versus
>
> perl -e 'my $fh; open($fh, "<", "/etc/services"); print <{$fh}>, "\n";'


The author reminds a commenter that the scope was 4 simple rules to
dereference "data structure references". He also clarifies:

I also didn't talk about creating references, symbolic references,
blessed references, closures, ref, UNIVERSAL::isa(), references to
globs, to the IO chunks of globs, to compiled regular expressions, nor
to any other types of things that Perl lets you have a reference to.


>
> and the
>
> If the reference is in a hash or an array (and you are getting
> back a scalar), then you can drop the -> between the adjacent
> [0] and/or {KEY} parts:
>
> is inaccurate: Everything stored in a 'Perl container object' is a
> scalar.
>
>

Yeah, I don't get the "getting back a scalar" part.

An example of the shortcut:

perl -e '@a=(["a","b"]);$r=\@a;print $r->[0][1]' ## vs. $r->[0]->[1]


But, it'd work in other cases too:

perl -le '@a=(["a",{b=>"c",d=>"e"}]);$r=\@a;
print $r->[0][1]{d}'

--
Charles DeRykus





Rainer Weikusat

unread,
Jun 14, 2013, 12:50:05 PM6/14/13
to
Charles DeRykus <der...@gmail.com> writes:
> perlref" to make sure it
>>>> parses OK. (I had been expecting $tmp{...} to be interpreted as a
>>>> hashref before @ was applied.) I would have written, and still
>>>> prefer, what I think is clearer:
>>>>
>>>> my ($A, $B, $C) = @{$tmp}{qw (e f g)};
>>>
>>> I suspect most would agree. And {} would be required anyway if the
>>> hash ref is anything but a simple scalar.
>>>
>>> A nice reference cheat sheet by Tye McQueen:
>>> http://www.perlmonks.org/?node=References%20quick%20reference
>>
>> This is incomplete. It doesn't mention code references,
>>
>> perl -e '$s = sub { print("What about me?\n") }; $s->();'
>>
>> doesn't mention an important special-case about glob references/ <>,
>>
>> perl -e 'my $fh; open($fh, "<", "/etc/services"); print <$fh>, "\n";'
>>
>> versus
>>
>> perl -e 'my $fh; open($fh, "<", "/etc/services"); print <{$fh}>, "\n";'
>
>
> The author reminds a commenter that

... all perceived shortcomings in his text are really intentional
omissions, at least in hindsight, lest he would have to admit that he
made some mistakes.

Rainer Weikusat

unread,
Jun 14, 2013, 3:33:37 PM6/14/13
to
In case this seems overly cryptic: Perl doesn't have 'data structures'
it has various kinds of objects and references to objects. This means
unless the author provides a definition of 'data structures' in the
context of Perl, a reader has to guess what was meant by that and
guessing that it was supposed to mean 'objects' isn't very far
fetched.

Leaving this aside, this 'cheat sheet' is a partially erroneous
paraphrase of the 'Using references' section of the perlref manpage:

1. Anywhere you'd put an identifier (or chain of identifiers)
as part of a variable or subroutine name, you can replace
the identifier with a simple scalar variable containing a
reference of the correct type:

[...]


2. Anywhere you'd put an identifier (or chain of identifiers)
as part of a variable or subroutine name, you can replace
the identifier with a BLOCK returning a reference of the
correct type.

[...]

3. Subroutine calls and lookups of individual array elements
arise often enough that it gets cumbersome to use
method 2. As a form of syntactic sugar, the examples
for method 2 may be written:

$arrayref->[0] = "January"; # Array element

[...]

The arrow is optional between brackets subscripts

This is not only complete and correct but also (IMHO) no more
difficult to understand than the other text.

Charles DeRykus

unread,
Jun 14, 2013, 4:21:43 PM6/14/13
to
Tye's cheat sheet dates from 2001 and still provides a short, useful
guide. He carefully qualified its scope. You could comment/critique
Tye's page fully on that forum and/or publish your own as as updated,
improved version.

--
Charles DeRykus









Ben Morrow

unread,
Jun 14, 2013, 4:51:37 PM6/14/13
to

Quoth Rainer Weikusat <rwei...@mssgmbh.com>:
> Rainer Weikusat <rwei...@mssgmbh.com> writes:
> > Charles DeRykus <der...@gmail.com> writes:
> >> [Rainer wrote:]
> >>> [Charles (IIRC?) wrote:]
> >>>>
> >>>> A nice reference cheat sheet by Tye McQueen:
> >>>> http://www.perlmonks.org/?node=References%20quick%20reference
> >>>
> >>> This is incomplete. It doesn't mention code references,
> >>
> >> The author reminds a commenter that
> >
> > ... all perceived shortcomings in his text are really intentional
> > omissions, at least in hindsight, lest he would have to admit that he
> > made some mistakes.
>
> In case this seems overly cryptic: Perl doesn't have 'data structures'
> it has various kinds of objects and references to objects. This means
> unless the author provides a definition of 'data structures' in the
> context of Perl, a reader has to guess what was meant by that and
> guessing that it was supposed to mean 'objects' isn't very far
> fetched.

Do you ever get tired of being snide, pedantic and somewhat unpleasant?

Perl has data structures. They are the things described in perldsc, the
Perl Data Structures Cookbook. Perl also has objects, which are
something rather different, and are not covered in Tye's tutorial.

Ben

Rainer Weikusat

unread,
Jun 14, 2013, 5:11:58 PM6/14/13
to
"Tye's tutorial" is a bad rehash of a perl man page. Did it already
occur to you that you're implicitly trashing the guy who wrote the
more useful text?

Rainer Weikusat

unread,
Jun 14, 2013, 5:16:52 PM6/14/13
to
Ben Morrow <b...@morrow.me.uk> writes:
> Quoth Rainer Weikusat <rwei...@mssgmbh.com>:
>> Rainer Weikusat <rwei...@mssgmbh.com> writes:
>> > Charles DeRykus <der...@gmail.com> writes:
>> >> [Rainer wrote:]
>> >>> [Charles (IIRC?) wrote:]
>> >>>>
>> >>>> A nice reference cheat sheet by Tye McQueen:
>> >>>> http://www.perlmonks.org/?node=References%20quick%20reference
>> >>>
>> >>> This is incomplete. It doesn't mention code references,
>> >>
>> >> The author reminds a commenter that
>> >
>> > ... all perceived shortcomings in his text are really intentional
>> > omissions, at least in hindsight, lest he would have to admit that he
>> > made some mistakes.
>>
>> In case this seems overly cryptic: Perl doesn't have 'data structures'
>> it has various kinds of objects and references to objects. This means
>> unless the author provides a definition of 'data structures' in the
>> context of Perl, a reader has to guess what was meant by that and
>> guessing that it was supposed to mean 'objects' isn't very far
>> fetched.
>
> Do you ever get tired of being snide, pedantic and somewhat
> unpleasant?

To answer that question: One reason why I'm on USENET is because I'm
interested in discussing things. Unfortunately, many USENET
'discussions' don't really qualify for that but people who are more
into throwing bottles at others in order to express their discontent
with them (something which happened to me yesterday evening) at least
can't really do that.

Jürgen Exner

unread,
Jun 14, 2013, 8:25:32 PM6/14/13
to
Ben Morrow <b...@morrow.me.uk> wrote:
>Quoth Rainer Weikusat <rwei...@mssgmbh.com>:
>> In case this seems overly cryptic: Perl doesn't have 'data structures'

Of course Perl has data structures. Support for the abstract data
structures 'list' and 'mapping' are built into the very core of the
language.

>Do you ever get tired of being snide, pedantic and somewhat unpleasant?

That's what filters are for.

jue

Rainer Weikusat

unread,
Jun 15, 2013, 10:04:06 AM6/15/13
to
Ben Morrow <b...@morrow.me.uk> writes:
> Quoth Rainer Weikusat <rwei...@mssgmbh.com>:

[...]

>> Perl doesn't have 'data structures' it has various kinds of objects
>> and references to objects.

[...]

> Perl has data structures. They are the things described in perldsc, the
> Perl Data Structures Cookbook. Perl also has objects, which are
> something rather different, and are not covered in Tye's tutorial.

This will probably earn me the 'pedantic' accusation again but so be
it: I was using 'object' in the sense it is used in the C standard,
for want of a better term for that: It's meaning is roughly "some
typed thing which can be allocated, deallocated and deal with directly
by code written in $language". The term 'first class citizen' is also
used to refer to that. In Perl, a behavioural definition of 'object'
in this sense could be "something the \-operator can be applied to [if
it isn't anonymous]", ie, scalar, arrays, hashes, subroutines, globs
and a few more, less common somethings. Another definition could be
'something which is either a glob can be "stored" in a glob slot'.#

In hindsight, I understand that the author of this 'cheat sheet'
intended to partition the set of perl objects into 'proper' and
'fishy' ones, presumably based on experiences with
$other_programming_language, however, that wasn't obvious to me when
reading the text and I also disagree with this partitioning. I use
anonymous subroutines, mostly closures, very frequently, and I also
write code which generates code at runtime frequently. Perl support
for the latter is fairly poor because it requires generating source
code text and running that through the compiler via eval but
nevertheless existant and useful: subroutines are almost 'first class
citizens' in Perl.

I've been doing an unholy amount of Java programming recently and some
things which are very simple in Perl, eg, write a general
'structured thing' comparison routine, are hideously complicated in
Java because its support for treating 'functions' as 'objects' is even
poorer than that of C (I have such a routine with a limited scope and
the code necessary to invoke that is only about 50% less than the
comparison code itself): Perl is a nice language because of its more
uncommon (in 'mainstream programming languages') features, not a nice
language despite of them because it enables people to build
punctuation cascades capable of reducing grown men to tears and
routinely outclevering everyone (including themselves) in the
process.

Willem

unread,
Jun 17, 2013, 12:53:55 PM6/17/13
to
Ivan Shmakov wrote:
)>>>>> Adrien BARREAU <adrien....@live.fr> writes:
)
) [...]
)
) > # Version 2
)
) > my $tmp = $stuff->{a}{b}{c}{d};
) > my $A = $tmp->{e};
) > my $B = $tmp->{f};
) > my $C = $tmp->{g};
)
) > What is the most efficient? What appears to be the most idiomatic?
)
) FWIW (and now that the experts have said their word), my
) personal preference would be to write it as follows:
)
) my $tmp = $stuff->{a}{b}{c}{d};
) my ($A, $B, $C) = @$tmp{qw (e f g)};

Writing it that way obviates the need for a temporary variable,
so why don't you write this:

my ($A, $B, $C) = @{$stuff->{a}{b}{c}{d}}{qw(e f g)};


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
0 new messages