[31099] in Perl-Users-Digest
Perl-Users Digest, Issue: 2344 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Apr 16 16:09:46 2009
Date: Thu, 16 Apr 2009 13:09:11 -0700 (PDT)
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, 16 Apr 2009 Volume: 11 Number: 2344
Today's topics:
effienct way to select random value from the hash <vikimun@gmail.com>
Re: effienct way to select random value from the hash xhoster@gmail.com
Re: effienct way to select random value from the hash <someone@example.com>
Re: effienct way to select random value from the hash <ben@morrow.me.uk>
Re: effienct way to select random value from the hash <someone@example.com>
Re: effienct way to select random value from the hash <ben@morrow.me.uk>
Re: Hash refs and printing to FD (Tim McDaniel)
Re: Hash refs and printing to FD <tadmc@seesig.invalid>
Re: If not match and naked block question <ben@morrow.me.uk>
Re: no $ENV{'CONTENT_LENGTH'} <tadmc@seesig.invalid>
Re: no $ENV{'CONTENT_LENGTH'} <tadmc@seesig.invalid>
Re: no $ENV{'CONTENT_LENGTH'} <noreply@gunnar.cc>
Using perl can I connect to mysql via a ssh tunnel <gg@solomontribe.co.uk>
Re: Using perl can I connect to mysql via a ssh tunnel <ben@morrow.me.uk>
Re: using SSH without modules <glennj@ncf.ca>
What does `my' do?! <nospam-abuse@ilyaz.org>
Re: What does `my' do?! <devnull4711@web.de>
Re: What does `my' do?! sln@netherlands.com
Re: What does `my' do?! <ben@morrow.me.uk>
Re: What does `my' do?! sln@netherlands.com
Re: What does `my' do?! (Tim McDaniel)
Re: What does `my' do?! <tadmc@seesig.invalid>
Re: What does `my' do?! <tadmc@seesig.invalid>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Thu, 16 Apr 2009 07:35:20 -0700 (PDT)
From: viki <vikimun@gmail.com>
Subject: effienct way to select random value from the hash
Message-Id: <eea94417-6971-45c7-8c46-6a276deb5f07@k2g2000yql.googlegroups.com>
sub RandomElement { # select random element from the hash
my ($hashref) = @_;
my @keys = keys(%{$hashref});
my $random = $hashref->{ $keys[ int(rand( @keys )) ]};
}
When the hash is large, the creation of @keys for every
invocation is invefficient. It's waste that's O((N)) for every call to
RandomElement.
What would be the fastest version of RandomElement ?
Thanks
Viki
------------------------------
Date: 16 Apr 2009 16:07:09 GMT
From: xhoster@gmail.com
Subject: Re: effienct way to select random value from the hash
Message-Id: <20090416120411.569$eW@newsreader.com>
viki <vikimun@gmail.com> wrote:
> sub RandomElement { # select random element from the hash
> my ($hashref) = @_;
> my @keys = keys(%{$hashref});
> my $random = $hashref->{ $keys[ int(rand( @keys )) ]};
> }
>
> When the hash is large, the creation of @keys for every
> invocation is invefficient. It's waste that's O((N)) for every call to
> RandomElement.
Use a different data structure.
> What would be the fastest version of RandomElement ?
That depends on what is done with $hashref between calls to RandomElement.
And on how random the random element must be.
Xho
--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
------------------------------
Date: Thu, 16 Apr 2009 10:24:26 -0700
From: "John W. Krahn" <someone@example.com>
Subject: Re: effienct way to select random value from the hash
Message-Id: <fRJFl.53698$0%2.22974@newsfe22.iad>
viki wrote:
> sub RandomElement { # select random element from the hash
> my ($hashref) = @_;
> my @keys = keys(%{$hashref});
> my $random = $hashref->{ $keys[ int(rand( @keys )) ]};
> }
>
> When the hash is large, the creation of @keys for every
> invocation is invefficient. It's waste that's O((N)) for every call to
> RandomElement.
>
> What would be the fastest version of RandomElement ?
This appears to be a bit faster:
sub RandomElement { # select random element from the hash
my ( $hashref ) = @_;
my $count;
my $random = ( grep 1 > rand ++$count, values %$hashref )[ -1 ];
}
John
--
Those people who think they know everything are a great
annoyance to those of us who do. -- Isaac Asimov
------------------------------
Date: Thu, 16 Apr 2009 18:49:56 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: effienct way to select random value from the hash
Message-Id: <4n7kb6-vtj1.ln1@osiris.mauzo.dyndns.org>
Quoth "John W. Krahn" <jwkrahn@shaw.ca>:
> viki wrote:
> > sub RandomElement { # select random element from the hash
> > my ($hashref) = @_;
> > my @keys = keys(%{$hashref});
> > my $random = $hashref->{ $keys[ int(rand( @keys )) ]};
> > }
> >
> > When the hash is large, the creation of @keys for every
> > invocation is invefficient. It's waste that's O((N)) for every call to
> > RandomElement.
> >
> > What would be the fastest version of RandomElement ?
>
> This appears to be a bit faster:
>
> sub RandomElement { # select random element from the hash
> my ( $hashref ) = @_;
> my $count;
> my $random = ( grep 1 > rand ++$count, values %$hashref )[ -1 ];
> }
Presumably
sub RandomElement {
my ($hashref) = @_;
my ($count, $got);
scalar keys %$hashref; # reset iterator
while (1) {
my ($k, $v) = each %$hashref;
$got = $v if 1 > rand ++$count;
}
return $got;
}
would be more efficient for a large hash, since it doesn't build a list
of the values. Since none of these are using the hash for lookup, it
would be better to keep the values in an array and just use
$ary[rand @ary] instead.
Ben
------------------------------
Date: Thu, 16 Apr 2009 11:39:45 -0700
From: "John W. Krahn" <someone@example.com>
Subject: Re: effienct way to select random value from the hash
Message-Id: <SXKFl.61257$TD1.31139@newsfe18.iad>
Ben Morrow wrote:
> Quoth "John W. Krahn" <jwkrahn@shaw.ca>:
>> viki wrote:
>>> sub RandomElement { # select random element from the hash
>>> my ($hashref) = @_;
>>> my @keys = keys(%{$hashref});
>>> my $random = $hashref->{ $keys[ int(rand( @keys )) ]};
>>> }
>>>
>>> When the hash is large, the creation of @keys for every
>>> invocation is invefficient. It's waste that's O((N)) for every call to
>>> RandomElement.
>>>
>>> What would be the fastest version of RandomElement ?
>> This appears to be a bit faster:
>>
>> sub RandomElement { # select random element from the hash
>> my ( $hashref ) = @_;
>> my $count;
>> my $random = ( grep 1 > rand ++$count, values %$hashref )[ -1 ];
>> }
>
> Presumably
>
> sub RandomElement {
> my ($hashref) = @_;
> my ($count, $got);
>
> scalar keys %$hashref; # reset iterator
> while (1) {
> my ($k, $v) = each %$hashref;
> $got = $v if 1 > rand ++$count;
> }
> return $got;
> }
>
> would be more efficient for a large hash, since it doesn't build a list
> of the values. Since none of these are using the hash for lookup, it
> would be better to keep the values in an array and just use
> $ary[rand @ary] instead.
Your while (1) loop doesn't end so it would probably be less efficient.
ITYM:
while ( my ( $k, $v ) = each %$hashref ) {
$got = $v if 1 > rand ++$count;
}
But under my Benchmark tests that is less efficient than the OP's version.
John
--
Those people who think they know everything are a great
annoyance to those of us who do. -- Isaac Asimov
------------------------------
Date: Thu, 16 Apr 2009 19:54:57 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: effienct way to select random value from the hash
Message-Id: <1hbkb6-kik1.ln1@osiris.mauzo.dyndns.org>
Quoth "John W. Krahn" <jwkrahn@shaw.ca>:
> Ben Morrow wrote:
> >
> > Presumably
> >
> > sub RandomElement {
> > my ($hashref) = @_;
> > my ($count, $got);
> >
> > scalar keys %$hashref; # reset iterator
> > while (1) {
> > my ($k, $v) = each %$hashref;
> > $got = $v if 1 > rand ++$count;
> > }
> > return $got;
> > }
> >
> > would be more efficient for a large hash, since it doesn't build a list
> > of the values. Since none of these are using the hash for lookup, it
> > would be better to keep the values in an array and just use
> > $ary[rand @ary] instead.
>
> Your while (1) loop doesn't end so it would probably be less efficient.
:)
I had initially forgotten that the algorithm needs to iterate over the
whole hash, and was planning something like
last if 1 > rand...;
to exit early.
> ITYM:
>
> while ( my ( $k, $v ) = each %$hashref ) {
> $got = $v if 1 > rand ++$count;
> }
>
> But under my Benchmark tests that is less efficient than the OP's version.
Interesting. Presumably it's because there are more ops involved, and a
new BLOCK every time around the while loop.
Ben
------------------------------
Date: Thu, 16 Apr 2009 14:49:08 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: Hash refs and printing to FD
Message-Id: <gs7gh4$b6n$1@reader1.panix.com>
In article <gs7657$m39$1@sagnix.uni-muenster.de>,
January Weiner <january.weiner@gmail.com> wrote:
>On 2009-04-16, A. Sinan Unur <1usa@llenroc.ude.invalid> wrote:
>> Follow the solution given in the documentation.
>
>Thanks, Sinan!
>
>I was looking for something in the perlre manual...
For anyone else who was puzzled about what the regular expressions
manual (perlre) had to do with it, he meant "perlref".
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Thu, 16 Apr 2009 12:59:37 -0500
From: Tad J McClellan <tadmc@seesig.invalid>
Subject: Re: Hash refs and printing to FD
Message-Id: <slrnguesg9.t5t.tadmc@tadmc30.sbcglobal.net>
January Weiner <january.weiner@gmail.com> wrote:
> On 2009-04-16, A. Sinan Unur <1usa@llenroc.ude.invalid> wrote:
>> Follow the solution given in the documentation.
>
> Thanks, Sinan!
>
> I was looking for something in the perlre manual...
s/perlre/perlref/
??
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
------------------------------
Date: Thu, 16 Apr 2009 17:19:06 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: If not match and naked block question
Message-Id: <qc2kb6-9mi1.ln1@osiris.mauzo.dyndns.org>
Quoth alfonsobaldaserra <alfonso.baldaserra@gmail.com>:
> hi all
>
> i am stuck at the following code. it's basically some error handling
> stuff
>
> my $DSPMQ = '/usr/bin/dspmq';
> $QUEUE is the argument passed to script
>
> my $DRET = qx( $DSPMQ -m $QUEUE ) if (! ~ /AMQ7048/ ) || {
> print "$QUEUE does not exist";
> exit $return_value{'UNKNOWN'};
> }
Umm, are you perhaps confusing Perl with awk? You can't just treat a
bare block as an expression like that in Perl, you need to use 'do'; the
'if' applies to the whole statement so it will be evaluated before the
qx// is even tried; and '! ~' is not valid syntax. Try
my $tmpDRET = qx( $DSPMQ -m $QUEUE );
if ($tmpDRET =~ /AMQ7048/) {
print "$QUEUE does not exist";
exit $return_value{'UNKNOWN'};
}
my $DRET = $tmpDRET;
Of course, since you are going to exit if the condition is false you
don't need the temporary. Just assign to $DRET in any case and then
check the value afterwards.
Ben
------------------------------
Date: Thu, 16 Apr 2009 12:18:49 -0500
From: Tad J McClellan <tadmc@seesig.invalid>
Subject: Re: no $ENV{'CONTENT_LENGTH'}
Message-Id: <slrngueq3p.t5t.tadmc@tadmc30.sbcglobal.net>
A. Sinan Unur <1usa@llenroc.ude.invalid> wrote:
> "Guy" <someone@somewhere.nb.ca> wrote in
> news:49e69739$0$5478$9a566e8b@news.aliant.net:
>> I had forgotten about GET/POST.
>
> Use CGI.pm or CGI::Simple rather than cargo cult code to decode and
> process requests.
That was suggested to him 8 years ago.
Time to exercise some intolerance with regard to this OP...
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
------------------------------
Date: Thu, 16 Apr 2009 12:17:17 -0500
From: Tad J McClellan <tadmc@seesig.invalid>
Subject: Re: no $ENV{'CONTENT_LENGTH'}
Message-Id: <slrngueq0t.t5t.tadmc@tadmc30.sbcglobal.net>
Guy <someone@somewhere.nb.ca> wrote:
>
> "Glenn Jackman" <glennj@ncf.ca> a écrit dans le message de news:
> slrngud4he.kbb.glennj@smeagol.ncf.ca...
>> At 2009-04-15 08:25PM, "Guy" wrote:
>>> I was using the following:
>>> read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
>>>
>>> But it appears that this server is not providing this information. What
>>> is
>>> the proper way to get this info.
>>>
>>> Here is the information that the server is providing: (PS. I removed
>>> the
>>> customer's info.)
>> [...]
>>> QUERY_STRING = t01=Hello
>> [...]
>>> REQUEST_METHOD = GET
>>
>> CONTENT_LENGTH is set only for POST submissions.
>>
>> --
>> Glenn Jackman
>> Write a wise saying and your name will live forever. -- Anonymous
>
> I had forgotten about GET/POST.
If you had been using CGI.pm that would not have mattered, as it
would have just done the Right Thing.
> I know I was using GET (where the form data
> is sent in the URL) so I must not have been using the 'CONTENT_LENGTH'. I
> just noticed that the QUERY_STRING contains what I need so I will use it.
Don't use QUERY_STRING.
Let CGI.pm use QUERY_STRING or CONTENT_LENGTH or... as needed.
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
------------------------------
Date: Thu, 16 Apr 2009 20:24:04 +0200
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: no $ENV{'CONTENT_LENGTH'}
Message-Id: <74pbe6F150k8uU1@mid.individual.net>
Tad J McClellan wrote:
> Guy <someone@somewhere.nb.ca> wrote:
>> "Glenn Jackman" <glennj@ncf.ca> a écrit dans le message de news:
>> slrngud4he.kbb.glennj@smeagol.ncf.ca...
>>> At 2009-04-15 08:25PM, "Guy" wrote:
>>>> I was using the following:
>>>> read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
>>>>
>>>> But it appears that this server is not providing this information. What
>>>> is the proper way to get this info.
>>>>
>>>> Here is the information that the server is providing: (PS. I removed
>>>> the
>>>> customer's info.)
>>> [...]
>>>> QUERY_STRING = t01=Hello
>>> [...]
>>>> REQUEST_METHOD = GET
>> >
>>> CONTENT_LENGTH is set only for POST submissions.
>>
>> I had forgotten about GET/POST.
>
> If you had been using CGI.pm that would not have mattered, as it
> would have just done the Right Thing.
You imply that, as long as you use CGI.pm, it's ok to write CGI apps
without knowing the basics about CGI. That implication is bad advice IMNSHO.
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
------------------------------
Date: Thu, 16 Apr 2009 06:13:22 -0700 (PDT)
From: mike_solomon <gg@solomontribe.co.uk>
Subject: Using perl can I connect to mysql via a ssh tunnel
Message-Id: <84b7135c-0ee1-4170-8818-d8f35df034e8@o30g2000vbc.googlegroups.com>
I have a perl scrip that connects to mysql on a remote server
I would like to lock the server down so that mysql can only be
connected to from localhost but that would break my script
What I would like to do is connect to the mysql server via a ssh
tunnel
Can I do this in a perl script and if so how?
Thanks
------------------------------
Date: Thu, 16 Apr 2009 17:20:49 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Using perl can I connect to mysql via a ssh tunnel
Message-Id: <1g2kb6-9mi1.ln1@osiris.mauzo.dyndns.org>
Quoth mike_solomon <gg@solomontribe.co.uk>:
> I have a perl scrip that connects to mysql on a remote server
>
> I would like to lock the server down so that mysql can only be
> connected to from localhost but that would break my script
>
> What I would like to do is connect to the mysql server via a ssh
> tunnel
>
> Can I do this in a perl script and if so how?
I don't know much about MySQL but I presume you just connect over a TCP
port? In which case you simply establish a tunnel, either using one of
the SSH modules or by invoking ssh(1) in the background, and then tell
DBI to connect to the local end of the tunnel.
Ben
------------------------------
Date: 16 Apr 2009 15:26:34 GMT
From: Glenn Jackman <glennj@ncf.ca>
Subject: Re: using SSH without modules
Message-Id: <slrnguejhb.kbb.glennj@smeagol.ncf.ca>
At 2009-04-15 07:46PM, "Nene" wrote:
> On Apr 15, 5:14 pm, Tad J McClellan <ta...@seesig.invalid> wrote:
> > Nene <rodbas...@gmail.com> wrote:
> > > My object is to do a few things without the use of modules,
> >
> > What is wrong with modules?
>
> I, personally, love modules. But my manager doesn't.
There's an interesting question on stackoverflow that touches on this:
http://stackoverflow.com/questions/755168/perl-myths
--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous
------------------------------
Date: Thu, 16 Apr 2009 14:15:40 GMT
From: Ilya Zakharevich <nospam-abuse@ilyaz.org>
Subject: What does `my' do?!
Message-Id: <slrnguefcc.fpg.nospam-abuse@chorin.math.berkeley.edu>
I managed to confuse myself in a teaspoon... Consider
perl -wle "my $x; BEGIN{ $x=12 } print $x"
12
I would expect it to warn that $x is uninitialized, and print
nothing. The reasoning goes like that:
AT COMPILE TIME:
`my' is seen; after this $x is considered as lexical
BEGIN is compiled and executed; $x becomes 12
`print' is compiled
AT RUN TIME
`my' is executed. [*] Variable $x becomes undef
`print' is executed
Apparently, [*]-action is not executed in this context. The question
is: why? Is it documented?
Puzzled,
Ilya
------------------------------
Date: Thu, 16 Apr 2009 17:11:32 +0200
From: Frank Seitz <devnull4711@web.de>
Subject: Re: What does `my' do?!
Message-Id: <74p054Ft8okjU2@mid.individual.net>
Ilya Zakharevich wrote:
> I managed to confuse myself in a teaspoon... Consider
>
> perl -wle "my $x; BEGIN{ $x=12 } print $x"
> 12
>
> I would expect it to warn that $x is uninitialized, and print
> nothing. The reasoning goes like that:
>
> AT COMPILE TIME:
> `my' is seen; after this $x is considered as lexical
> BEGIN is compiled and executed; $x becomes 12
> `print' is compiled
>
> AT RUN TIME
> `my' is executed. [*] Variable $x becomes undef
> `print' is executed
>
> Apparently, [*]-action is not executed in this context. The question
> is: why? Is it documented?
I think, my() creates a variable at compile time but it doesn't
change its value at run time. To achieve the desired effect,
you must initialze $x yourself:
perl -wle 'my $x = 13; BEGIN{ $x=12 } print $x'
13
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
------------------------------
Date: Thu, 16 Apr 2009 08:55:59 -0700
From: sln@netherlands.com
Subject: Re: What does `my' do?!
Message-Id: <b6jeu4d8j1ni3jqibnh3hdvmbjue3j55n0@4ax.com>
On Thu, 16 Apr 2009 14:15:40 GMT, Ilya Zakharevich <nospam-abuse@ilyaz.org> wrote:
>I managed to confuse myself in a teaspoon... Consider
>
> perl -wle "my $x; BEGIN{ $x=12 } print $x"
> 12
>
>I would expect it to warn that $x is uninitialized, and print
>nothing. The reasoning goes like that:
>
> AT COMPILE TIME:
> `my' is seen; after this $x is considered as lexical
> BEGIN is compiled and executed; $x becomes 12
> `print' is compiled
>
> AT RUN TIME
> `my' is executed. [*] Variable $x becomes undef
> `print' is executed
>
>Apparently, [*]-action is not executed in this context. The question
>is: why? Is it documented?
>
>Puzzled,
>Ilya
perl -wle " BEGIN{ $x=12; print $x; } print 'here'; my $x=99; print $x"
12
here
99
------------
perl -wle " BEGIN{ $x=12; print $x; } print 'here'; my $x; print $x"
12
here
Use of uninitialized value in print at -e line 1.
------------
perl -wle "my $x; undef $x; print $x; BEGIN{ $x=12; } print 'here'; print $x"
Use of uninitialized value in print at -e line 1.
here
Use of uninitialized value in print at -e line 1.
------------
It appears declarations used by and past the BEGIN block is re-initialized
after block execution ('my' is re-examined) while at run-time, assignments
are processed from the beginning.
This makes sense since 'use Module' initializes variables and runs code
at compile time.
But, unusual behavior.
-sln
------------------------------
Date: Thu, 16 Apr 2009 17:44:56 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: What does `my' do?!
Message-Id: <8t3kb6-tdj1.ln1@osiris.mauzo.dyndns.org>
Quoth Ilya Zakharevich <nospam-abuse@ilyaz.org>:
> I managed to confuse myself in a teaspoon... Consider
>
> perl -wle "my $x; BEGIN{ $x=12 } print $x"
> 12
>
> I would expect it to warn that $x is uninitialized, and print
> nothing. The reasoning goes like that:
>
> AT COMPILE TIME:
> `my' is seen; after this $x is considered as lexical
> BEGIN is compiled and executed; $x becomes 12
> `print' is compiled
>
> AT RUN TIME
> `my' is executed. [*] Variable $x becomes undef
> `print' is executed
>
> Apparently, [*]-action is not executed in this context. The question
> is: why? Is it documented?
Interesting. Despite the fact that I have used exactly this construct
many times, your reasoning makes sense :). Indeed, if we run the 'my'
twice:
~% perl -wle'for (1..2) { my $x; BEGIN { $x = 2 } print $x }'
2
Use of uninitialized value $x in print at -e line 1.
~%
what you expect is exactly what happens. OK, let's see what's in
pp_hot.c... it appears that 'my' actually clears the variable on scope
*exit*, not when the 'my' is encountered at runtime, and this has been
there since at least 5.000. I suppose it makes sense: since we must
clear the variable on scope exit (to get timely destruction), there's no
point clearing it on scope entry as well.
Ben
------------------------------
Date: Thu, 16 Apr 2009 09:49:34 -0700
From: sln@netherlands.com
Subject: Re: What does `my' do?!
Message-Id: <0rmeu4ta6ft9cqsr4ttf2fe43vb5a6tsre@4ax.com>
On Thu, 16 Apr 2009 14:15:40 GMT, Ilya Zakharevich <nospam-abuse@ilyaz.org> wrote:
>I managed to confuse myself in a teaspoon... Consider
>
> perl -wle "my $x; BEGIN{ $x=12 } print $x"
> 12
>
>I would expect it to warn that $x is uninitialized, and print
>nothing. The reasoning goes like that:
>
> AT COMPILE TIME:
> `my' is seen; after this $x is considered as lexical
> BEGIN is compiled and executed; $x becomes 12
> `print' is compiled
>
> AT RUN TIME
> `my' is executed. [*] Variable $x becomes undef
> `print' is executed
>
>Apparently, [*]-action is not executed in this context. The question
>is: why? Is it documented?
>
>Puzzled,
>Ilya
perl -wle "BEGIN{ $x=12; } print 'here'; print $x; my $x;"
here
12
---------------
perl -wle "BEGIN{ $x=12; } print 'here'; print $x;"
here
12
Looks like a strange issue. Kind of auto-creates the lexical in the
case of the last one.
------------------------------
Date: Thu, 16 Apr 2009 16:56:34 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: What does `my' do?!
Message-Id: <gs7o02$6e$1@reader1.panix.com>
In article <slrnguefcc.fpg.nospam-abuse@chorin.math.berkeley.edu>,
Ilya Zakharevich <nospam-abuse@ilyaz.org> wrote:
>I managed to confuse myself in a teaspoon... Consider
>
> perl -wle "my $x; BEGIN{ $x=12 } print $x"
> 12
>
>I would expect it to warn that $x is uninitialized, and print
>nothing. The reasoning goes like that:
>
> AT COMPILE TIME:
> `my' is seen; after this $x is considered as lexical
> BEGIN is compiled and executed; $x becomes 12
> `print' is compiled
>
> AT RUN TIME
> `my' is executed. [*] Variable $x becomes undef
> `print' is executed
>
>Apparently, [*]-action is not executed in this context. The question
>is: why? Is it documented?
In "man perlsub", under "Private Variables via my()", I see both
The parameter list to my() may be assigned to if desired, which
allows you to initialize your variables. (If no initializer is
given for a particular variable, it is created with the
undefined value.)
and
A "my" has both a compile-time and a run-time effect. At
compile time, the compiler takes notice of it. The principal
usefulness of this is to quiet "use strict 'vars'", but it is
also essential for generation of closures as detailed in
perlref. Actual initialization is delayed until run time,
though, so it gets executed at the appropriate time, such as
each time through a loop, for example.
I think "Actual initialization" refers to explicit assignment via "=",
so if there's no initialization, there's no run-time assignment.
So I think
(If no initializer is given for a particular variable, it is
created with the undefined value.)
is inaccurate: it's always created undef.
So I'm thinking the the sequence is:
- compile time:
= variable is created
= since it has to have SOME value in Perl, it's set to undef
- run time:
= if an explicit initializer is provided, the assignment is done
= so if no explicit initializer is provided, it is unchanged
That is, that
my $y = 123;
is equivalent to
my $y; BEGIN { undef $y; }
$y = 123; # assigned at run time
$y;
and
my $z;
is
my $z; BEGIN { undef $z; }
$z;
That seems consistent with the examples and with
perl -wle 'my $x = 13; BEGIN{ print "in begin ", $x; $x=12 } print $x'
Use of uninitialized value $x in print at -e line 1.
in begin
^ both showing that it's created undef
13
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Thu, 16 Apr 2009 12:55:20 -0500
From: Tad J McClellan <tadmc@seesig.invalid>
Subject: Re: What does `my' do?!
Message-Id: <slrngues88.t5t.tadmc@tadmc30.sbcglobal.net>
Ilya Zakharevich <nospam-abuse@ilyaz.org> wrote:
> I managed to confuse myself in a teaspoon... Consider
>
> perl -wle "my $x; BEGIN{ $x=12 } print $x"
> 12
You develop on Windows?
> I would expect it to warn that $x is uninitialized, and print
> nothing. The reasoning goes like that:
>
> AT COMPILE TIME:
> `my' is seen; after this $x is considered as lexical
> BEGIN is compiled and executed; $x becomes 12
> `print' is compiled
>
> AT RUN TIME
> `my' is executed. [*] Variable $x becomes undef
> `print' is executed
>
> Apparently, [*]-action is not executed in this context. The question
> is: why?
Because $x is not being assigned to in the my(), I guess.
i.e. "no initializer is given" (see below).
> Is it documented?
I think so, if you can divine that "created" means "at compile time"...
From perlsub.pod (with my emphasis):
The parameter list to my() may be assigned to if desired, which allows you
to initialize your variables. (If no initializer is given for a
particular variable, it is created with the undefined value.)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
and since "creation" is in my()'s compile-time component, that is when
it is given the undef value.
If we _do_ give an initializer:
perl -wle 'my $x=undef; BEGIN{ $x=12 } print $x'
then things match up with your expectations.
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
------------------------------
Date: Thu, 16 Apr 2009 13:12:48 -0500
From: Tad J McClellan <tadmc@seesig.invalid>
Subject: Re: What does `my' do?!
Message-Id: <slrnguet90.vbp.tadmc@tadmc30.sbcglobal.net>
sln@netherlands.com <sln@netherlands.com> wrote:
[ snip all but "the last one" ]
> ---------------
> perl -wle "BEGIN{ $x=12; } print 'here'; print $x;"
> here
> 12
>
> Looks like a strange issue. Kind of auto-creates the lexical in the
> case of the last one.
There is no lexical in that one. There are only package variables there.
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
------------------------------
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:
#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc. For subscription or unsubscription requests, send
#the single line:
#
# subscribe perl-users
#or:
# unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.
#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 2344
***************************************