[32353] in Perl-Users-Digest
Perl-Users Digest, Issue: 3620 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Feb 23 14:09:26 2012
Date: Thu, 23 Feb 2012 11:09:08 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Thu, 23 Feb 2012 Volume: 11 Number: 3620
Today's topics:
Re: a question about efficiency (Greg Bacon)
Re: a question about efficiency <kiuhnm03.4t.yahoo.it>
Re: a question about efficiency (Greg Bacon)
Re: a question about efficiency <kiuhnm03.4t.yahoo.it>
Re: a question about efficiency (Tim McDaniel)
Re: a question about efficiency <ben@morrow.me.uk>
Re: a question about efficiency <ben@morrow.me.uk>
Re: a question about efficiency (Tim McDaniel)
Re: a question about efficiency <ben@morrow.me.uk>
Re: a question about efficiency <tzz@lifelogs.com>
Re: Can't connect to 'localhost' in IO::Socket <mvdwege@mail.com>
Constructing a value beforehand <bhdistortion@gmail.com>
Re: Constructing a value beforehand <rweikusat@mssgmbh.com>
Re: Constructing a value beforehand (Tim McDaniel)
Re: Constructing a value beforehand (Tim McDaniel)
Re: Constructing a value beforehand <rweikusat@mssgmbh.com>
Re: Constructing a value beforehand <ben@morrow.me.uk>
Re: Constructing a value beforehand <rweikusat@mssgmbh.com>
Re: Constructing a value beforehand <ben@morrow.me.uk>
size of an array via a ref to it <dn.perl@gmail.com>
Re: size of an array via a ref to it <markus.hutmacher@googlemail.com>
Re: size of an array via a ref to it <ben@morrow.me.uk>
Re: size of an array via a ref to it <jwkrahn@example.com>
tree to array of arrays <nospam.gravitalsun.antispam@hotmail.com.nospam>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Wed, 22 Feb 2012 16:08:35 -0600
From: gbacon@hiwaay.net (Greg Bacon)
Subject: Re: a question about efficiency
Message-Id: <sK2dnRhAhdj--tjSnZ2dnUVZ_u-dnZ2d@posted.hiwaay2>
Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
: This is, of course, completely wrong :-), because there's always 'an
: enclosing block' in perl, with 'the current compilation unit' (aka
: 'file') being the outermost one.
Yes, there's always an outer scope, but that's relevant only when
the sub needs to close over outer lexicals. See the implementation
of Perl_cv_clone in pad.c.
Greg
--
...we need an amendment that requires every Congressman and Senator to
certify in writing that he has read a bill in its entirety before he
can vote on it. The same must be required for the President before he
can sign a bill into law. -- Harry Browne
------------------------------
Date: Wed, 22 Feb 2012 23:27:55 +0100
From: Kiuhnm <kiuhnm03.4t.yahoo.it>
Subject: Re: a question about efficiency
Message-Id: <4f456beb$0$1378$4fafbaef@reader2.news.tin.it>
On 2/22/2012 0:49, Ben Morrow wrote:
> I didn't, actually :). I have no formal training in computer science,
> just what I've picked up here and there. At any rate, I do know that
> perl internally considers anonymous subs which do in fact close over
> outer variables to be different from those which don't; in particular,
> a sub {} which doesn't close over anything will return a ref to the same
> sub every time, whereas one which doesn't won't. So:
>
> ~% perl -E'say for map { sub { 1 } } 1..2'
> CODE(0x821928)
> CODE(0x821928)
> ~% perl -E'say for map { my $x; sub { $x } } 1..2'
> CODE(0x803aa8)
> CODE(0x8196c8)
> ~%
>
> (and there are a couple more Perl idioms for you :) ).
Good example, thanks.
Just a question. When I run the following code I get different values:
my $x; # global variable
say for map { sub { $x } } 1..10000;
It seems that Perl uses closures even when there's no real need for
them. Or am I missing something?
Kiuhnm
------------------------------
Date: Wed, 22 Feb 2012 16:40:40 -0600
From: gbacon@hiwaay.net (Greg Bacon)
Subject: Re: a question about efficiency
Message-Id: <LO6dndiRk6h189jSnZ2dnUVZ_h-dnZ2d@posted.hiwaay2>
Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
: [...] Consequently, what is or isn't a closure would be something
: of interest to the implementation and for users, its just
: functions/ subroutines who also observe the rules of lexical
: scoping if there are such rules to observe.
That is an important distinction for users who want to understand
how a program works, e.g., whether calls through a given ref
are idempotent, whether results depend on @_ parameters only,
whether state lingers in secret hidey-holes, whether closures
communicate via an inaccessible medium, etc.
Yes, it's only a matter of adhering to the rules of lexical scoping,
but those rules add significant expressive power and thus more to
consider while reasoning about programs.
Greg
--
Democracy is the theory that the common people know what they want, and
deserve to get it good and hard.
-- H.L. Mencken
------------------------------
Date: Wed, 22 Feb 2012 23:47:54 +0100
From: Kiuhnm <kiuhnm03.4t.yahoo.it>
Subject: Re: a question about efficiency
Message-Id: <4f45709a$0$1380$4fafbaef@reader2.news.tin.it>
On 2/22/2012 20:53, Tim McDaniel wrote:
> In article<4f454435$0$1382$4fafbaef@reader1.news.tin.it>,
> Kiuhnm<kiuhnm03.4t.yahoo.it> wrote:
>> I'm just a little surprised that I need braces to enclose single
>> statements.
>
> There are reasons. It's easy to forget curly braces and not realize
> that the indentation and control flow are not as you expected:
>
> if (-x "$path/$basename")
> $name = "$path/$basename";
> last;
>
> or the "dangling else" problem:
>
> if (this)
> if (that)
> stuff;
> else
> other_stuff;
>
> (Note that in neither case does the indentation match the control
> flow, and neither is valid Perl without adding curly braces.)
I've been programming in C++ for many years and those mistakes are very
uncommon. Moreover, if you use a good editor or, better, a good IDE,
they're virtually impossible.
And even if they were common, isn't Perl the language where
say 1+2+3;
say (1+2)+3
print two different things?
I thought Perl was a language where omitting a few characters was worth
the risk of shooting oneself in the foot.
Kiuhnm
------------------------------
Date: Wed, 22 Feb 2012 23:25:58 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: a question about efficiency
Message-Id: <ji3ti5$a0j$1@reader1.panix.com>
In article <4f45709a$0$1380$4fafbaef@reader2.news.tin.it>,
Kiuhnm <kiuhnm03.4t.yahoo.it> wrote:
>I thought Perl was a language where omitting a few characters was
>worth the risk of shooting oneself in the foot.
If that were so, there would be no "use strict" and few variable
declarations. I'd say more that, in general, Perl was designed (if I
can use the word that loosely) to have defaults that Larry Wall (et
al) considered reasonable for the particular case at hand. Functions
without parentheses and behavior in scalar versus list contexts are
illustrative: "In general, they do what you want, unless you want
consistency."
So I assume Larry thought it better to not have a default for compound
statements like if, for, and such. But he didn't see a problem with
omitting curly braces with statement modifiers, or in map or grep.
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Thu, 23 Feb 2012 01:08:52 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: a question about efficiency
Message-Id: <46gg19-lit.ln1@anubis.morrow.me.uk>
Quoth Kiuhnm <kiuhnm03.4t.yahoo.it>:
> On 2/22/2012 0:49, Ben Morrow wrote:
> >
> > ~% perl -E'say for map { sub { 1 } } 1..2'
> > CODE(0x821928)
> > CODE(0x821928)
> > ~% perl -E'say for map { my $x; sub { $x } } 1..2'
> > CODE(0x803aa8)
> > CODE(0x8196c8)
> > ~%
>
> Just a question. When I run the following code I get different values:
> my $x; # global variable
This isn't a true global, of course, but a file-scoped lexical. True
package globals (declared with 'our' or 'use vars') are never closed
over, since they are directly accessible from everywhere.
> say for map { sub { $x } } 1..10000;
> It seems that Perl uses closures even when there's no real need for
> them. Or am I missing something?
No, you're not. For efficiency reasons, perl doesn't entirely
distinguish between this case
my $x;
for (1..2) {
sub { $x }
}
and this case
for (1..2) {
my $x;
sub { $x }
}
so it has to create a full closure in both cases. In principle it could
work out that in the first case $x is in a section of code that will
only run once, and treat it as a global, but that information isn't
available at the point where it decides which form of anon sub it needs.
(Incidentally, this issue came up here just the other day in the context
of 'variable will not stay shared' warnings, which are of course very
closely related. In that situation perl treats the second case as though
it were the first, rather than the other way around.)
Ben
------------------------------
Date: Thu, 23 Feb 2012 01:56:19 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: a question about efficiency
Message-Id: <3vig19-6ku.ln1@anubis.morrow.me.uk>
Quoth tmcd@panix.com:
> In article <4f45709a$0$1380$4fafbaef@reader2.news.tin.it>,
> Kiuhnm <kiuhnm03.4t.yahoo.it> wrote:
> >I thought Perl was a language where omitting a few characters was
> >worth the risk of shooting oneself in the foot.
>
> If that were so, there would be no "use strict" and few variable
> declarations.
There weren't, in the beginning. That's why 'uninitialised value' and
'variable used only once' warnings were so important: in Perl 4 they
were your only hope of spotting you'd misspelled a variable name. You
will notice, if you look, that there are still a number of modules
distributed with the perl core that don't run under strictures
(Exporter, Carp, and Getopt::Std, for instance).
As time goes on, perl is becoming more strict. This is, in general a
Good Thing.
> I'd say more that, in general, Perl was designed (if I
> can use the word that loosely)
No need to use it loosely. Perl was designed rather carefully, though
not always in a way likely to appeal to language purists. There are a
great many ways of changing Perl which, while they seem sensible on the
surface, actually end up causing huge problems because they go against
the grain of the language (*cough*SvUTF8). For instance, quite a lot of
languages have taken up Perl's regex operators; none of them make them
as easy to use as Perl, despite the initial apparent weirdness of (say)
the =~ operator.
> to have defaults that Larry Wall (et
> al) considered reasonable for the particular case at hand. Functions
> without parentheses and behavior in scalar versus list contexts are
> illustrative: "In general, they do what you want, unless you want
> consistency."
The specific example given ('say (1+2)+3' vs say 1+2+3) was IMHO a
mistake (I have *finally* trained myself to usually add the appropriate
unary + without thinking...), though I'm not entirely sure what the Right
Answer would have been.
One of the problems here is that Perl's grammar is *extremely*
ambiguous. (If you want to give yourself nightmares, go take a look at
the code in toke.c for parsing quoted strings. In particular, the bit
which decides whether a [] is a subscript or a character class...)
> So I assume Larry thought it better to not have a default for compound
> statements like if, for, and such. But he didn't see a problem with
> omitting curly braces with statement modifiers, or in map or grep.
Well, there isn't any need. A braceless 'if' is simply spelled 'and'.
(Before Perl 5 it was spelled '&&', and you had to use more parens.)
(They're even implemented the same: 'if (A) { B }' is compiled, after
optimisation, to exactly the same code as 'A and do { B };', though of
course the lexical scoping is slightly different.)
Ben
------------------------------
Date: Thu, 23 Feb 2012 06:26:08 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: a question about efficiency
Message-Id: <ji4m60$d1p$1@reader1.panix.com>
In article <3vig19-6ku.ln1@anubis.morrow.me.uk>,
Ben Morrow <ben@morrow.me.uk> wrote:
>
>Quoth tmcd@panix.com:
>> I'd say more that, in general, Perl was designed (if I
>> can use the word that loosely)
>
>No need to use it loosely. Perl was designed rather carefully,
The prosecutor could introduce package'name as exhibit A and rest.
$[
$]
pseudo-hash
and lots of other things in
http://www.modernperlbooks.com/mt/2009/07/deprecated-pointy-bits.html
that were ill-considered at the time (not just in retrospect).
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Thu, 23 Feb 2012 11:32:13 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: a question about efficiency
Message-Id: <tmkh19-l091.ln1@anubis.morrow.me.uk>
Quoth tmcd@panix.com:
> In article <3vig19-6ku.ln1@anubis.morrow.me.uk>,
> Ben Morrow <ben@morrow.me.uk> wrote:
> >Quoth tmcd@panix.com:
> >> I'd say more that, in general, Perl was designed (if I
> >> can use the word that loosely)
> >
> >No need to use it loosely. Perl was designed rather carefully,
>
> The prosecutor could introduce package'name as exhibit A and rest.
package'name was introduced, like so much else in Perl, to be compatible
with an existing language (in this case Ada, which was important at the
time). I don't believe it's actually the least bit ambiguous within the
Perl grammar: it only causes problems for extremely-simple-minded syntax
highlighters, which, again, probably didn't exist at the time.
> $[
This was another get-people-to-switch feature, this time for awk and
Fortran users. Yes, it's an extremely bad fit for Perl 5, but it wasn't
introduced into Perl 5, it was introduced into Perl 1. I don't think
Perl 1 even had 'require' (or 'do FILE'), so problems with global
settings didn't really apply.
> $]
What's wrong with that? (If you wanted to bring up $^V and vstrings and
version.pm I wouldn't disagree, but those are 5.{6,10}-isms rather than
original features.)
> pseudo-hash
Phash was (I believe) a 5005 feature, so, again, relatively recent and
not designed with enough of an eye on the language as a whole.
Ben
------------------------------
Date: Thu, 23 Feb 2012 11:33:08 -0500
From: Ted Zlatanov <tzz@lifelogs.com>
Subject: Re: a question about efficiency
Message-Id: <87zkc933y3.fsf@lifelogs.com>
On Wed, 22 Feb 2012 20:51:56 +0100 Kiuhnm <kiuhnm03.4t.yahoo.it> wrote:
K> Thanks for the tip. My idea was to read
K> Learning Perl,
K> Intermediate Perl and
K> Mastering Perl,
K> but I'll have a look at PP. It seems that the latest edition covers
K> Perl 5.14 as well.
I'd put the Perl Cookbook either second or third on that list. It's a
very valuable compendium of common problems with good solutions.
Also Unix Power Tools, if you have interest in Unix, is a very good book
to add to this list. Perl grew and exists in a Unix ecosystem (Windows
ports notwithstanding) so learning about the tools and facilities in
that ecosystem is very useful.
Ted
------------------------------
Date: Thu, 23 Feb 2012 08:05:56 +0100
From: Mart van de Wege <mvdwege@mail.com>
Subject: Re: Can't connect to 'localhost' in IO::Socket
Message-Id: <8639a2f2qz.fsf@gaheris.avalon.lan>
Martijn Lievaart <m@rtij.nl.invlalid> writes:
> On Wed, 22 Feb 2012 17:04:03 +0100, Mart van de Wege wrote:
>
>> On what interface will a host answer ARP queries?
>
> Most OSses, all interfaces, for all IP addresses.
>
So, for the *outside* world, it can be assumed to be on all interfaces.
For the server administrator and a programmer, it requires an interface,
even a virtual one, to even set up an IP address.
>> That's the interface the IP is bound to. In general deployments, more is
>
> No, it's not.
>
>> not needed, if that means the host answers on *all* interfaces.
>
> This doesn't make sense to me. Are you saying all IP addresses are bound
> to all interfaces?
>
Yes, I dropped an 'even' there. Should be 'even if...'.
I maintain that the low-level details are needless pedantry in the
context of OP's question. It's like saying the world's militaries are
wrong to use Newtonian mechanics to plot artillery fire.
That may be technically wrong, but bringing up relativity does not help
to understand ballistic trajectories better, it only over-complicates
matters; thus it is wrong.
I accept that on the strict definition of the terms you and Rainer
consider me wrong. Technically you're right; I maintain an advanced
routing setup in our three datacenters, so I know and use all the
techniques you talk about. But context is everything, and I judged
Rainer's remarks far enough out of context to consider *him* wrong.
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
------------------------------
Date: Thu, 23 Feb 2012 07:48:46 -0800 (PST)
From: Xze <bhdistortion@gmail.com>
Subject: Constructing a value beforehand
Message-Id: <a53b1ac0-fe14-4523-853f-8296023c1cc5@b18g2000vbz.googlegroups.com>
Hi everyone,
I'm trying to implement the 'verbose' mode and got stuck.
Here is the requirement:
if verbose mode is on then: $just_hash -> {$key} = $val1.$val2.$val3
if verbose mode is off then: $just_hash -> {$key} = $val3
Now, how do I avoid useless checks 'is verbose on or off' in the loop,
having that this is known before entering the loop (please see the
code)?
This is what i currently have
my %hOpt = qw{-v 1 --verbose 1};
my $bVerbose = 0;
for (@ARGV) {
$hOpt{$_} ? $bVerbose = 1 : usage ("Unknown option: $_");
}
while(<FH>){
chomp;
my @aflds = split/,/;
#Verobse on: $just_hash -> {$key} = $val1.$val2.$val3;
#Verobse off: $just_hash -> {$key} = $val3;
$bVerbose ? $just_hash -> {$key} = ($val1.$val2.$val3) :
$just_hash -> {$key} = ($val3);
}
but this code checks the $bVervose at every iteration which is ugly. I
feel that there should be a perl-ish way to accomplish this
Is it possible to construct a pattern of the value beforehand, based
on $bVerbose?
Please advice,
Thanks
------------------------------
Date: Thu, 23 Feb 2012 16:18:11 +0000
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: Constructing a value beforehand
Message-Id: <87ehtlplq4.fsf@sapphire.mobileactivedefense.com>
Xze <bhdistortion@gmail.com> writes:
>
> I'm trying to implement the 'verbose' mode and got stuck.
> Here is the requirement:
> if verbose mode is on then: $just_hash -> {$key} = $val1.$val2.$val3
> if verbose mode is off then: $just_hash -> {$key} = $val3
>
> Now, how do I avoid useless checks 'is verbose on or off' in the loop,
[...]
> my %hOpt = qw{-v 1 --verbose 1};
> my $bVerbose = 0;
Do you have other kinds of 'verbosity' beyond b-verbosity? If not,
consider dropping the b.
> for (@ARGV) {
> $hOpt{$_} ? $bVerbose = 1 : usage ("Unknown option: $_");
> }
>
> while(<FH>){
> chomp;
> my @aflds = split/,/;
> #Verobse on: $just_hash -> {$key} = $val1.$val2.$val3;
> #Verobse off: $just_hash -> {$key} = $val3;
> $bVerbose ? $just_hash -> {$key} = ($val1.$val2.$val3) :
> $just_hash -> {$key} = ($val3);
> }
>
> but this code checks the $bVervose at every iteration which is ugly.
There are a variety of options but the most straight-forward one (and
the only without a performance penalty) is to move the verbose check
out of the loop and use two loops, one which does the 'verbose' stuff
and one which doesn't. An aesthetically nicer one would be to assign a
reference to a subroutine, roughly like this:
$value = $verbose ? sub { return $val1.$val.2.$val3; } : sub { return $val3; };
while (<FH>) {
.
.
.
$just_hash->{$key} = $value->();
}
------------------------------
Date: Thu, 23 Feb 2012 17:31:53 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: Constructing a value beforehand
Message-Id: <ji5t68$ipk$1@reader1.panix.com>
In article
<a53b1ac0-fe14-4523-853f-8296023c1cc5@b18g2000vbz.googlegroups.com>,
Xze <bhdistortion@gmail.com> wrote:
>$bVerbose ? $just_hash -> {$key} = ($val1.$val2.$val3) : $just_hash -> {$key} = ($val3);
Just a tactical thing.
The ?: operator works on values just as well. The left-hand sides are
identical, and I believe that, where it's at all convenient, identical
code should be factored out and kept in one place.
So I'd write it as
$just_hash->{$key} = ($bVerbose ? $val1.$val2.$val3 : $val3);
According to "man perlop", I believe that the parentheses are not
needed. However, for operators that I use rarely and where I'm not
sure of the precedence off the top of my head, I tend to
(over)parenthesize just to be certain.
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Thu, 23 Feb 2012 17:46:48 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: Constructing a value beforehand
Message-Id: <ji5u28$80t$1@reader1.panix.com>
In article <87ehtlplq4.fsf@sapphire.mobileactivedefense.com>,
Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
>Xze <bhdistortion@gmail.com> writes:
>> for (@ARGV) {
>> $hOpt{$_} ? $bVerbose = 1 : usage ("Unknown option: $_");
>> }
>>
>> while(<FH>){
>> chomp;
>> my @aflds = split/,/;
>> #Verobse on: $just_hash -> {$key} = $val1.$val2.$val3;
>> #Verobse off: $just_hash -> {$key} = $val3;
>> $bVerbose ? $just_hash -> {$key} = ($val1.$val2.$val3) :
>> $just_hash -> {$key} = ($val3);
>> }
>>
...
>> but this code checks the $bVervose at every iteration which is
>> ugly.
We disagree, Xze: I think you're being overly fastidious. I don't see
a clean alternative and the inefficiency is trivial.
>There are a variety of options but the most straight-forward one (and
>the only without a performance penalty) is to move the verbose check
>out of the loop and use two loops, one which does the 'verbose' stuff
>and one which doesn't.
I think it's very much more important to factor it so that common code
usually occurs in only one place. When maintaining it, you'd have to
read both loops to see that they're close to identical. If you
need to change it you'd have to remember to change it in both places,
and if you don't, Perl won't catch it and you'll likely have a
hard-to-find bug.
>An aesthetically nicer one would be to assign a reference to a
>subroutine, roughly like this:
>
>$value = $verbose ? sub { return $val1.$val2.$val3; } : sub { return $val3; };
>while (<FH>) {
> .
> .
> .
> $just_hash->{$key} = $value->();
>}
It is clever; I hadn't thought of that possibility.
Then you have to have $val1, $val2, and $val3 defined in the outer
scope, or at least create an extra {...} pair to enclose their
declarations and this code.
More seriously,
> $just_hash->{$key} = $value->();
By looking at this line, you can't tell what variables it's using --
it's splitting a lot of important information between two widely
separated parts. You could make it
> $just_hash->{$key} = $value->($val1, $val2, $val3);
(which solves the scope problem I mentioned). But it's still not
evident from looking at the line what it does with them -- it's still
splitting information. It's also not that efficient.
I think all these alternatives are much uglier than just checking one
variable in a loop.
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Thu, 23 Feb 2012 17:53:42 +0000
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: Constructing a value beforehand
Message-Id: <8762exphax.fsf@sapphire.mobileactivedefense.com>
tmcd@panix.com (Tim McDaniel) writes:
> In article
> <a53b1ac0-fe14-4523-853f-8296023c1cc5@b18g2000vbz.googlegroups.com>,
> Xze <bhdistortion@gmail.com> wrote:
>>$bVerbose ? $just_hash -> {$key} = ($val1.$val2.$val3) : $just_hash -> {$key} = ($val3);
>
> Just a tactical thing.
>
> The ?: operator works on values just as well. The left-hand sides are
> identical, and I believe that, where it's at all convenient, identical
> code should be factored out and kept in one place.
>
> So I'd write it as
>
> $just_hash->{$key} = ($bVerbose ? $val1.$val2.$val3 : $val3);
This lends itself to another variant:
my $verbose # Perl
alternatively,
my $verbose = ''; # Chicken-Little-Perl
and then use
$just_hash->{$key} = ($verbose && $val1.$val2).$val3;
------------------------------
Date: Thu, 23 Feb 2012 18:18:27 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Constructing a value beforehand
Message-Id: <jgci19-49h1.ln1@anubis.morrow.me.uk>
Quoth Xze <bhdistortion@gmail.com>:
> Hi everyone,
>
> I'm trying to implement the 'verbose' mode and got stuck.
> Here is the requirement:
> if verbose mode is on then: $just_hash -> {$key} = $val1.$val2.$val3
> if verbose mode is off then: $just_hash -> {$key} = $val3
>
> Now, how do I avoid useless checks 'is verbose on or off' in the loop,
> having that this is known before entering the loop (please see the
> code)?
>
> This is what i currently have
>
> my %hOpt = qw{-v 1 --verbose 1};
> my $bVerbose = 0;
Is this Hungarian notation? Perl variables already have sigils, they
don't need more prefixes.
Also, there's no need for that '= 0'. Newly-declared variables are
initialised to undef, which is a perfecly good false value.
> for (@ARGV) {
> $hOpt{$_} ? $bVerbose = 1 : usage ("Unknown option: $_");
> }
You might want to consider using one of the Getopt modules instead of
rolling your own.
> while(<FH>){
Don't use global bareword filehandles, use filehandles in lexical
variables. If you'd shown us how you opened the file I could show you
what I mean; something like
open my $FH, "<", "file" or die ...;
> chomp;
> my @aflds = split/,/;
> #Verobse on: $just_hash -> {$key} = $val1.$val2.$val3;
> #Verobse off: $just_hash -> {$key} = $val3;
> $bVerbose ? $just_hash -> {$key} = ($val1.$val2.$val3) :
> $just_hash -> {$key} = ($val3);
Please post complete code. Where do $val1 &c. come from? Do you just
mean @aflds[0..3], or are they supposed to come from outside the loop?
> }
>
> but this code checks the $bVervose at every iteration which is ugly.
It's not bad, actually. If your code really is this simple it may well
be the best option: all the other choices have overhead, and a simple ?:
is neither expensive nor unclear.
> I
> feel that there should be a perl-ish way to accomplish this
> Is it possible to construct a pattern of the value beforehand, based
> on $bVerbose?
There are basically two options: duplicate the loop, or use a subref.
The first is more verbose that what you have:
if ($bVerbose) {
while (<FH>) {
...;
$just_hash->{$key} = $val1.$val2.$val3;
}
}
else {
while (<FH>) {
...;
$just_hash->{$key} = $val3;
}
}
and probably isn't even faster. The second looks something like this:
my $get_val = $bVerbose
? sub { $val1.$val2.$val3 }
: sub { $val3 };
while (<FH>) {
...;
$just_hash->{$key} = $get_val->();
}
unless $valN actually live inside the loop. In that case you have to
pass them in to the subref, so you end up with
my $get_val = $bVerbose
? sub { join "", @_ }
: sub { $_[2] };
while (<FH>) {
...;
$just_hash->{$key} = $get_val->($val1, $val2, $val3);
}
Ben
------------------------------
Date: Thu, 23 Feb 2012 18:43:19 +0000
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: Constructing a value beforehand
Message-Id: <871uplpf08.fsf@sapphire.mobileactivedefense.com>
tmcd@panix.com (Tim McDaniel) writes:
> In article <87ehtlplq4.fsf@sapphire.mobileactivedefense.com>,
> Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
>>Xze <bhdistortion@gmail.com> writes:
>>> for (@ARGV) {
>>> $hOpt{$_} ? $bVerbose = 1 : usage ("Unknown option: $_");
>>> }
>>>
>>> while(<FH>){
>>> chomp;
>>> my @aflds = split/,/;
>>> #Verobse on: $just_hash -> {$key} = $val1.$val2.$val3;
>>> #Verobse off: $just_hash -> {$key} = $val3;
>>> $bVerbose ? $just_hash -> {$key} = ($val1.$val2.$val3) :
>>> $just_hash -> {$key} = ($val3);
>>> }
>>>
> ...
>>> but this code checks the $bVervose at every iteration which is
>>> ugly.
>
> We disagree, Xze: I think you're being overly fastidious. I don't see
> a clean alternative and the inefficiency is trivial.
The amount of additional work this does is proportional to the number
of lines in the input file. And this means it can become arbitrarly
large.
[...]
>>An aesthetically nicer one would be to assign a reference to a
>>subroutine, roughly like this:
>>
>>$value = $verbose ? sub { return $val1.$val2.$val3; } : sub { return $val3; };
>>while (<FH>) {
>> .
>> .
>> .
>> $just_hash->{$key} = $value->();
>>}
>
> It is clever; I hadn't thought of that possibility.
>
> Then you have to have $val1, $val2, and $val3 defined in the outer
> scope, or at least create an extra {...} pair to enclose their
> declarations and this code.
Since it is completely unknown what these $valn are etc because the
original example code didn't contain them anywhere, it is somewhat
pointless to make speculative arguments like the one above: I was
using the same dysfunctional example code that was originally posted
to mean 'whatever is supposed to be done in this case', as it was in
the original.
> More seriously,
>> $just_hash->{$key} = $value->();
> By looking at this line, you can't tell what variables it's using --
> it's splitting a lot of important information between two widely
> separated parts.
Indeed: By introducing an abstraction which encapsulates some
irrelevant detail of the original code, this irrelevant detail is
moved out of sight and what remains is the more general loop
while (<FH>) {
.
.
.
perform_operation();
}
That's an idea someone tried to introduce into 'software design' some
thirty years ago as 'functional decomposition' and it has met the
knee-jerk rejection that using a hierachical structure with a clean
separation of concerns between elements at different levels of the
hierarchy would necessarily mean getting rid of the unstructured mess
and who could possibly want that! ever since: I am the superbrain!
Chaos is my element! I don't need no stinkin' structure!
------------------------------
Date: Thu, 23 Feb 2012 18:42:15 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Constructing a value beforehand
Message-Id: <7tdi19-aih1.ln1@anubis.morrow.me.uk>
Quoth tmcd@panix.com:
> In article
> <a53b1ac0-fe14-4523-853f-8296023c1cc5@b18g2000vbz.googlegroups.com>,
> Xze <bhdistortion@gmail.com> wrote:
> >$bVerbose ? $just_hash -> {$key} = ($val1.$val2.$val3) : $just_hash ->
> {$key} = ($val3);
>
> Just a tactical thing.
>
> The ?: operator works on values just as well. The left-hand sides are
> identical, and I believe that, where it's at all convenient, identical
> code should be factored out and kept in one place.
More importantly, it's generally considered bad form to use ?: for full
statements rather than for values. I have been known to do it on
occasion, but it's nearly always clearer to use a full if/else.
(I have always quite wanted an 'else' which would turn 'and' and 'or'
into a ternary construction...)
> So I'd write it as
>
> $just_hash->{$key} = ($bVerbose ? $val1.$val2.$val3 : $val3);
>
> According to "man perlop", I believe that the parentheses are not
> needed. However, for operators that I use rarely and where I'm not
> sure of the precedence off the top of my head, I tend to
> (over)parenthesize just to be certain.
The parentheses are not needed because ?: is meant to be used as a value
operator, like '+', rather than for flow control.
In fact, ?: has rather useful precedence: you can nest more ?:s in
either half without parens, so you end up with constructions like
my $x =
$y > 0 ? "y is positive" :
$y < 0 ? "y is negative" :
$y == 0 ? "y is zero" :
"y is NaN";
or
my $x =
blessed $y ?
$y->isa("Foo") ? $y->foo :
$y->isa("Bar") ? $y->bar :
die("bad object '$y'") :
ref $y ?
reftype $y eq "HASH" ? $y->{foo} :
reftype $y eq "ARRAY" ? $y->[0] :
die("bad ref '$y'") :
$y;
which are very clear as long as you believe the precedence works
correctly :).
Ben
------------------------------
Date: Wed, 22 Feb 2012 22:42:56 -0800 (PST)
From: "dn.perl@gmail.com" <dn.perl@gmail.com>
Subject: size of an array via a ref to it
Message-Id: <e75b9c98-ce10-4520-8b4a-67f0648751e8@pi3g2000pbb.googlegroups.com>
The first patch of code works, but the second one (below the === line
below) does not.
The line marked 'this line should work, too' was temporarily bypassed
by hard-coding a value.
I have an array, and the intention is to remove the leading/trailing
whitespace from each element of the array.
So, [" one ", " Peter "] -- should become -- ["one",
"Peter"] .
I tried reading perlreftut but did not find the answer.
#!/usr/local/bin/perl
use strict ;
use warnings ;
my @arr2 = (" one ", " two ") ;
trim_array(@arr2) ;
sub trim_array
{
my @arr2 = @_ ;
my $size01 = $#arr2 + 1;
print "size-of-array is $size01\n" ;
for(my $ii = 0; $ii < $size01; $ii++) {
$arr2[$ii] =~ s/\s*(.*)\s*/$1/ ;
print "element is $arr2[$ii] \n" ;
}
}
===============
= = = = = = =
#!/usr/local/bin/perl
use strict ;
use warnings ;
my @arr2 = (" one ", " two ") ;
trim_array(\@arr2) ; ## passing the reference to the array this time
sub trim_array
{
my $ra = @_ ;
## my $size01 = $#{$ra} + 1; ## this line should work, too
my $size01 = 2 ;
print "size-of-array is $size01\n" ;
for(my $ii = 0; $ii < $size01; $ii++) {
${$ra}[$ii] =~ s/\s*(.*)\s*/$1/ ;
print "element is ${$ra}[$ii] \n" ;
}
}
Error: Can't use string ("1") as an ARRAY ref while "strict refs" in
use
------------------------------
Date: Thu, 23 Feb 2012 01:00:01 -0800 (PST)
From: Markus Hutmacher <markus.hutmacher@googlemail.com>
Subject: Re: size of an array via a ref to it
Message-Id: <9b71d8af-63db-431c-b2da-83c74c92faf8@o6g2000vbz.googlegroups.com>
On 23 Feb., 07:42, "dn.p...@gmail.com" <dn.p...@gmail.com> wrote:
> The first patch of code works, but the second one (below the =3D=3D=3D li=
ne
> below) does not.
> The line marked 'this line should work, too' was temporarily bypassed
> by hard-coding a value.
> I have an array, and the intention is to remove the leading/trailing
> whitespace from each element of the array.
> So, =A0[" =A0one =A0 ", =A0" =A0 =A0Peter "] =A0-- should become -- ["one=
",
> "Peter"] .
> I tried reading perlreftut but did not find the answer.
>
> #!/usr/local/bin/perl
>
> use strict ;
> use warnings ;
>
> my @arr2 =3D (" one ", " two ") ;
> trim_array(@arr2) ;
>
> sub trim_array
> {
> =A0 =A0 my @arr2 =3D @_ ;
> =A0 =A0 my $size01 =3D $#arr2 + 1;
> =A0 =A0 print "size-of-array is $size01\n" ;
> =A0 =A0 for(my $ii =3D 0; $ii < $size01; $ii++) =A0{
> =A0 =A0 =A0 =A0 $arr2[$ii] =3D~ s/\s*(.*)\s*/$1/ ;
> =A0 =A0 =A0 =A0 print "element is $arr2[$ii] \n" ;
> =A0 =A0 }
>
> }
>
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> =3D =3D =3D =3D =3D =3D =3D
>
> #!/usr/local/bin/perl
>
> use strict ;
> use warnings ;
>
> my @arr2 =3D (" one ", " two ") ;
> trim_array(\@arr2) ; =A0 ## passing the reference to the array this time
>
> sub trim_array
> {
> =A0 =A0 my $ra =3D @_ ;
> =A0 =A0 ## my $size01 =3D $#{$ra} + 1; =A0## this line should work, too
> =A0 =A0 my $size01 =3D 2 ;
> =A0 =A0 print "size-of-array is $size01\n" ;
> =A0 =A0 for(my $ii =3D 0; $ii < $size01; $ii++) =A0{
> =A0 =A0 =A0 =A0 ${$ra}[$ii] =3D~ s/\s*(.*)\s*/$1/ ;
> =A0 =A0 =A0 =A0 print "element is ${$ra}[$ii] \n" ;
> =A0 =A0 }
>
> }
>
> Error: Can't use string ("1") as an ARRAY ref while "strict refs" in
> use
the parameter for "trim_array" in the second case is a variable
instead of an array.
You should use
my $ra =3D shift ;
Markus
------------------------------
Date: Thu, 23 Feb 2012 11:46:45 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: size of an array via a ref to it
Message-Id: <5ilh19-l091.ln1@anubis.morrow.me.uk>
Quoth "dn.perl@gmail.com" <dn.perl@gmail.com>:
>
> The first patch of code works, but the second one (below the === line
> below) does not.
<snip>
>
> sub trim_array
> {
> my $ra = @_ ;
$ra is a scalar. That means an assignment like this evaluates @_ in
scalar context, which returns the number of elements.
Slightly confusingly, if you want to force assignment to a single scalar
to occur in list context, you need to add parens:
my ($ra) = @_;
> ## my $size01 = $#{$ra} + 1; ## this line should work, too
> my $size01 = 2 ;
> print "size-of-array is $size01\n" ;
> for(my $ii = 0; $ii < $size01; $ii++) {
> ${$ra}[$ii] =~ s/\s*(.*)\s*/$1/ ;
I realise you're just learning, but this is a very long-winded way of
writing this loop. You can use make it much simpler by using
- for (...) without any semicolons will loop over a list;
- by default it sets $_ to the current item;
- it doesn't just *set* $_, it makes it an alias, so you can modify
the original item by modifying $_;
- s/// operates on $_ by default.
So
for (@$ra) {
s/\s*(.*)\s*/$1/;
}
Also, that substitution doesn't do what you think it does. The captured
.* will match as much as it can, including whitespace, so there will be
nothing left for the final \s* to match. There are several ways round
this: the simplest is just to make two substitutions:
for (@$ra) {
s/^\s*//;
s/\s*$//;
}
You could also force the captured part to finish with non-whitespace,
which would leave all the trailing whitespace to the \s*:
s/\s*(.*\S)?\s*/$1/
The ? is necessary to make sure the pattern still matches when the
string consists only of whitespace.
Ben
------------------------------
Date: Thu, 23 Feb 2012 05:23:05 -0800
From: "John W. Krahn" <jwkrahn@example.com>
Subject: Re: size of an array via a ref to it
Message-Id: <_4r1r.12095$2q1.1565@newsfe06.iad>
dn.perl@gmail.com wrote:
>
> The first patch of code works, but the second one (below the === line
> below) does not. The line marked 'this line should work, too' was
> temporarily bypassed by hard-coding a value. I have an array, and
> the intention is to remove the leading/trailing whitespace from each
> element of the array.
> So, [" one ", " Peter "] -- should become -- ["one",
> "Peter"] .
> I tried reading perlreftut but did not find the answer.
>
> #!/usr/local/bin/perl
>
> use strict ;
> use warnings ;
>
> my @arr2 = (" one ", " two ") ;
> trim_array(@arr2) ;
>
> sub trim_array
> {
> my @arr2 = @_ ;
> my $size01 = $#arr2 + 1;
> print "size-of-array is $size01\n" ;
> for(my $ii = 0; $ii< $size01; $ii++) {
> $arr2[$ii] =~ s/\s*(.*)\s*/$1/ ;
> print "element is $arr2[$ii] \n" ;
> }
> }
That is usually written as:
my @arr2 = ( " one ", " two " );
s/^\s+//, s/\s+$// for @arr2;
John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein
------------------------------
Date: Thu, 23 Feb 2012 20:43:33 +0200
From: "George Mpouras" <nospam.gravitalsun.antispam@hotmail.com.nospam>
Subject: tree to array of arrays
Message-Id: <ji61cl$2ekl$1@news.ntua.gr>
I want to build an array of arrays from a random tree data structure.
for example if d... means "directory" and f... "file"
then from the data
/d1/d7/d8
/d1/d2/f1
/d1/d2/f2
/f1
/f2
/d1/f1
/d2/f3
/d4/d6/f1
The following array must be created. Any idea is wellcome.
[d1,
[d7,
[d8
],
[d2,
[f1],
[f2],
],
[f1],
],
[f1],
[f2],
[d2,
[f3],
],
[d4,
[d6,
[f1]
]
]
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 3620
***************************************