[23566] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 5773 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Mon Nov 10 06:05:50 2003

Date: Mon, 10 Nov 2003 03:05:05 -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           Mon, 10 Nov 2003     Volume: 10 Number: 5773

Today's topics:
        Dispatching sub in $var to SUPER without stringy eval <mb@uq.net.au>
    Re: Dispatching sub in $var to SUPER without stringy ev <usenet@morrow.me.uk>
    Re: Dispatching sub in $var to SUPER without stringy ev <mb@uq.net.au>
    Re: Dispatching sub in $var to SUPER without stringy ev <usenet@morrow.me.uk>
    Re: installing perl <kingsman22004@yahoo.com>
    Re: installing perl <usenet@morrow.me.uk>
    Re: Q: Perl & LWP - HTML Processing with Regular Expres <voitec@zzzzzzzzz.com>
    Re: Style question: map versus foreach <dmcbride@naboo.to.org.no.spam.for.me>
    Re: Style question: map versus foreach <tassilo.parseval@rwth-aachen.de>
    Re: Style question: map versus foreach <abigail@abigail.nl>
    Re: Style question: map versus foreach <abigail@abigail.nl>
    Re: Style question: map versus foreach <tassilo.parseval@rwth-aachen.de>
    Re: Style question: map versus foreach <usenet@morrow.me.uk>
    Re: Style question: map versus foreach (Anno Siegel)
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Mon, 10 Nov 2003 13:05:18 +1000
From: Matthew Braid <mb@uq.net.au>
Subject: Dispatching sub in $var to SUPER without stringy eval
Message-Id: <bomv9f$p8m$1@bunyip.cc.uq.edu.au>

Hi all,

I've got an object-package which inherits from another. Simple enough.

Both use AUTOLOAD to catch accessor calls (see example below), the 
'child' package using eval to dispatch anything it doesn't override to 
its parent.

This works, but only if I use the 'stringy' version of eval (eg eval 
"This is slow").

Is there an alternate way I can call a class' SUPER with a variable 
function call? (The code is probably clearer than my attempt to explain 
it :) )

TIA,
MB

----EXAMPLE CODE----

package Foo;
sub new {
   my $class = shift;
   my $self = bless({}, (ref($class) or $class or __PACKAGE__));
   $self->{bar} = "BAR!";
   return $self;
}

sub AUTOLOAD {
   my $self = shift;
   my $var = $AUTOLOAD;
   $var =~ s/^.*:://;
   return if $var eq 'DESTROY';
   if (exists $self->{$var}) {
     print "AUTOLOADED $var - $self->{$var}\n";
   } else {
     die "Unknown accessor $AUTOLOAD";
   }
}

package Baz;

use base qw/Foo/;

sub AUTOLOAD {
   my $self = shift;
   my $var = $AUTOLOAD;
   $var =~ s/^.*:://;
   return if $var eq 'DESTROY';
   if ($var eq 'bar') {
     # Add to parent's behaviour
     print "BAZ AUTOLOADED $var\n";
   }
   my $ret;
   # EEK - String eval
   eval "\$ret = \$self->SUPER::$var(\@_)";
   # Unfortunately this:
   # eval {$ret = $self->SUPER::$var(@_)};
   # does not even compile.
   die $@ if $@;
   return $ret;
}

package main;

my $baz = Baz->new;
$baz->bar;

----END EXAMPLE CODE----



------------------------------

Date: Mon, 10 Nov 2003 06:44:04 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Dispatching sub in $var to SUPER without stringy eval
Message-Id: <bonc3k$siu$1@wisteria.csv.warwick.ac.uk>


Matthew Braid <mb@uq.net.au> wrote:
> Hi all,
> 
> I've got an object-package which inherits from another. Simple enough.
> 
> Both use AUTOLOAD to catch accessor calls (see example below), the 
> 'child' package using eval to dispatch anything it doesn't override to 
> its parent.
> 
> This works, but only if I use the 'stringy' version of eval (eg eval 
> "This is slow").

And insecure. In almost every circumstance, string eval is Wrong... :).

> 
> Is there an alternate way I can call a class' SUPER with a variable 
> function call? (The code is probably clearer than my attempt to explain 
> it :) )
> 
> TIA,
> MB
> 
> ----EXAMPLE CODE----
> 
> package Foo;
<snip package Foo>
>
> package Baz;
> 
> use base qw/Foo/;
> 
> sub AUTOLOAD {
>    my $self = shift;
>    my $var = $AUTOLOAD;
>    $var =~ s/^.*:://;
>    return if $var eq 'DESTROY';
>    if ($var eq 'bar') {
>      # Add to parent's behaviour
>      print "BAZ AUTOLOADED $var\n";
>    }
>    my $ret;
>    # EEK - String eval
>    eval "\$ret = \$self->SUPER::$var(\@_)";
>    # Unfortunately this:
>    # eval {$ret = $self->SUPER::$var(@_)};
>    # does not even compile.

$var = "SUPER::$var";
eval { $ret = $self->$var(@_) };

>    die $@ if $@;
>    return $ret;
> }

A few more comments:

1. Have you considered using the 'fields' pragma?
2. It is usual in AUTOLOAD subs to call the sub with goto &sub so as
   not to leave an extra entry in the call stack.
3. You are not considering the context in which you are called. See
   'wantarray' in perlfunc.
4. What is the point of the eval {} ?

Ben

-- 
       .  |  .
    \           /           The clueometer is reading zero.
  .               .
 __ <-----@       __                                           ben@morrow.me.uk


------------------------------

Date: Mon, 10 Nov 2003 16:58:26 +1000
From: Matthew Braid <mb@uq.net.au>
Subject: Re: Dispatching sub in $var to SUPER without stringy eval
Message-Id: <boncuj$4p$1@bunyip.cc.uq.edu.au>

Ben Morrow wrote:
> Matthew Braid <mb@uq.net.au> wrote:
> 
>>Hi all,
>>
>>I've got an object-package which inherits from another. Simple enough.
>>
>>Both use AUTOLOAD to catch accessor calls (see example below), the 
>>'child' package using eval to dispatch anything it doesn't override to 
>>its parent.
>>
>>This works, but only if I use the 'stringy' version of eval (eg eval 
>>"This is slow").
> 
> 
> And insecure. In almost every circumstance, string eval is Wrong... :).
> 
> 
>>Is there an alternate way I can call a class' SUPER with a variable 
>>function call? (The code is probably clearer than my attempt to explain 
>>it :) )
>>
>>TIA,
>>MB
>>
>>----EXAMPLE CODE----
>>
>>package Foo;
> 
> <snip package Foo>
> 
>>package Baz;
>>
>>use base qw/Foo/;
>>
>>sub AUTOLOAD {
>>   my $self = shift;
>>   my $var = $AUTOLOAD;
>>   $var =~ s/^.*:://;
>>   return if $var eq 'DESTROY';
>>   if ($var eq 'bar') {
>>     # Add to parent's behaviour
>>     print "BAZ AUTOLOADED $var\n";
>>   }
>>   my $ret;
>>   # EEK - String eval
>>   eval "\$ret = \$self->SUPER::$var(\@_)";
>>   # Unfortunately this:
>>   # eval {$ret = $self->SUPER::$var(@_)};
>>   # does not even compile.
> 
> 
> $var = "SUPER::$var";
> eval { $ret = $self->$var(@_) };
> 
> 
>>   die $@ if $@;
>>   return $ret;
>>}
> 
> 
> A few more comments:
> 
> 1. Have you considered using the 'fields' pragma?
> 2. It is usual in AUTOLOAD subs to call the sub with goto &sub so as
>    not to leave an extra entry in the call stack.
> 3. You are not considering the context in which you are called. See
>    'wantarray' in perlfunc.
> 4. What is the point of the eval {} ?
> 
> Ben
> 

D'oh. Just needed to move the quotes around :) Thanks.

1. Haven't come across 'fields' yet - will look into it.
2. I make the AUTOLOAD this way so I don't _have_ to make a sub. In the 
case of the dispatching call (ie where Baz overrode Foo) I could do so, 
but I've often had trouble mixing OO with goto&. The docs don't mention 
it at all, so I'm never quite sure what I'm supposed to put - goto 
&$self->SUPER::whatever?
3. Good point. I'm pretty sure all the pseudo-accessors in my real code 
always return scalars (straight or refs - I hate mixing scalars and 
lists, makes checking for failure with a return undef a pain), but not a 
bad idea to have it anyway.
4. I'm going to have to look at this further. Some of this is old code 
that I inherited and for the life of me I can't tell you why the eval is 
there. I take it that the die results would look the same either way?

MB



------------------------------

Date: Mon, 10 Nov 2003 07:15:11 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Dispatching sub in $var to SUPER without stringy eval
Message-Id: <bondtv$t23$2@wisteria.csv.warwick.ac.uk>


Matthew Braid <mb@uq.net.au> wrote:
> 2. I make the AUTOLOAD this way so I don't _have_ to make a sub. In the 
> case of the dispatching call (ie where Baz overrode Foo) I could do so, 
> but I've often had trouble mixing OO with goto&. The docs don't mention 
> it at all, so I'm never quite sure what I'm supposed to put - goto 
> &$self->SUPER::whatever?

No, you have to make sure that you *don't* shift the object off @_ and
then call

goto &SUPER::method;

 . I have to confess that I'm not entirely sure what this does to
method dispatch... so it's possible that it won't work if &method is
defined in a super-super-class. :)

> 4. I'm going to have to look at this further. Some of this is old code 
> that I inherited and for the life of me I can't tell you why the eval is 
> there. I take it that the die results would look the same either way?

Yes... I guess someone may have been thinking to catch the fact that
the method didn't exist, and never got round tuit... UNIVERSAL::can is
a better choice for that, though.

Ben

-- 
Musica Dei donum optimi, trahit homines, trahit deos.    |
Musica truces molit animos, tristesque mentes erigit.    |   ben@morrow.me.uk
Musica vel ipsas arbores et horridas movet feras.        |


------------------------------

Date: Mon, 10 Nov 2003 14:29:27 +1100
From: King <kingsman22004@yahoo.com>
Subject: Re: installing perl
Message-Id: <3FAF0617.4010708@yahoo.com>


Ben Morrow wrote:
news@group.com wrote:

Ben
I am new to linux, I do appreicaite you help


Fair enough.


$/bin/su
# rm -f /usr/bin/perl
# ln -sf /usr/local/bin/perl /usr/bin/perl
# perl -e 'print "$]\n";'
bash: perl: command not found
# perl -e 'print "$]\n";'
bash: perl: command not found
#

domain:/usr/bin# ls -l | grep perl
-rwxr-xr-x    1 root     root        22903 Aug 10 11:18 find2perl
lrwxrwxrwx    1 root     root           19 Nov 10 07:48 perl -> 
/usr/local/bin/perl
-rwxr-xr-x    2 root     root       774947 Aug 10 11:19 perl-5.6
-rwxr-xr-x    2 root     root       774947 Aug 10 11:19 perl5.6.1
-rwxr-xr-x    1 root     root        35465 Aug 10 11:18 perlbug
-rwxr-xr-x    1 root     root        16920 Aug 10 11:18 perlcc
-rwxr-xr-x    1 root     root        22696 Aug 10 11:18 perldoc
-rwxr-xr-x    1 root     root          121 Aug 10 11:19 perldoc.stub
domain:/usr/bin# ls -l /usr/local/bin/ | grep perl
lrwxrwxrwx    1 root     staff           9 Nov 10 07:57 perl -> perl5.8.0
domain:/usr/bin#C-d
username@domain:~$ls -l | grep perl
drwxr-xr-x   32 username    username        8192 Nov  7 20:12 perl-5.8.1
username@demain:~$


Right, what you have here is technically known as 'a mess' :).


right :)

1. Which version of perl have you just installed, 5.8.0 or 5.8.1?


5.8.1


2. Where did you install it? What answer did you give when Configure
    asked for an installation prefix?


I don't remember a Configurating asking any question.

:~$wget http://cpan.org/src/stable.tar.gz
:~$tar -zxvf stable.tar.gz
:~$cd perl-5.8.1  <--has been corrected from previous post.
:~/perl-5.8.1$rm -f config.sh Policy.sh
:~/perl-5.8.1$sh Configure -de
:~/perl-5.8.1$make
:~/perl-5.8.1$make test
:~/perl-5.8.1$make install
so from the steps above, I would understand that I installed it in the 
/home/username/, thats what the ~$ indicates, is that right?


3. Where did that file perl-5.8.1 in ~ come from? And that symlink
    perl in /usr/local/bin?

after the make install, the steps 2 and 3 I followed at 
http://perlmonks.thepen.com/285799.html were

2.revert system Perl to Debian-standard 5.6.1
cd /usr/bin
rm perl
ln -isv perl5.6.1 perl
3.set user Perl to 5.8.1
cd /usr/local/bin
rm perl
ln -isv perl5.8.1 perl



4. Are you sure you can't install 5.8 using apt-get/dpkg/dselect?

no I am not sure, wanted to have the stable perl5.6.1 with the os, but 
use 5.8.1 with my perl programs I am writing. also download modules from 
  cpan later once I am done with this mess. I understand that using 
apt-get/dpkg/dselect would change the system perl5.6.1 to perl5.8.1 and 
thus using the unstable debian package of perl which I did not want.


thanks




------------------------------

Date: Mon, 10 Nov 2003 07:08:38 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: installing perl
Message-Id: <bondhm$t23$1@wisteria.csv.warwick.ac.uk>

[I don't quite know what happened to your quoting...]

news@group.com wrote:
> Ben Morrow wrote:
>
> 2. Where did you install it? What answer did you give when Configure
>     asked for an installation prefix?
> 
> I don't remember a Configurating asking any question.

OK... you used Configure -d, so it took all default answers. 
Check for me: after running Configure, config.sh contains
  prefix='/usr/local'
and
  installprefix='/usr/local'
?

> :~$wget http://cpan.org/src/stable.tar.gz
> :~$tar -zxvf stable.tar.gz
> :~$cd perl-5.8.1  <--has been corrected from previous post.
> :~/perl-5.8.1$rm -f config.sh Policy.sh
> :~/perl-5.8.1$sh Configure -de
> :~/perl-5.8.1$make
> :~/perl-5.8.1$make test
> :~/perl-5.8.1$make install
> so from the steps above, I would understand that I installed it in the 
> /home/username/, thats what the ~$ indicates, is that right?

That is what the ~ indicates, yes. That is not where you installed
perl. Chances are you tried to install perl under /usr/local/, because
that's where you told Configure to install it; and the install failed
because you weren't root.

> 3. Where did that file perl-5.8.1 in ~ come from? And that symlink
>     perl in /usr/local/bin?
> 
> after the make install, the steps 2 and 3 I followed at 
> http://perlmonks.thepen.com/285799.html were
> 
> 2.revert system Perl to Debian-standard 5.6.1
> cd /usr/bin
> rm perl
> ln -isv perl5.6.1 perl
> 3.set user Perl to 5.8.1
> cd /usr/local/bin
> rm perl
> ln -isv perl5.8.1 perl

*Don't* run things like this if you don't understand what they do, and why.
*Especially* not as root.

When you make a symlink, it is supposed to point to something. As the
install above failed, there is no file /usr/local/bin/perl5.8.1, and
so no point symlinking to it.

You need to run the 'make install' step as root.

You also need to be *very* sure you get the right version of perl all
the time. All the system scripts should already have
  #!/usr/bin/perl
at the top: make sure before you finish that
  /usr/bin/perl -v
shows that that is still 5.6.1. All your scripts which use the new
perl will need to have
  #!/usr/local/bin/perl
at the top; again, make sure that is in fact 5.8.1. Also, check that
your new perl is first in your path as an ordinary user. You should
probably have the old perl (/usr/bin/perl) first in your path as root,
if debian stuff needs it; you will then need to be *very* sure that
you use
  /usr/local/bin/perl -MCPAN -eshell
when you install modules, or you'll install them in the wrong tree.

Good luck!

Ben

-- 
       .  |  .
    \           /           The clueometer is reading zero.
  .               .
 __ <-----@       __                                           ben@morrow.me.uk


------------------------------

Date: Mon, 10 Nov 2003 02:20:43 GMT
From: "Voitec" <voitec@zzzzzzzzz.com>
Subject: Re: Q: Perl & LWP - HTML Processing with Regular Expressions
Message-Id: <%BCrb.4538$aT.662@news-server.bigpond.net.au>

Thanks very much James and Tad. Especially Tad for your exhaustive and quite
simple explanations.
I have retreated redfaced to my desk and fixed up the glitches.

The script now does, in a roundabout way, what I was after. It's getting a
few uninitilized valu concatenation errors but that's due to no error
checking at this stage, ie. it warns whenever it comes up across a
non-existant value or a string instead of a digit.

Like you said Tad, this can break easily :)
So I'll be off to CPAN later today for a browse.

Last night, I said to one of my friends that I'm starting to like Perl. I'll
be getting straight into "Perl & LWP" by O'Reilly to explore its web
capabilities.

Voitec


"Tad McClellan" <tadmc@augustmail.com> wrote in message
news:slrnbqt2v0.aa7.tadmc@magna.augustmail.com...
> Voitec <voitec@zzzzzzzzz.com> wrote:
>
> > my $Postcode;
> > for ($Postcode = 2040; $Postcode < 2042; $Postcode++) {
>
>
> This is a less error-prone way to do the same thing, and
> it is easier to read/understand as well:
>
>    foreach my $Postcode ( 2040 .. 2041 ) {
>
> and has the added bonus of not advertising that you have
> done too much C programming.  :-)
>
>
> >   or die "Couldn't fetch the Suburb page.";
>
>
> You should include the value of the $! variable in diagnostic messages.
>
>
> > $html =~ m{<td align=\"center\" class=\"tbody\">(\$[\d,]+)</td>}g;
>                        ^       ^        ^      ^
>                        ^       ^        ^      ^
>
> Double quotes are not "meta" in a regular expression so you
> do not need any of those backslashes.
>
>
> > my $House_Suburb_Avg = $1;
> > my $House_Region_Avg = $1;
> > my $House_Suburb_Median = $1;
> > my $House_Region_Median = $1;
> >
> > $html =~ m{<td align=\"center\" class=\"tbody\">([+|-][\d]+%)</td>}g;
>                                                      ^
>                                                      ^
> I don't think that does what you think it does.
>
> It allows a vertical bar character to match, eg:  |22%
>
>
> > my $House_Suburb_Median_Change = $1;
> > my $House_Region_Median_Change = $1;
> >
> > $html =~ m{<td align=\"center\" class=\"tbody\">(\$[\d,]+)</td>}g;
> > my $Unit_Suburb_Avg = $1;
> > my $Unit_Region_Avg = $1;
> > my $Unit_Suburb_Median = $1;
> > my $Unit_Region_Median= $1;
> >
> > $html =~ m{<td align=\"center\" class=\"tbody\">([+|-][\d]+%)</td>}g;
>
>
> backslash-d (\d) already _is_ a character class, no need
> for the square brackets either.
>
>
> > my $Unit_Suburb_Median_Change = $1;
> > my $Unit_Region_Median_Change = $1;
>
>
> > I'm sure I'm doing something surprisingly silly. Any help would be
>                      ^^^^^^^^^
>                      ^^^^^^^^^ make that plural :-)
> > appreciated.
>
>
> 1) You should use a module that understands HTML for processing
>    of HTML data. The HTML::TableExtract module would be helpful
>    when you want to process <table> data.
>
> 2) You should never use the dollar-digit variables unless you
>    have first tested to see if the match _succeeded_.
>
>       if ( $html =~ /some(.*)thing/ ) {    # or:  while (m//g)
>           # safe to use $1 here
>       }
>
> 3) The reason the values are the same is because you are copying
>    the values from the same place ($1). If that isn't what you
>    want, then don't do that.  :-)
>
> 4) The first group of four and the second group of four match
>    the same things. If you do them all together in list context,
>    you'll get the first 8 matches. If you do them separately
>    as above, you'll get the first 4 matches twice. Same for
>    the first group of two and the second group of two:
>
>    # m//g in list context, get first 4, discard the rest  (untested)
>    my( $House_Suburb_Median_Change, $House_Region_Median_Change,
>        $Unit_Suburb_Median_Change, $Unit_Region_Median_Change ) =
>        $html =~ m{<td align="center" class="tbody">([+-]\d+%)</td>}g;
>
> 5) Your program is very fragile and will break easily. If the site
>    does something as simple as change to using single quotes then
>    you get the opportunity to revisit this forgotten code and figure
>    out what it does so that you can fix it. Getting HTML parsing
>    correct is very hard to do.
>
> 6) Note that if you do #1 above, then you don't have to deal with
>    any of the other points made above!
>
>
> You are doing it the hard way. The easy way is, well, easier:
>
>    http://search.cpan.org/~msisk/HTML-TableExtract-1.08/
>
>
> -- 
>     Tad McClellan                          SGML consulting
>     tadmc@augustmail.com                   Perl programming
>     Fort Worth, Texas




------------------------------

Date: Mon, 10 Nov 2003 02:37:25 GMT
From: Darin McBride <dmcbride@naboo.to.org.no.spam.for.me>
Subject: Re: Style question: map versus foreach
Message-Id: <FRCrb.356754$pl3.261426@pd7tw3no>

Abigail wrote:

> Darin McBride (dmcbride@naboo.to.org.no.spam.for.me) wrote on MMMDCCXXII
> September MCMXCIII in <URL:news:dTzrb.355948$6C4.127445@pd7tw1no>:
> ""
> ""  The difference is that this "returns" a single scalar.  Map allocates
> ""  and returns an array (or at least, that's the concept).  Big
> ""  difference.
> 
> 
> Wrong. First of all, from the language point of view, what a function
> returns is determined by the *CONTEXT*, not the function. As Randal
> likes to chant "there are no lists in scalar context". So, a function
> in void context (it being a special case of scalar context) simply
> *cannot* return a list (arrays are never returned by Perl anyway).

No, you're right.  I suppose you overlooked the "that's the concept"
part of that paragraph.  Context rules in perl.  But that doesn't mean
that context rules in the maintainer's head when trying to decipher
what was written.

> Secondly, the fact than in older versions of Perl map was implemented
> inefficiently was a bug in perl, that now is luckely fixed. But it's

That it being fixed is "lucky" is somewhat debatable.  That doesn't
make map in void context any more clear than before - only not as bad
for runtime speed vs before the "fix".

Note that the fix is not necessarily goodness.  It may have a speed
penalty on array-context map's if it means that all of my 80 map's need
to check their context (which is never void) just so that one of your
map's (in void context) can be zillions faster.  That's an overall
negative to perl's speed since I can't speed up my map's any more, but
you could have simply converted to foreach to get an even better (even
if only slightly better) speed increase.

> pretty lame to call a certain style of Perl programming "bad practise",
> just because the implementation was inefficient. But that's no longer
> an issue anymore.

I suppose you also missed pretty much any of my post that you didn't
quote.  My point, as opposed to others, is that even without the speed
penalty, there is a stylistic benefit to using foreach when you may
otherwise wish to use map in void context.

It's simply more *obvious* to use map for array contexts and foreach in
void contexts.  And that, regardless of any speed difference, is enough
reason to discourage map in void context.


------------------------------

Date: 10 Nov 2003 07:20:26 GMT
From: "Tassilo v. Parseval" <tassilo.parseval@rwth-aachen.de>
Subject: Re: Style question: map versus foreach
Message-Id: <bone7q$82f$1@nets3.rz.RWTH-Aachen.DE>

Also sprach Abigail:

> LaDainian Tomlinson (go@away.spam) wrote on MMMDCCXXII September MCMXCIII
> in <URL:news:Jrvrb.91943$fl1.3981732@twister.southeast.rr.com>:
> ##  "Abigail" wrote:
> ## >
> ## > I'm curious, what made you think that map () in void context was bad
> ## > practice?
> ##  
> ##  I guess I don't like discarding return values.  It seems like a bad habit to
> ##  get into.  At least in this case, it could have easily been avoided with a
> ##  solution like Roy's (printing the list returned by grep() or map() rather
> ##  than printing in the map() itself).
> 
> print returns a value, which is discarded in void context..
> Assignment returns a value, which is discarded in void context.
> s/// returns a value, which is discarded in void context.
> pop returns a value, which is discarded in void context.
> map returns a value, which is discarded in void context.
> 
> 
> Do you think that using any of these five operations in void context is
> bad practise? If not, could you indicate why using some operations in
> void context is fine, but map in void context is bad practise? Because
> I really fail to see what map has done to get this special status.

It's a historical thing. It used to always generate a return-list and so
it was bad. It's questionable of course whether this a stylistic
question at all or maybe whether it wasn't simply a shortcoming (or even
a bug) in the implementation. For me it's the latter.

Perhaps some day the same optimization happens for grep (I looked at it
but it's a little more complicated than the map-case). Then these three

    $_++ for @a;
    map $_++, @a;
    grep $_++, @a;

will all behave very similarily in speed although the third version
looks indeed kind of strange since it looks like a conceptual abuse of
grep.

Tassilo
-- 
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval


------------------------------

Date: 10 Nov 2003 09:32:54 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: Style question: map versus foreach
Message-Id: <slrnbqumq6.j1k.abigail@alexandra.abigail.nl>

Tassilo v. Parseval (tassilo.parseval@rwth-aachen.de) wrote on
MMMDCCXXIII September MCMXCIII in <URL:news:bone7q$82f$1@nets3.rz.RWTH-Aachen.DE>:
<>  
<>  Perhaps some day the same optimization happens for grep (I looked at it
<>  but it's a little more complicated than the map-case). Then these three
<>  
<>      $_++ for @a;
<>      map $_++, @a;
<>      grep $_++, @a;
<>  
<>  will all behave very similarily in speed although the third version
<>  looks indeed kind of strange since it looks like a conceptual abuse of
<>  grep.


Actually, they will all be slightly different:

    sub f {
        print wantarray ? "LIST" : defined wantarray ? "SCALAR" : "VOID"
    }

         f () for 1;    # VOID.
     map f ()  => 1;    # LIST.
    grep f ()  => 1;    # SCALAR.


Abigail
-- 
perl -e '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / 
         % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %;
         BEGIN {% % = ($ _ = " " => print "Just Another Perl Hacker\n")}'


------------------------------

Date: 10 Nov 2003 09:45:51 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: Style question: map versus foreach
Message-Id: <slrnbqunif.j1k.abigail@alexandra.abigail.nl>

Darin McBride (dmcbride@naboo.to.org.no.spam.for.me) wrote on MMMDCCXXIII
September MCMXCIII in <URL:news:FRCrb.356754$pl3.261426@pd7tw3no>:
__  Abigail wrote:
__  
__  No, you're right.  I suppose you overlooked the "that's the concept"
__  part of that paragraph.  Context rules in perl.  But that doesn't mean
__  that context rules in the maintainer's head when trying to decipher
__  what was written.

If you're going to assume the maintainer doesn't know basic concepts
of Perl, all bets are off. Then one might want to avoid hashes and
regexes too.

__ > Secondly, the fact than in older versions of Perl map was implemented
__ > inefficiently was a bug in perl, that now is luckely fixed. But it's
__  
__  That it being fixed is "lucky" is somewhat debatable.  That doesn't
__  make map in void context any more clear than before - only not as bad
__  for runtime speed vs before the "fix".
__  
__  Note that the fix is not necessarily goodness.  It may have a speed
__  penalty on array-context map's if it means that all of my 80 map's need
__  to check their context (which is never void) just so that one of your
__  map's (in void context) can be zillions faster.  That's an overall
__  negative to perl's speed since I can't speed up my map's any more, but
__  you could have simply converted to foreach to get an even better (even
__  if only slightly better) speed increase.

Of course, map already had to check context. It wasn't that map left
its intermediar list on the stack if it was called in void or scalar
context. 

__  
__ > pretty lame to call a certain style of Perl programming "bad practise",
__ > just because the implementation was inefficient. But that's no longer
__ > an issue anymore.
__  
__  I suppose you also missed pretty much any of my post that you didn't
__  quote.  My point, as opposed to others, is that even without the speed
__  penalty, there is a stylistic benefit to using foreach when you may
__  otherwise wish to use map in void context.
__  
__  It's simply more *obvious* to use map for array contexts and foreach in
__  void contexts.  And that, regardless of any speed difference, is enough
__  reason to discourage map in void context.


"Obvious" is something subjective. *YOU* might find one way of doing
something more obvious than doing it another way. But that doesn't
mean it's true for everyone. Could you please explain why you find
map in void context so non-obvious? Do you think map in general is 
non-obvious, or do you only get confused when the context is void?
What about other functions in void context? Are they non-obvious too?
Or is it only map that's non-obvious?

I've had this discussion before, and people sometimes claim they find 
map in void context hard to understand but when I point out to them they
happily use other function in void context without a problem, and ask
them why they special case 'map', they don't know.

Is there anyone who can explain why map in void context is confusing,
but other functions aren't?


Abigail
-- 
perl -we '$@="\145\143\150\157\040\042\112\165\163\164\040\141\156\157\164".
             "\150\145\162\040\120\145\162\154\040\110\141\143\153\145\162".
             "\042\040\076\040\057\144\145\166\057\164\164\171";`$@`'


------------------------------

Date: 10 Nov 2003 10:29:26 GMT
From: "Tassilo v. Parseval" <tassilo.parseval@rwth-aachen.de>
Subject: Re: Style question: map versus foreach
Message-Id: <bonpa6$ivb$1@nets3.rz.RWTH-Aachen.DE>

Also sprach Abigail:

> Tassilo v. Parseval (tassilo.parseval@rwth-aachen.de) wrote on
> MMMDCCXXIII September MCMXCIII in <URL:news:bone7q$82f$1@nets3.rz.RWTH-Aachen.DE>:
><>  
><>  Perhaps some day the same optimization happens for grep (I looked at it
><>  but it's a little more complicated than the map-case). Then these three
><>  
><>      $_++ for @a;
><>      map $_++, @a;
><>      grep $_++, @a;
><>  
><>  will all behave very similarily in speed although the third version
><>  looks indeed kind of strange since it looks like a conceptual abuse of
><>  grep.
> 
> 
> Actually, they will all be slightly different:
> 
>     sub f {
>         print wantarray ? "LIST" : defined wantarray ? "SCALAR" : "VOID"
>     }
> 
>          f () for 1;    # VOID.
>      map f ()  => 1;    # LIST.
>     grep f ()  => 1;    # SCALAR.

You are right. The different contextes map() and grep() impose onto their
first argument is something I always forget about. Fortunately it
shouldn't matter in my example (unless $_ holds an object with some
fancy ++-overloading).

Thanks for the reminder,
Tassilo
-- 
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval


------------------------------

Date: Mon, 10 Nov 2003 10:35:17 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Style question: map versus foreach
Message-Id: <bonpl5$4cm$1@wisteria.csv.warwick.ac.uk>


abigail@abigail.nl wrote:
> Tassilo v. Parseval (tassilo.parseval@rwth-aachen.de) wrote on
> MMMDCCXXIII September MCMXCIII in
> <URL:news:bone7q$82f$1@nets3.rz.RWTH-Aachen.DE>:
> <>  Perhaps some day the same optimization happens for grep (I looked at it
> <>  but it's a little more complicated than the map-case). Then these three
> <>  
> <>      $_++ for @a;
> <>      map $_++, @a;
> <>      grep $_++, @a;
> <>  
> <>  will all behave very similarily in speed although the third version
> <>  looks indeed kind of strange since it looks like a conceptual abuse of
> <>  grep.
> 
> Actually, they will all be slightly different:
> 
>     sub f {
>         print wantarray ? "LIST" : defined wantarray ? "SCALAR" : "VOID"
>     }
> 
>          f () for 1;    # VOID.
>      map f ()  => 1;    # LIST.
>     grep f ()  => 1;    # SCALAR.

I like that :) it appeals to my simple mind...

It also gives a specific use for map in void context: to call a
function in list context but discard the result.

Ben

-- 
It will be seen... that the Erwhonians are a meek and long-suffering people,
easily led by the nose, and quick to offer up common sense at the shrine of
logic, when a philosopher arises among them who... convinc[es] them that their
 ...institutions are not based on... morality. [Samuel Butler] ben@morrow.me.uk


------------------------------

Date: 10 Nov 2003 10:56:24 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Style question: map versus foreach
Message-Id: <bonqso$dfh$1@mamenchi.zrz.TU-Berlin.DE>

Tassilo v. Parseval <tassilo.parseval@post.rwth-aachen.de> wrote in comp.lang.perl.misc:
> Also sprach Abigail:
> 
> > LaDainian Tomlinson (go@away.spam) wrote on MMMDCCXXII September MCMXCIII
> > in <URL:news:Jrvrb.91943$fl1.3981732@twister.southeast.rr.com>:
> > ##  "Abigail" wrote:

[...]

> > print returns a value, which is discarded in void context..
> > Assignment returns a value, which is discarded in void context.
> > s/// returns a value, which is discarded in void context.
> > pop returns a value, which is discarded in void context.
> > map returns a value, which is discarded in void context.
> > 
> > 
> > Do you think that using any of these five operations in void context is
> > bad practise? If not, could you indicate why using some operations in
> > void context is fine, but map in void context is bad practise? Because
> > I really fail to see what map has done to get this special status.
> 
> It's a historical thing. It used to always generate a return-list and so
> it was bad. ...

(bad to use it in void context, I assume)

Historically, the concept of "map" functions was introduced with LISP,
every other language has it from there.  Interestingly, the original
LISP "map" doesn't return anything, it is a procedure that is only called
for its side effects.  Calling it anywhere *but* in void context is useless.
(You need "maplist" if you want a return value; the real ancestor of other
"map" functions is LISPs "mapcar".)

So the original inventors of "map" didn't share the intuition that "map"
has to return an image.

Anno


------------------------------

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.  

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 V10 Issue 5773
***************************************


home help back first fref pref prev next nref lref last post