[31315] in Perl-Users-Digest
Perl-Users Digest, Issue: 2560 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Aug 19 03:09:46 2009
Date: Wed, 19 Aug 2009 00:09:12 -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 Wed, 19 Aug 2009 Volume: 11 Number: 2560
Today's topics:
How to code an implicit $_ argument? (Tim McDaniel)
Re: How to code an implicit $_ argument? <someone@example.com>
Re: How to code an implicit $_ argument? <nospam-abuse@ilyaz.org>
Re: How to code an implicit $_ argument? (Tim McDaniel)
Re: revisiting web development in Perl...where to start <nat.k@gm.ml>
Re: revisiting web development in Perl...where to start <tadmc@seesig.invalid>
Re: Rounding issue <ben@morrow.me.uk>
Re: Rounding issue <jurgenex@hotmail.com>
Re: Rounding issue (Jens Thoms Toerring)
undef($foo) versus $foo = undef()? (Tim McDaniel)
Re: undef($foo) versus $foo = undef()? <uri@stemsystems.com>
Re: undef($foo) versus $foo = undef()? <nospam-abuse@ilyaz.org>
Re: undef($foo) versus $foo = undef()? (Tim McDaniel)
Re: undef($foo) versus $foo = undef()? <uri@StemSystems.com>
Re: undef($foo) versus $foo = undef()? (Tim McDaniel)
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Wed, 19 Aug 2009 00:10:23 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: How to code an implicit $_ argument?
Message-Id: <h6fftf$82a$1@reader1.panix.com>
This is a function which trims leading and trailing whitespace from a
variable in-place, operating on $_ if there are no arguments provided.
(If the value is undef, it leaves it undef.) I feel a bit unclean
using "goto &sub" and hand-manipulation of @_. Opinions? Better ways
to do it?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#! /usr/bin/perl -w
use strict;
sub trim(;\$) {
if (@_ == 0) {
$_[0] = \$_;
goto &trim;
}
my $var = $_[0];
if (defined $$var) {
$$var =~ s/^\s+//;
$$var =~ s/\s+$//;
}
return $$var;
}
my $v = ' abc ';
trim $v;
if ($v ne 'abc') {
warn "\$v should be 'abc' but is '$v' instead.\n";
}
$_ = ' 123 ';
trim;
if ($_ ne '123') {
warn "\$_ should be '123' but is '$_' instead.\n";
}
exit 0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The only clean way I see to do it is this, but I don't know whether
later Perl interpreters notice and optimize the tail recursion.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
sub trim(;\$);
sub trim(;\$) {
if (@_ == 0) {
return trim($_);
}
my $var = $_[0];
if (defined $$var) {
$$var =~ s/^\s+//;
$$var =~ s/\s+$//;
}
return $$var;
}
...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In a recent message, someone mentioned that Perl 5.10 has the _
prototype character: if there is no matching argument, use $_.
But that doesn't work here, as the following code produces
Can't use string (" abc ") as a SCALAR ref while "strict refs"
in use at /home/tmcdaniel/local/test/084.pl line 7.
and "sub trim(\_)" causes
Malformed prototype for main::trim: \_ at
/home/tmcdaniel/local/test/084.pl line 15.
Also, where is _ documented? I don't see it in "man perlsub" for Perl
5.10 in Cygwin.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
sub trim(_) {
my $var = $_[0];
if (defined $$var) {
$$var =~ s/^\s+//;
$$var =~ s/\s+$//;
}
return $$var;
}
...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Tue, 18 Aug 2009 19:48:11 -0700
From: "John W. Krahn" <someone@example.com>
Subject: Re: How to code an implicit $_ argument?
Message-Id: <KJJim.77878$0z7.49077@newsfe07.iad>
Tim McDaniel wrote:
> This is a function which trims leading and trailing whitespace from a
> variable in-place, operating on $_ if there are no arguments provided.
> (If the value is undef, it leaves it undef.) I feel a bit unclean
> using "goto &sub" and hand-manipulation of @_. Opinions? Better ways
> to do it?
sub trim {
if ( @_ ) {
s/^\s+//, s/\s+$// for @_;
}
else {
s/^\s+//, s/\s+$// for $_;
}
}
John
--
Those people who think they know everything are a great
annoyance to those of us who do. -- Isaac Asimov
------------------------------
Date: Wed, 19 Aug 2009 03:48:10 +0000 (UTC)
From: Ilya Zakharevich <nospam-abuse@ilyaz.org>
Subject: Re: How to code an implicit $_ argument?
Message-Id: <slrnh8mtfq.q2f.nospam-abuse@chorin.math.berkeley.edu>
On 2009-08-19, Tim McDaniel <tmcd@panix.com> wrote:
> sub trim(;\$) {
> if (@_ == 0) {
> $_[0] = \$_;
> goto &trim;
> }
push @_, $_ unless @_;
Etc,
Ilya
------------------------------
Date: Wed, 19 Aug 2009 04:47:38 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: How to code an implicit $_ argument?
Message-Id: <h6g05a$2kk$1@reader1.panix.com>
In article <KJJim.77878$0z7.49077@newsfe07.iad>,
John W. Krahn <jwkrahn@shaw.ca> wrote:
>Tim McDaniel wrote:
>> This is a function which trims leading and trailing whitespace from
>> a variable in-place, operating on $_ if there are no arguments
>> provided. (If the value is undef, it leaves it undef.) I feel a
>> bit unclean using "goto &sub" and hand-manipulation of @_.
>> Opinions? Better ways to do it?
>
>sub trim {
> if ( @_ ) {
> s/^\s+//, s/\s+$// for @_;
> }
> else {
> s/^\s+//, s/\s+$// for $_;
> }
> }
Oo-er. So I should depend on
The array @_ is a local array, but its elements are aliases for
the actual scalar parameters. In particular, if an element $_[0]
is updated, the corresponding argument is updated (or an error
occurs if it is not updatable).
instead of taking references explicitly or implicitly. Hrm. It's a
run-time error instead of compile-time, but it's much more elegant and
Perlish.
Two improvements occur to me.
> s/^\s+//, s/\s+$// for $_;
has the effect of creating a new $_ and aliasing $_ to, um, old $_,
which is not needed. It would be easier to just do
s/^\s+//, s/\s+$//;
> if ( @_ ) {
> s/^\s+//, s/\s+$// for @_;
> }
> else {
> s/^\s+//, s/\s+$// for $_;
> }
looks very symmetric and therefore elegant. But the individual
actions have to fit in a comma expression. Also, the set of
statements are repeated, so any change has to be done in two places --
in particular, one part of the spec is that undef should be silently
ignored, but the above code causes two "Use of uninitialized value $_
in substitution (s///)" warnings.
My first version defined a return value, but I don't really need it,
since the function changes variables. I prefer to always return an
explicit value, if nothing else to prevent accidental communication of
the function's last expression, causing the caller to accidentally
depend on the implementation.
I think I'll do something along these lines:
sub trim(@) {
foreach (@_ ? @_ : $_) {
if (defined $_) {
s/^\s+//;
s/\s+$//;
}
}
return undef;
}
or something equivalent. Maybe I will go for
defined($_) && (s/^\s+//, s/\s+$//) for @_ ? @_ : $_;
Many thanks for the insight.
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Tue, 18 Aug 2009 15:15:24 -0700
From: Nathan Keel <nat.k@gm.ml>
Subject: Re: revisiting web development in Perl...where to start?
Message-Id: <ZJFim.106366$O23.83588@newsfe11.iad>
Jamie wrote:
> I suspect most of the php coders out there have PHP as their first
> "language" and aren't programmers so much as web designers, they
> figure out how to do a couple things with it and walla, they jump into
> writing full-fledged php applications that aren't planned out.
>
That's exactly what I've seen. Of course, none of us are claiming there
aren't skilled coders in PHP, but far more unskilled people code in PHP
than in Perl.
------------------------------
Date: Tue, 18 Aug 2009 22:44:54 -0500
From: Tad J McClellan <tadmc@seesig.invalid>
Subject: Re: revisiting web development in Perl...where to start?
Message-Id: <slrnh8msoo.1vf.tadmc@tadmc30.sbcglobal.net>
Jamie <nospam@geniegate.com> wrote:
> I suspect most of the php coders out there have PHP as their first "language" and
> aren't programmers so much as web designers, they figure out how to do a couple
> things with it and walla, they jump into writing full-fledged php applications
> that aren't planned out.
s/walla/voila/
http://www.wsu.edu/~brians/errors/voila.html
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
------------------------------
Date: Tue, 18 Aug 2009 23:16:46 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Rounding issue
Message-Id: <erlrl6-r8q2.ln1@osiris.mauzo.dyndns.org>
Quoth pacman@kosh.dhis.org (Alan Curry):
>
> Will there ever be a time when our need for speed is satiated, and we can
> start thinking about making it easier to get correct results, instead of
> bad results quickly? Can a well-rounded, general-purpose language like perl
> ever decide that computers are fast enough now, that accuracy-preserving
> "bignum" should be the default mode, and FPU speed freaks should be the ones
> importing a special module to meet their needs?
There are modern languages that default to using exact types; Haskell,
for instance. I believe Perl 6 is slated to auto-upgrade to bignums
where necessary to preserve precision, but I really couldn't say for
sure.
> If not, then can we at least hope that in the future, Math::BigRat will
> play well with sprintf?
Patches welcome :).
Ben
------------------------------
Date: Tue, 18 Aug 2009 15:57:08 -0700
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: Rounding issue
Message-Id: <jk9m85p8jgvvcp5i7d7no6a3feoqerjra5@4ax.com>
pacman@kosh.dhis.org (Alan Curry) wrote:
>In article <j12m855c4rvjkbqtk39ls6psdgh8mu1l5o@4ax.com>,
>Jürgen Exner <jurgenex@hotmail.com> wrote:
>>
>>No, Perl does not provide BCD natively (Binary Coded Decimals; someone
>>else already pointed that out). The reason is simple: they not only take
>>up more space (probably a minor issue on modern hardware) but more
>>important most hardware does not support BCD arithmetic, therefore all
>>calculations would have to be handcoded in software, making them very
>>slow.
>
>Does anyone else find this argument ("We have to use the CPU's floating-point
>because anything else is too slow") a bit odd?
Please note I said "very slow", I didn't say "too slow". The first is a
comparison against hardware supported arithmetic and can be measured.
The second is an empirical evaluation that has to be made for the
individual application.
>Did we not once have CPUs with
>no floating point at all?[1] It was all "in software", and at about 1MHz too.
>Still, somehow, things got done.
Of course, the question is more if you are patient enough to wait that
long considering today's applications. Somehow I have a feeling that
viewing a video or running a graphic intensive game on a 386 wouldn't be
much fun ;-) .
>I wouldn't be surprised if arbitrary-precision GMP-based Math::BigRat on a
>recent machine outperforms the limited-precision software floating-point that
>was used in the old days. But still people say "Too slow. Gotta use the FPU
>for speed." Really?
Well, you can always do a benchmark test.
>Will there ever be a time when our need for speed is satiated, and we can
>start thinking about making it easier to get correct results, instead of
>bad results quickly? Can a well-rounded, general-purpose language like perl
>ever decide that computers are fast enough now, that accuracy-preserving
>"bignum" should be the default mode, and FPU speed freaks should be the ones
>importing a special module to meet their needs?
I'm not sure if that's really the issue.
There are only very few areas where a number has to be accurate to the
last digit, finance being the most obvious.
Pretty much any other application area really doesn't care that much
about precision. Typically either the input data itself is only
approximate to begin with. It really doesn't matter if the readout on
that 5$ digital thermometer from the hardware store is 25.34 or 25.35
degree, its accuracy is lower than the display increment anyway.
Or there is no benefit for a result that is accurate to the last digit.
For example it really doesn't matter if it takes 2 hours, 4 minutes,
25.1234 seconds to reach your destination or 2 hours, 4 minutes, 25.1235
seconds, in particular as the distance as well as the speed are both
only rough approximations in the first place.
Same goes for graphics: if the color for a particular pixel is off by
one and the immediate neighbour colour is shown instead your eye would
never notice.
Same goes for parts manufacturing: those machining tolerances are orders
of magnitudes larger then any rounding error.
Same for architecture and building plans, construction, engineering,
surveying, ... you name it. The list goes on and on while I feel hard
pressed to name an area beside finance where the accuracy of the last
digit is really significant.
Remember those slide rulers and tables of logarithms? I still remember
how we learned in school how to use them properly, i.e. when and how to
round and which precision to expect and were warned sternly not to hunt
for false precision. And those rulers and tables were used to
sucessfully build rockets, airplanes, and nuclear bombs.
Today even a simple 16bit binary FPU is way(!) more accurate than those
rulers and tables. I really don't think we need more precision but a
better understanding why hunting for more precision is pointless.
BTW: Last but not least teachers would also show us how to rearrange our
calculations, such that using those tools would introduce the least
error. And that is what's missing in our OP's understanding. A computer
is a tool. You need to understand _how_ to use it and how to arrange
your calculations to not screw up your final result. Famous example:
adding a very long sequence of very small numbers to a very large
number.
As I said: revisit Computer Numerics.
jue
------------------------------
Date: 18 Aug 2009 23:14:32 GMT
From: jt@toerring.de (Jens Thoms Toerring)
Subject: Re: Rounding issue
Message-Id: <7f0quoF2h4nceU1@mid.uni-berlin.de>
Marten Lehmann <lehmannmapson@cnm.de> wrote:
> Hello,
> > But what will do for you (if it's possible at all) depends on
> > what exactly you want to do.
> I want to do financial calculations (nothing special, just simple things
> like adding items of an invoice, adding taxes, removing disagio from
> creditcard transactions etc.) and I want to be sure of correct results.
I fear you stepped not only into a mathematical but at the same
time legal minefield;-)
> So if a total with tax is $0.015, then I need it to be rounded to $0.02
> and not $0.01. Therefor, numbers need to be represented as they are and
> not the typical internal representation.
As others have pointed out there's no "as they are". You are always
dealing with a certain representation of a number. (Finite) rational
numbers can be represented with a limited number of bits in a repre-
sentation that uses a nominator and denominator. But once you want
to write them in a system with a decimal point in whatever base you
choose most numbers can't be represented exactly (and that are just
the rational numbers). Which these few "lucky numbers" are depends
on the base.
> I don't want to use cents as integers. Even cents will get odd
> numbers after the decimal point if you have to add e.g. 19% value
> added taxes.
Yes. And thus there are, as far as I know (but I am not an expert
on this at all and just have read a bit here an there, so take this
ith a big grain of salt), certain regulations that tell how you have
to do it. That's because there is no "right" and simple way to deal
with these problems, so instead certain rules of how to do it in a
at least in a consistent way where set up. They range from the ques-
tion "should I apply the tax to each item individually and then add
them up or add them up first and then calculate the tax" to "how
many digits after the decimal point have to be taken into account",
how rounding is to be done consistently (which doesn't mean mathe-
matically correct!).
The "most mathematically correct" way to go is use something like
Math::BigRat, hoping that you don't have to deal with operations
that result in irrational numbers (like taking square roots just
to mention a very simple case) - then all bets are off. If you can
reduce everything to basically addition, subtraction, multiplica-
tion and division (which also covers exponentiation with integer
exponents) you should be fine with that. Anything more complica-
ted is likely to get you to end up with irrational numbers.
> And even worser: The whole code would get bloated and the original
> intention of the code would be harder to understand if the whole
> source is full of "* 100" and "/ 100".
I fear that most "correctly" written programs in that problem domain
("correctly" in the sense that they satisfy the local regulations)
have to look a bit "ugly", at least in parts. The best way is probably
to write a module that takes care of all the "ugly" stuff, so the main
part of the program doesn't.
> In databases it is easy to define a decimal like (10,2): 10 digits before
> the point, 2 after it. It would be great to have this directly in Perl
In a database you (normally) only store things. So it's easy to e.g.
store the string (or BCD) representation of "0.15" in a database in
this case. The real problems arise when you have to do something
with these numbers (and that holds also for a database when you
have e.g. stored procedures, they also have to do calculations in
some representation). And what do you think is going to be stored
in the database when you ask it to store the value 1.144999999736
(i.e. the result of some floating point computation) in the 10,2
format? It's rather likely going to be "1.14" and not the "1.15"
you might be wishing for.
> so that sprintf and other functions can still work with such values and
> variables, not only specific modules like Math::Decimal.
Since there are no general mathematically correct solutions for
those problems they can't be easily incorporated into a program-
ming language. As far as I know there are regulations that tell
how to do things "correctly - but this definition of what is
"correct" may be different in different countries (or may even
already differ if you are calculating taxes or interest rates -
but as I said, I am no real expert on this).
What you're asking for is a simple solution to an extremely com-
plicated problem. And a general solution, unfortunately, doesn't
(and can't) exist. As someone else pointed out, you have to first
define what the "correct" behaviour actually is. But since what
is "correct" is not well-defined the very best you can hope for
is that someone else came up with the same definition of "correct"
before and published a module that implements this "correct" way.
Otherwise you have to write one yourself.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
------------------------------
Date: Tue, 18 Aug 2009 23:39:18 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: undef($foo) versus $foo = undef()?
Message-Id: <h6fe36$96u$1@reader1.panix.com>
Is there any reason to prefer one of
$foo = undef;
versus
undef $foo;
? (If you like, include the parens that show that undef is a
function.)
I prefer functions that are pure to those that alter its arguments,
ceteris paribus (no pun intended), so I think I prefer
$foo = undef;
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Tue, 18 Aug 2009 23:30:24 -0400
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: undef($foo) versus $foo = undef()?
Message-Id: <87ws508oq7.fsf@quad.sysarch.com>
>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
TM> Is there any reason to prefer one of
TM> $foo = undef;
TM> versus
TM> undef $foo;
i prefer NEITHER. explicitly undefing a scalar usually signals a poor
design. usually you let variables exit scope and upon reentry they get
cleared by the my declaration. so when i see code like the above i look
around and try to find a way to not need to do that.
TM> I prefer functions that are pure to those that alter its arguments,
TM> ceteris paribus (no pun intended), so I think I prefer
TM> $foo = undef;
if you must choose one, that is better for a subtle reason. undef $foo
leads newbies to also say undef @bar or undef %bar. those seem to work
fine as the aggregates are cleared. but then that leads to this bad code
to see if there are any value or keys in them: defined( @bar ) or
defined( %bar ). that actually doesn't test if there is any actual data
in them but whether any memory has ever been allocated for them. you
normally just need to do a plain boolean test to see if they are empty
or not. the proper way to clear an aggregate (other than leaving scope
and having them clear by their my declaration) is to assign the empty
list () to them.
so it is a long way around but that is why i never do undef $foo and
almost never do $foo = undef.
in over 10k lines of stem code, i found 9 uses of undef and 4 of them
were this line in one module that needed to ignore the keys of a hash:
while( my( undef, $event ) = each %{$timer_events} ) {
4 of the uses were assigning undef in cases where you had to and the
scalar wasn't going out of scope (it was to be used in nearby code).
so i practice what i preach and don't use undef unless i have to and
when i do, i assign it vs call it for its side effect.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Wed, 19 Aug 2009 03:46:20 +0000 (UTC)
From: Ilya Zakharevich <nospam-abuse@ilyaz.org>
Subject: Re: undef($foo) versus $foo = undef()?
Message-Id: <slrnh8mtcb.q2f.nospam-abuse@chorin.math.berkeley.edu>
On 2009-08-18, Tim McDaniel <tmcd@panix.com> wrote:
> Is there any reason to prefer one of
>
> $foo = undef;
>
> versus
>
> undef $foo;
The second one free()s the buffers associated with $foo. The second
one is 2 opcodes, the first one is 3.
Enjoy,
Ilya
------------------------------
Date: Wed, 19 Aug 2009 05:02:06 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: undef($foo) versus $foo = undef()?
Message-Id: <h6g10e$jrk$1@reader1.panix.com>
In article <87ws508oq7.fsf@quad.sysarch.com>,
Uri Guttman <uri@stemsystems.com> wrote:
>>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
>
> TM> Is there any reason to prefer one of
> TM> $foo = undef;
>
> TM> versus
>
> TM> undef $foo;
>
>i prefer NEITHER. explicitly undefing a scalar usually signals a poor
>design. usually you let variables exit scope and upon reentry they
>get cleared by the my declaration.
Yes. I do try to limit the scope of variables by using blocks, often
not connected to if or for, just
{
my %unique_xes;
...
}
or whatever.
But there have been a few cases where variable scopes don't nest
nicely, so I explicitly kill the variable as soon as I can.
>undef $foo leads newbies to also say undef @bar or undef %bar. those
>seem to work fine as the aggregates are cleared.
Well, they certainly work, unlike
@bar = undef;
%baz = undef;
!
>but then that leads to this bad code to see if there are any value or
>keys in them: defined( @bar ) or defined( %bar ).
"Doctor, doctor, it hurts when I do *this*!"
"Well, don't DO '*this*'!"
>the proper way to clear an aggregate (other than leaving scope and
>having them clear by their my declaration) is to assign the empty
>list () to them.
Is there any functional difference between
undef @bar;
or
@bar = ();
(and similarly for %baz)?
So symmetry would prefer
undef $foo;
undef @bar;
undef %baz;
but value-ness would prefer
$foo = undef;
@bar = ();
%baz = ();
>in over 10k lines of stem code, i found 9 uses of undef and 4 of them
>were this line in one module that needed to ignore the keys of a
>hash:
> while( my( undef, $event ) = each %{$timer_events} ) {
Some wording in the man pages makes me wonder whether it would be just
as efficient to do
foreach my $event ( values %{$timer_events} ) {
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Wed, 19 Aug 2009 01:37:52 -0400
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: undef($foo) versus $foo = undef()?
Message-Id: <87pras749b.fsf@quad.sysarch.com>
>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
>> undef $foo leads newbies to also say undef @bar or undef %bar. those
>> seem to work fine as the aggregates are cleared.
TM> Well, they certainly work, unlike
TM> @bar = undef;
TM> %baz = undef;
TM> !
>> but then that leads to this bad code to see if there are any value or
>> keys in them: defined( @bar ) or defined( %bar ).
>> the proper way to clear an aggregate (other than leaving scope and
>> having them clear by their my declaration) is to assign the empty
>> list () to them.
TM> Is there any functional difference between
TM> undef @bar;
TM> or
TM> @bar = ();
TM> (and similarly for %baz)?
yes. do one and the other and then test with defined. one is true and
the other is false. the fact that you can even call defined on an
aggregate is really a bug. p6 is eliminating that iirc.
TM> So symmetry would prefer
TM> undef $foo;
TM> undef @bar;
TM> undef %baz;
TM> but value-ness would prefer
TM> $foo = undef;
TM> @bar = ();
TM> %baz = ();
>> in over 10k lines of stem code, i found 9 uses of undef and 4 of them
>> were this line in one module that needed to ignore the keys of a
>> hash:
>> while( my( undef, $event ) = each %{$timer_events} ) {
TM> Some wording in the man pages makes me wonder whether it would be just
TM> as efficient to do
TM> foreach my $event ( values %{$timer_events} ) {
but that creates a list of the values first. my code iterates over the
values with less storage needed and more speed.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Wed, 19 Aug 2009 06:28:20 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: undef($foo) versus $foo = undef()?
Message-Id: <h6g624$j66$1@reader1.panix.com>
In article <87pras749b.fsf@quad.sysarch.com>,
Uri Guttman <uri@StemSystems.com> wrote:
>>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
> TM> Is there any functional difference between
> TM> undef @bar;
> TM> or
> TM> @bar = ();
> TM> (and similarly for %baz)?
>
>yes. do one and the other and then test with defined. one is true and
>the other is false. the fact that you can even call defined on an
>aggregate is really a bug. p6 is eliminating that iirc.
"man perlfunc" says
Use of "defined" on aggregates (hashes and arrays) is deprecated.
It used to report whether memory for that aggregate has ever been
allocated. This behavior may disappear in future versions of
Perl. You should instead use a simple test for size:
if (@an_array) { print "has array elements\n" }
if (%a_hash) { print "has hash members\n" }
> >> in over 10k lines of stem code, i found 9 uses of undef and 4 of them
> >> were this line in one module that needed to ignore the keys of a
> >> hash:
> >> while( my( undef, $event ) = each %{$timer_events} ) {
>
> TM> Some wording in the man pages makes me wonder whether it would
> TM> be just as efficient to do
>
> TM> foreach my $event ( values %{$timer_events} ) {
>
>but that creates a list of the values first. my code iterates over
>the values with less storage needed and more speed.
What made me wonder was
The values are returned in an apparently random order. The actual
random order is subject to change in future versions of perl, but
it is guaranteed to be the same order as either the "keys" or
"each" function would produce on the same (unmodified) hash. ...
As a side effect, calling values() resets the HASH's internal
iterator, see "each". (In particular, calling values() in void
context resets the iterator with no other overhead.)
Note that the values are not copied, which means modifying them
will modify the contents of the hash:
for (values %hash) { s/foo/bar/g } # modifies %hash values
for (@hash{keys %hash}) { s/foo/bar/g } # same
particularly that last. It could be generating a list for
values(%hash) and doing further magic to point to the real values
(multiplying the storage needed), or maybe there's an optimization in
such a simple case to make values() work as efficiently as each()?
I've seen people post timing test results here, but I've not looked
into the modules that conveniently implement them.
--
Tim McDaniel, tmcd@panix.com
------------------------------
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 2560
***************************************