[24438] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 6622 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri May 28 14:10:42 2004

Date: Fri, 28 May 2004 11:10:13 -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           Fri, 28 May 2004     Volume: 10 Number: 6622

Today's topics:
    Re: On "for (@foo)" <tadmc@augustmail.com>
    Re: On "for (@foo)" <jkrugman345@yahbitoo.com>
    Re: On "for (@foo)" <usenet@morrow.me.uk>
    Re: On "for (@foo)" <usenet@morrow.me.uk>
    Re: On "for (@foo)" <usenet@morrow.me.uk>
    Re: On "for (@foo)" <dha@panix2.panix.com>
    Re: On "for (@foo)" <ittyspam@yahoo.com>
    Re: On "for (@foo)" <tadmc@augustmail.com>
    Re: On "for (@foo)" <nobull@mail.com>
    Re: On "for (@foo)" <nobull@mail.com>
    Re: On "for (@foo)" <jkrugman345@yahbitoo.com>
    Re: On "for (@foo)" <nobull@mail.com>
    Re: On "for (@foo)" <please_post@nomail.edu>
    Re: On "for (@foo)" <usenet@morrow.me.uk>
    Re: On "for (@foo)" <ittyspam@yahoo.com>
    Re: On "for (@foo)" <nobull@mail.com>
    Re: On "for (@foo)" <nobull@mail.com>
    Re: On "for (@foo)" <jgibson@mail.arc.nasa.gov>
    Re: Remove first letter of each string in array <uri.guttman@fmr.com>
    Re: Remove first letter of each string in array <nobull@mail.com>
    Re: Unwanted double-interpolation in string passed to b <usenet@morrow.me.uk>
    Re: Unwanted double-interpolation in string passed to b <lawshouse.public@btconnect.com>
    Re: Unwanted double-interpolation in string passed to b <usenet@morrow.me.uk>
    Re: Unwanted double-interpolation in string passed to b ctcgag@hotmail.com
    Re: Using Cookies With Perl (GreenLight)
    Re: Why is this upload script not working (Mark Constant)
    Re: Why is this upload script not working <usenet@morrow.me.uk>
    Re: Why is this upload script not working <remorse@partners.org>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Fri, 28 May 2004 08:00:23 -0500
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: On "for (@foo)"
Message-Id: <slrncbedv7.gld.tadmc@magna.augustmail.com>

bill <please_post@nomail.edu> wrote:
> 
> 
> 
> Something like this burned me really bad once:


That can happen when you don't carefully read the documentation
for the features that you use.


> It's as if the loop variable $y was a reference to the current
> element of the array, except that it doesn't need to be dererenced.


The docs call it an "alias".

Perl's control structures are documented in:

   perldoc perlsyn


The 3rd paragraph in the "Foreach Loops" section discusses the
behavior that you have observed.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


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

Date: Fri, 28 May 2004 14:14:45 +0000 (UTC)
From: J Krugman <jkrugman345@yahbitoo.com>
Subject: Re: On "for (@foo)"
Message-Id: <c97hgl$j48$1@reader2.panix.com>

In <slrncbedv7.gld.tadmc@magna.augustmail.com> Tad McClellan <tadmc@augustmail.com> writes:

>bill <please_post@nomail.edu> wrote:
>> 
>> Something like this burned me really bad once:

>That can happen when you don't carefully read the documentation
>for the features that you use.

I don't think one could blame users from assuming that 2+2 is going
to evaluate to 4, no matter how clearly the documentations stated

  Note that perl always evaluates 2+2 to 5.

The idea that the loop variable somehow channels through to the
array it is looping over is something I've never seen outside of
Perl.

jill
-- 
To  s&e^n]d  me  m~a}i]l  r%e*m?o\v[e  bit from my a|d)d:r{e:s]s.



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

Date: Fri, 28 May 2004 14:41:15 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: On "for (@foo)"
Message-Id: <c97j2b$7gu$1@wisteria.csv.warwick.ac.uk>


Quoth bill <please_post@nomail.edu>:
> In <c966vt$bkc$1@wisteria.csv.warwick.ac.uk> Ben Morrow <usenet@morrow.me.uk> writes:
> 
> 
> >Quoth bill <please_post@nomail.edu>:
> >> Surprisingly, to me at least, this doesn't produce any errors:
> >> 
> >>   for my $y (1..3) {
> >>     $y = 0;
> >>   }
> >> 
> >> Perl doesn't see the above as analogous to
> >> 
> >>   1 = 0;  # triggers "Can't modify constant item" error
> 
> >No: an array element is an lvalue, and modifiable.
> 
> Ah, yes.  Somehow I thought that '..' returned a list.  Come to
> think of it, does anything in Perl *ever* return a list?

Hang on, no, I misread your code... my brane read it as

for my $y (@x) {

 . Hmmm; I'm puzzled too :). I think I'd call this a perl bug, especially
as 

for my $y (1, 2, 3) {

fails...

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 convinces them that their institutions are not based 
on the strictest morality.  [Samuel Butler, paraphrased]       ben@morrow.me.uk


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

Date: Fri, 28 May 2004 14:42:27 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: On "for (@foo)"
Message-Id: <c97j4j$7gu$2@wisteria.csv.warwick.ac.uk>


Quoth anno4000@lublin.zrz.tu-berlin.de (Anno Siegel):
> Ben Morrow  <usenet@morrow.me.uk> wrote in comp.lang.perl.misc:
> > 
> > Quoth "Andrew Palmer" <atp5470 at fsu.edu>:
> > > > OK, now, in an expression like this
> > > >
> > > >   for my $x (@X) {
> > > >     # etc.
> > > >   }
> > > >
> > > > I assume that Perl keeps track of the index on @X correponding to
> > > > the current element.  Is there a way to access this "current index"
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > from within a Perl program?
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > for my $i (0..$#X) {
> >     $X[$i] = 0;
> > }
> 
>     $_ = 0 for @X;

The OP was asking about more complex loops than the example given... :)

Ben

-- 
'Deserve [death]? I daresay he did. Many live that deserve death. And some die
that deserve life. Can you give it to them? Then do not be too eager to deal
out death in judgement. For even the very wise cannot see all ends.'
                                                               ben@morrow.me.uk


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

Date: Fri, 28 May 2004 14:43:14 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: On "for (@foo)"
Message-Id: <c97j62$7gu$3@wisteria.csv.warwick.ac.uk>


Quoth J Krugman <jkrugman345@yahbitoo.com>:
> In <slrncbedv7.gld.tadmc@magna.augustmail.com> Tad McClellan <tadmc@augustmail.com> writes:
> 
> >bill <please_post@nomail.edu> wrote:
> >> 
> >> Something like this burned me really bad once:
> 
> >That can happen when you don't carefully read the documentation
> >for the features that you use.
> 
> I don't think one could blame users from assuming that 2+2 is going
> to evaluate to 4, no matter how clearly the documentations stated
> 
>   Note that perl always evaluates 2+2 to 5.
> 
> The idea that the loop variable somehow channels through to the
> array it is looping over is something I've never seen outside of
> Perl.

It's incredibly useful, though, which is why it's there :)

Ben

-- 
               We do not stop playing because we grow old; 
                  we grow old because we stop playing.
                            ben@morrow.me.uk


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

Date: Fri, 28 May 2004 15:07:53 +0000 (UTC)
From: "David H. Adler" <dha@panix2.panix.com>
Subject: Re: On "for (@foo)"
Message-Id: <slrncbele9.3nr.dha@panix2.panix.com>

On 2004-05-28, Ben Morrow <usenet@morrow.me.uk> wrote:

> You never need C-style loops:
>
> for my $i (0..$#X) {
>     $X[$i] = 0;
> }

"Never"?

How about:

  for ($i = 20; $i > 0; $i--) {
      do_stuff_with($i);
  }

(and, although I'm sure someone will come up with a way of avoiding the
c-style loop there, I'm not sure it'll be more readable)

On the other hand, I haven't finished my first coffee yet, so maybe I'm
missing something obvious.

dha
-- 
David H. Adler - <dha@panix.com> - http://www.panix.com/~dha/
Your question doesn't make any sense. You might as well ask whether
it is possible to grow vegetables from a painting, without becoming
Wednesday first.       - Abigail, c.l.p.misc


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

Date: Fri, 28 May 2004 11:28:47 -0400
From: Paul Lalli <ittyspam@yahoo.com>
Subject: Re: On "for (@foo)"
Message-Id: <20040528112746.N18263@dishwasher.cs.rpi.edu>

On Fri, 28 May 2004, David H. Adler wrote:

> On 2004-05-28, Ben Morrow <usenet@morrow.me.uk> wrote:
>
> > You never need C-style loops:
> >
> > for my $i (0..$#X) {
> >     $X[$i] = 0;
> > }
>
> "Never"?
>
> How about:
>
>   for ($i = 20; $i > 0; $i--) {
>       do_stuff_with($i);
>   }
>

for my $i (reverse (1..20)){
	do_stuff_with($i);
}

> (and, although I'm sure someone will come up with a way of avoiding the
> c-style loop there, I'm not sure it'll be more readable)


I disagree. <shrug>


Paul Lalli


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

Date: Fri, 28 May 2004 10:24:10 -0500
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: On "for (@foo)"
Message-Id: <slrncbemcq.hp4.tadmc@magna.augustmail.com>

J Krugman <jkrugman345@yahbitoo.com> wrote:
> In <slrncbedv7.gld.tadmc@magna.augustmail.com> Tad McClellan <tadmc@augustmail.com> writes:
> 
>>bill <please_post@nomail.edu> wrote:
>>> 
>>> Something like this burned me really bad once:
> 
>>That can happen when you don't carefully read the documentation
>>for the features that you use.
> 
> I don't think one could blame users from assuming that 2+2 is going
> to evaluate to 4, no matter how clearly the documentations stated
> 
>   Note that perl always evaluates 2+2 to 5.


If he had followed the advice I gave, he would not have been burned.
(which is why I followed up with it in the first place.)

If you are satisfied with "assuming" then you accept the possibility
of being burned.

If you don't want to accept that possibility, then look it up instead
of guessing from empirical observations.




Now, nobody reads all of the docs.

It is completely sensible to assume that foreach works like loops
in other languages and use it without reading its docs.

But when it appears to behave differently, the first thing to do
is look it up (ie. attempt to verify your assumption), not ask 
hundreds of others to look it up for you.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


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

Date: 28 May 2004 17:27:54 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: On "for (@foo)"
Message-Id: <u9fz9kwm7p.fsf@wcl-l.bham.ac.uk>

Paul Lalli <ittyspam@yahoo.com> writes:

> On Fri, 28 May 2004, David H. Adler wrote:
> 
> > On 2004-05-28, Ben Morrow <usenet@morrow.me.uk> wrote:
> >
> > > You never need C-style loops:
> >
> > How about:
> >
> >   for ($i = 20; $i > 0; $i--) {
> >       do_stuff_with($i);
> >   }
> >
> 
> for my $i (reverse (1..20)){
> 	do_stuff_with($i);
> }

This, of course, assumes that:

 * 20 is a small number[1] because the optomisation of .. in for()
   does not cope with reverse(). 

 * do_stuff_with() does not alter its arguments. If it did I'd still
   not use a C-style for, I'd use a while().

[1] er, 20 _is_ a small number but you know what I mean.  :-)

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


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

Date: 28 May 2004 17:32:06 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: On "for (@foo)"
Message-Id: <u9brk8wm0p.fsf@wcl-l.bham.ac.uk>

Ben Morrow <usenet@morrow.me.uk> writes:

> Quoth bill <please_post@nomail.edu>:

> > Surprisingly, to me at least, this doesn't produce any errors:
> > 
> >   for my $y (1..3) {
> >     $y = 0;
> >   }
> > 
> > Perl doesn't see the above as analogous to
> > 
> >   1 = 0;  # triggers "Can't modify constant item" error
> 
> No: an array element is an lvalue, and modifiable.

There is no array.  1..3 in the above is a list.  Or rather it would
be a list if the .. operator was not handled as a special case in for().

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


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

Date: Fri, 28 May 2004 16:39:48 +0000 (UTC)
From: J Krugman <jkrugman345@yahbitoo.com>
Subject: Re: On "for (@foo)"
Message-Id: <c97q0k$mbc$1@reader2.panix.com>

In <slrncbemcq.hp4.tadmc@magna.augustmail.com> Tad McClellan <tadmc@augustmail.com> writes:

>But when it appears to behave differently, the first thing to do
>is look it up (ie. attempt to verify your assumption), not ask 
>hundreds of others to look it up for you.

In fairness to the OP, as far as we know he never asked anyone to
"look it up for him", "it" being the case where he got burned.

jill
-- 
To  s&e^n]d  me  m~a}i]l  r%e*m?o\v[e  bit from my a|d)d:r{e:s]s.



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

Date: 28 May 2004 17:41:55 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: On "for (@foo)"
Message-Id: <u97juwwlkc.fsf@wcl-l.bham.ac.uk>

bill <please_post@nomail.edu> writes:

> In <c966vt$bkc$1@wisteria.csv.warwick.ac.uk> Ben Morrow <usenet@morrow.me.uk> writes:
> 
> >Quoth bill <please_post@nomail.edu>:
> >> Surprisingly, to me at least, this doesn't produce any errors:
> >> 
> >>   for my $y (1..3) {
> >>     $y = 0;
> >>   }
> >> 
> >> Perl doesn't see the above as analogous to
> >> 
> >>   1 = 0;  # triggers "Can't modify constant item" error
> 
> >No: an array element is an lvalue, and modifiable.
> 
> Ah, yes.  Somehow I thought that '..' returned a list.

If it were not for the special case then it would.

To remove the special case wrap it in do{}

  for my $y ( do { 1..3 } ) {
     $y = 0;
  }

You still don't get an error, but now you don't get an error for a
different reason.

The fact is that the elements of a list that results from a
compulation are usually modifiyable.  You can't say:

  ( something() )[0] = 666;

But the reson you can't say that is because there's a compile time
check "Can't modify list slice".  If it wasn't for the compile time
check there'd be no run-time error.
 
-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


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

Date: Fri, 28 May 2004 16:48:06 +0000 (UTC)
From: bill <please_post@nomail.edu>
Subject: Re: On "for (@foo)"
Message-Id: <c97qg6$mgf$1@reader2.panix.com>

In <u9brk8wm0p.fsf@wcl-l.bham.ac.uk> Brian McCauley <nobull@mail.com> writes:

>Ben Morrow <usenet@morrow.me.uk> writes:

>> Quoth bill <please_post@nomail.edu>:

>> > Surprisingly, to me at least, this doesn't produce any errors:
>> > 
>> >   for my $y (1..3) {
>> >     $y = 0;
>> >   }
>> > 
>> > Perl doesn't see the above as analogous to
>> > 
>> >   1 = 0;  # triggers "Can't modify constant item" error
>> 
>> No: an array element is an lvalue, and modifiable.

>There is no array.  1..3 in the above is a list.  Or rather it would
>be a list if the .. operator was not handled as a special case in for().

Now I'm mega-confused.  From perlop: 

       Range Operators

       Binary ".." is the range operator, which is really two
       different operators depending on the context.  In list
       context, it returns an array of values counting (up by
                           ^^^^^^^^
       ones) from the left value to the right value.

I thought this is what Ben was alluding to.  At any rate, as I
wrote in another post, other operators that perlop describe as
returning lists behave just like .. with regards to their return
value's modifiability via the loop variable (i.e. no error triggered).

	-bill



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

Date: Fri, 28 May 2004 16:53:18 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: On "for (@foo)"
Message-Id: <c97qpt$cup$1@wisteria.csv.warwick.ac.uk>


Quoth bill <please_post@nomail.edu>:
> In <u9brk8wm0p.fsf@wcl-l.bham.ac.uk> Brian McCauley <nobull@mail.com> writes:
> 
> >Ben Morrow <usenet@morrow.me.uk> writes:
> 
> >> Quoth bill <please_post@nomail.edu>:
> 
> >> > Surprisingly, to me at least, this doesn't produce any errors:
> >> > 
> >> >   for my $y (1..3) {
> >> >     $y = 0;
> >> >   }
> >> > 
> >> > Perl doesn't see the above as analogous to
> >> > 
> >> >   1 = 0;  # triggers "Can't modify constant item" error
> >> 
> >> No: an array element is an lvalue, and modifiable.
> 
> >There is no array.  1..3 in the above is a list.  Or rather it would
> >be a list if the .. operator was not handled as a special case in for().
> 
> Now I'm mega-confused.  From perlop: 
> 
>        Range Operators
> 
>        Binary ".." is the range operator, which is really two
>        different operators depending on the context.  In list
>        context, it returns an array of values counting (up by
>                            ^^^^^^^^
>        ones) from the left value to the right value.
> 
> I thought this is what Ben was alluding to.

As I said, I was wrong... this perldoc is also wrong. .. returns a list
in list context except (apparantly) in a for loop where it is optimized
away to simply incrementing the variable each time.

> At any rate, as I
> wrote in another post, other operators that perlop describe as
> returning lists behave just like .. with regards to their return
> value's modifiability via the loop variable (i.e. no error triggered).

I think Brian has explained this (his understanding is at any rate
better than mine): the result of a calculation performed on constant
terms is not itself constant. It's as though the result were explicitly
assigned to a temporary variable.

Ben

-- 
                Outside of a dog, a book is a man's best friend.
                Inside of a dog, it's too dark to read.
ben@morrow.me.uk                                                  Groucho Marx


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

Date: Fri, 28 May 2004 13:16:40 -0400
From: Paul Lalli <ittyspam@yahoo.com>
Subject: Re: On "for (@foo)"
Message-Id: <20040528131511.E18263@dishwasher.cs.rpi.edu>

On Fri, 28 May 2004, Brian McCauley wrote:

> > for my $i (reverse (1..20)){
> > 	do_stuff_with($i);
> > }
>
> This, of course, assumes that:
>
>  * 20 is a small number[1] because the optomisation of .. in for()
>    does not cope with reverse().
>
>  * do_stuff_with() does not alter its arguments. If it did I'd still
>    not use a C-style for, I'd use a while().
>
> [1] er, 20 _is_ a small number but you know what I mean.  :-)

I never claimed that this was a *good* way of doing it.  I merely
commented that for ($i=20; $i>0; $i--) {} could be written without using
the C-style for loop.

Paul Lalli


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

Date: 28 May 2004 18:24:59 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: On "for (@foo)"
Message-Id: <u9y8ncv504.fsf@wcl-l.bham.ac.uk>

Paul Lalli <ittyspam@yahoo.com> writes:

> On Fri, 28 May 2004, Brian McCauley wrote:
> 
> > > for my $i (reverse (1..20)){
> > > 	do_stuff_with($i);
> > > }
> >
> > This assumes that 20 is a small number because the optomisation of
> > .. in for() does not cope with reverse().
> 
> I never claimed that this was a *good* way of doing it.  I merely
> commented that for ($i=20; $i>0; $i--) {} could be written without using
> the C-style for loop.

Well I do claim that reverse(1..20) is a good way of doing it.  I just
think it is worth warning people that it's only good for small numbers
of interations.

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


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

Date: 28 May 2004 18:30:09 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: On "for (@foo)"
Message-Id: <u9u0y0v4ri.fsf@wcl-l.bham.ac.uk>

bill <please_post@nomail.edu> writes:

>  From perlop: 
> 
>        Range Operators
> 
>        Binary ".." is the range operator, which is really two
>        different operators depending on the context.  In list
>        context, it returns an array of values counting (up by
>                            ^^^^^^^^

No need to report this bug, it appears to have alredy been fixed.

http://search.cpan.org/~nwclark/perl-5.8.4/pod/perlop.pod#Range_Operators

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


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

Date: Fri, 28 May 2004 10:40:49 -0700
From: Jim Gibson <jgibson@mail.arc.nasa.gov>
Subject: Re: On "for (@foo)"
Message-Id: <280520041040496268%jgibson@mail.arc.nasa.gov>

In article <c96vkq$kkk$1@wisteria.csv.warwick.ac.uk>, Ben Morrow
<usenet@morrow.me.uk> wrote:

> Quoth "Andrew Palmer" <atp5470 at fsu.edu>:
> > > OK, now, in an expression like this
> > >
> > >   for my $x (@X) {
> > >     # etc.
> > >   }
> > >
> > > I assume that Perl keeps track of the index on @X correponding to
> > > the current element.  Is there a way to access this "current index"
> > > from within a Perl program?
> > 
> > I think the only way to do what you want is like
> > 
> > for(my $i=0;$i<$#X;++$i)
> > {
> >   $X[$i]=0;
> > }
> 
> You never need C-style loops:
> 
> for my $i (0..$#X) {
>     $X[$i] = 0;
> }
> 
> Ben

You do if you want to skip some elements:

Jim 53% cat loops.pl
#!/usr/local/bin/perl
use strict;
use warnings;

my @array = ( 0..4 );

print "C-style:\n";
for( my $i = 0; $i < @array; $i++ ) {
  print "$i. $array[$i]\n";
  $i++ if $i == 2;
}

print "Perlish:\n";
for my $i ( 0 .. $#array ) {
  print "$i. $array[$i]\n";
  $i++ if $i == 2;
}
Jim 54% ./loops.pl
C-style:
0. 0
1. 1
2. 2
4. 4
Perlish:
0. 0
1. 1
2. 2
3. 3
4. 4
Jim 55%

Couldn't the above behavior be considered a bug in Perl? At the very
least, it would be nice if the run-time system warned of trying to
modify a read-only value $i in the 'for my $i ( 0 .. $#array )' loop.


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

Date: 27 May 2004 12:20:24 -0400
From: Uri Guttman <uri.guttman@fmr.com>
Subject: Re: Remove first letter of each string in array
Message-Id: <li7jux9707.fsf@localhost.localdomain>

>>>>> "KH" == Kien Ha <kha@rogers.com> writes:

  KH> Julia deSilva wrote:
  >> Hi there all.
  >> my @array = qw(1this 2is 3a 4new 5message);
  >> for (my $x=0;$x<@array;$x++){
  >> $array[$x] = substr($array[$x],1,length($array[$x]))
  >> }
  >> foreach (@array){print"$_\n";};
  >> This does indeed remove the first letter of each string in this
  >> array, but
  >> is there a better way ! ?
  >> 

  KH> Shorter and more Perlish:
  KH>    $_ = substr $_, 1 for @array;
  KH> or
  KH>    @array = map { substr $_, 1 } @array;

and even faster and simpler (IMO):
substr( $_, 0, 1, '' ) for @array;

uri


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

Date: 28 May 2004 18:19:11 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: Remove first letter of each string in array
Message-Id: <u93c5kwju8.fsf@wcl-l.bham.ac.uk>

Uri Guttman <uri.guttman@fmr.com> writes:

> >>>>> "BM" == Brian McCauley <nobull@mail.com> writes:
> 
>   BM> However, it's not so fast...
> 
> you chose a bad data set for this.

!?

> my @data = ( 'a' x 1000 ) x 1000 ;
> 
> Benchmark: running map, substr1, substr2, substr3 for at least 2 CPU seconds...
>        map:  2 wallclock secs ( 2.22 usr +  0.00 sys =  2.22 CPU) @ 127.48/s (n=283)
>    substr1:  2 wallclock secs ( 2.18 usr +  0.00 sys =  2.18 CPU) @ 293.12/s (n=639)
>    substr2:  2 wallclock secs ( 2.07 usr +  0.00 sys =  2.07 CPU) @ 347.34/s (n=719)
>    substr3:  2 wallclock secs ( 2.05 usr +  0.00 sys =  2.05 CPU) @ 317.07/s (n=650)
> 
> now 4 arg substr is much faster.
> 
> this is why benchmarking is an art unto itself. it is so easy to get
> results that support wrong conclusions.

Indeed - in this case you've chosen the conclusion you want and
written a benchmark to support it.  This ensures the conclusion that
will be supported is the "right" one.

Removing the first character from an array of string is typically
something one does to plaintext.  And plaintext is typically ~70-120
characters wide.

Without knowing the OP's real problem domain it's just as likely that
it is you who've chosen a bad data set that supports the wrong
conclusion. :-)

But then again I'm not even able to reproduce your results...

use Benchmark;

my %tests;
for ( my $i = 1; $i <= 1024 ; $i*=2 ) {
    my @data = ('X' x $i) x 1000;
    $tests{sprintf('4arg%4d',$i)} = sub {
	my @array = @data;
	substr $_, 0, 1, '' for @array;
    };
    $tests{sprintf('copy%4d',$i)} = sub {
	my @array = @data;
	$_ = substr $_, 1 for @array;
    };
}

timethese -2 => \%tests;
__END__
Benchmark: running 4arg   1, 4arg   2, 4arg   4, 4arg   8, 4arg  16, 4arg  32, 4arg  64, 4arg 128, 4arg 256, 4arg 512, 4arg1024, copy   1, copy   2, copy   4, copy   8, copy  16, copy  32, copy  64, copy 128, copy 256, copy 512, copy1024, each for at least 2 CPU seconds...
  4arg   1:  2 wallclock secs ( 2.19 usr +  0.00 sys =  2.19 CPU) @ 642.01/s (n=1406)
  4arg   2:  2 wallclock secs ( 2.02 usr +  0.00 sys =  2.02 CPU) @ 642.57/s (n=1298)
  4arg   4:  2 wallclock secs ( 2.19 usr +  0.00 sys =  2.19 CPU) @ 642.01/s (n=1406)
  4arg   8:  2 wallclock secs ( 2.16 usr +  0.00 sys =  2.16 CPU) @ 592.13/s (n=1279)
  4arg  16:  2 wallclock secs ( 2.16 usr +  0.00 sys =  2.16 CPU) @ 592.13/s (n=1279)
  4arg  32:  3 wallclock secs ( 2.13 usr +  0.00 sys =  2.13 CPU) @ 572.77/s (n=1220)
  4arg  64:  2 wallclock secs ( 2.16 usr +  0.00 sys =  2.16 CPU) @ 518.06/s (n=1119)
  4arg 128:  2 wallclock secs ( 2.03 usr +  0.00 sys =  2.03 CPU) @ 354.19/s (n=719)
  4arg 256:  2 wallclock secs ( 2.06 usr +  0.00 sys =  2.06 CPU) @ 229.13/s (n=472)
  4arg 512:  2 wallclock secs ( 2.02 usr +  0.09 sys =  2.11 CPU) @ 135.55/s (n=286)
  4arg1024:  2 wallclock secs ( 1.74 usr +  0.27 sys =  2.01 CPU) @ 77.61/s (n=156)
  copy   1:  2 wallclock secs ( 2.06 usr +  0.00 sys =  2.06 CPU) @ 702.91/s (n=1448)
  copy   2:  2 wallclock secs ( 2.06 usr +  0.00 sys =  2.06 CPU) @ 702.91/s (n=1448)
  copy   4:  2 wallclock secs ( 2.07 usr +  0.00 sys =  2.07 CPU) @ 699.52/s (n=1448)
  copy   8:  3 wallclock secs ( 2.01 usr +  0.00 sys =  2.01 CPU) @ 645.77/s (n=1298)
  copy  16:  2 wallclock secs ( 2.06 usr +  0.03 sys =  2.09 CPU) @ 606.70/s (n=1268)
  copy  32:  2 wallclock secs ( 2.15 usr +  0.00 sys =  2.15 CPU) @ 594.88/s (n=1279)
  copy  64:  2 wallclock secs ( 2.08 usr +  0.00 sys =  2.08 CPU) @ 535.10/s (n=1113)
  copy 128:  2 wallclock secs ( 2.12 usr +  0.00 sys =  2.12 CPU) @ 339.15/s (n=719)
  copy 256:  3 wallclock secs ( 2.09 usr +  0.00 sys =  2.09 CPU) @ 207.66/s (n=434)
  copy 512:  2 wallclock secs ( 2.11 usr +  0.00 sys =  2.11 CPU) @ 135.55/s (n=286)
  copy1024:  2 wallclock secs ( 2.11 usr +  0.00 sys =  2.11 CPU) @ 79.15/s (n=167)

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


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

Date: Fri, 28 May 2004 14:51:21 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Unwanted double-interpolation in string passed to backticks
Message-Id: <c97jl9$7gu$4@wisteria.csv.warwick.ac.uk>


Quoth "Henry Law" <news@lawshouse.org>:
> I think I've done my homework on this, including "How can I call
> backticks without shell processing?" in perlfaq8, and a Groups search
> on "perl shell escape characters backticks" but I'm none the wiser;
> pointers would be welcome.
> 
> Here's a test program:
> -----------------------
> #! /usr/bin/perl
> 
> use strict;
> use warnings;
> 
> print "Enter filename:";
> my $filename = <STDIN>;
> chomp $filename;
> 
> my $ret = `ls -m $filename`;
> 
> print "Returned value:$ret\n";
> -----------------------
> 
> The problem comes when the file name that is entered contains the "$"
> character, which in my case it often does.  In the test directory
> there is a file called "test" and another called "$test".   If I run
> the program above and enter "test" the result is as expected, thus:
> 
> 	$ ./test
> 	Enter filename:test
> 	Returned value:test
> 
> But if I enter the name of the "$test" file, the variable $filename is
> interpolated a second time,

By the shell, not Perl.

> and since there is no "$test" variable
> within the program it comes out as null, thus:

You say you've read the faq answer; why didn't you try it?

my $ret = do {
    open my $LS, '-|', ls => -m => $filename
        or die "can't fork ls: $!";
    local $/;
    <$LS>;
};

As a separate issue, is possible to define some sort of DESTROY method
to call die automatically if the implicit close at end of scope fails?
It would make this sort of code both safe and clean.

Ben

-- 
   If you put all the prophets,   |   You'd have so much more reason
   Mystics and saints             |   Than ever was born
   In one room together,          |   Out of all of the conflicts of time.
ben@morrow.me.uk                                    The Levellers, 'Believers'


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

Date: Fri, 28 May 2004 17:16:37 +0100
From: Henry Law <lawshouse.public@btconnect.com>
Subject: Re: Unwanted double-interpolation in string passed to backticks
Message-Id: <e6peb0d6hb7hemootv562c0o60pm10buih@4ax.com>

On Fri, 28 May 2004 14:51:21 +0000 (UTC), Ben Morrow
<usenet@morrow.me.uk> wrote:

>You say you've read the faq answer; why didn't you try it?

I did; and of course it worked.   But forking sounded like too much
heavy-duty workload for something so trivial, and which I have to do
many times within this particular program, so I ended up with my
current solution, which is the sub which excapes $'s and then executes
the command within backticks.

Henry Law       <><     Manchester, England 


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

Date: Fri, 28 May 2004 16:20:39 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Unwanted double-interpolation in string passed to backticks
Message-Id: <c97osn$c44$1@wisteria.csv.warwick.ac.uk>


Quoth "Henry Law" <news@lawshouse.org>:
> On Fri, 28 May 2004 14:51:21 +0000 (UTC), Ben Morrow
> <usenet@morrow.me.uk> wrote:
> 
> >You say you've read the faq answer; why didn't you try it?
> 
> I did; and of course it worked.   But forking sounded like too much
> heavy-duty workload for something so trivial, and which I have to do
> many times within this particular program, so I ended up with my
> current solution, which is the sub which excapes $'s and then executes
> the command within backticks.

Backticks perform a fork. If you want to execute an external command,
you *have* to fork.

In fact, the open '-|' answer is lighter, as backticks will fork twice:
once for the shell and again for ls. Avoiding the shell will remove a
completely extraneous process.

Always benchmark before deciding something is 'too heavy-duty'.

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: 28 May 2004 16:29:00 GMT
From: ctcgag@hotmail.com
Subject: Re: Unwanted double-interpolation in string passed to backticks
Message-Id: <20040528122900.965$tH@newsreader.com>

"Henry Law" <news@lawshouse.org> wrote:
> On Fri, 28 May 2004 14:51:21 +0000 (UTC), Ben Morrow
> <usenet@morrow.me.uk> wrote:
>
> >You say you've read the faq answer; why didn't you try it?
>
> I did; and of course it worked.   But forking sounded like too much
> heavy-duty workload for something so trivial,

Do you have any idea how much work qx{} does behind the scenes?

> and which I have to do
> many times within this particular program, so I ended up with my
> current solution, which is the sub which excapes $'s and then executes
> the command within backticks.

Why not use glob?  That is probably lighter (or at least as light) than any
shell-based method, and much easier to figure out the escaping for.

Xho

-- 
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service                        $9.95/Month 30GB


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

Date: 28 May 2004 09:23:51 -0700
From: google@milbaugh.com (GreenLight)
Subject: Re: Using Cookies With Perl
Message-Id: <c4b60ce1.0405280823.7c8b299a@posting.google.com>

"David K. Wall" <dwall@fastmail.fm> wrote in message news:<Xns94F6859D48FF8dkwwashere@216.168.3.30>...
> GreenLight <google@milbaugh.com> wrote:
> 
> > That is an interesting article.
> > 
> > I have found, however, that the File::Cache module is not
> > available on Win32 with ActiveState Perl 5.6x.
> > 
> > Has anyone recoded Randall's cookie management technique to
> > account for this shortcoming in AS Perl / Win32?
> 
> So just install File::Cache from CPAN, or better yet, install 
> Cache::Cache and modify the code appropriately.

Yes, I used Cache::FileCache instead of File::Cache; it seemed to be a
drop-in replacement, but I could be wrong 8^)


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

Date: 28 May 2004 08:06:30 -0700
From: constants@mix-net.net (Mark Constant)
Subject: Re: Why is this upload script not working
Message-Id: <ce43fdea.0405280706.b9970a9@posting.google.com>

Well I listened to some of the suggestions and it still doesn't work.
I tried Ben's way but it still acts like it is uploading the file and
never does. Here is what I have now. Now I am at work and don't have
linux so I had to change the way the slashes. Also Taint mode doesn't
really work because it says it is too late for Taint mode (Guess it is
because I am running in this in Windows). I noticed that when the HTML
displays it says that my destination is ..\htdocs\quickbooks$file. I
want it to be ..\htdocs\quickbooks\$file where $file of course is
replaced with the actually file name. Also should I be stripping the
forward slashes out of the file name?

#!c:\perl\bin\perl -T
use strict;
use warnings;
use CGI;

my $q = CGI->new();
my $file = $q->param('upfile');
my $dir = '..\htdocs\quickbooks';
print $q->header, $q->start_html('Uploading File');
print $q->h1('Upload Results');

if(!$file){
 print "Nothing Uploaded\n";
} else {
 print "Filename: $file<br />\n";
 print "Destination: $dir\$file<br />\n";
 my $ctype = $q->uploadInfo($file)->{'Content-Type'};
 print "MIME Type: $ctype<br />\n";
 open(OUTFILE, ">$dir\$file") or dienice("Can't upload file: $! \n");
 binmode(OUTFILE);

 while (my $bytesread = read($file, my $buffer, 1024)) {
   print OUTFILE $buffer;
 }

 close(OUTFILE);
 print "File saved\n";
}

$q->end_html;

sub dienice {
 my($msg) = @_;
 print "<h2>Error</h2>\n";
 print $msg;
 exit;

}


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

Date: Fri, 28 May 2004 15:29:21 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Why is this upload script not working
Message-Id: <c97lsh$9tr$1@wisteria.csv.warwick.ac.uk>


Quoth constants@mix-net.net (Mark Constant):
> Well I listened to some of the suggestions and it still doesn't work.
> I tried Ben's way but it still acts like it is uploading the file and
> never does. Here is what I have now. Now I am at work and don't have
> linux so I had to change the way the slashes.

No you don't. Real slashes work just as well on Win32.

> Also Taint mode doesn't
> really work because it says it is too late for Taint mode (Guess it is
> because I am running in this in Windows).

No, it's because it's too late... I would create an association from
 .plt to 'perl -T "%1"' (or whatever the syntax is) in addition to the
one from .pl to 'perl "%1"'; then you can make scripts taint by changing
the extn. Leave the -T on the #! line: that way you'll get an error if
it should run without tainting by accident.

> I noticed that when the HTML
> displays it says that my destination is ..\htdocs\quickbooks$file. I
> want it to be ..\htdocs\quickbooks\$file where $file of course is
> replaced with the actually file name. Also should I be stripping the
> forward slashes out of the file name?

Yes. You should (in fact must, under taint mode) check that the name is
what you expect. Read perldoc perlsec. Something like

$file =~ /^([\w.-]+)$/ or dienice "Invalid filename: $file";
my $filename = $1;

is safe; you may want to restrict the name more or less depending on
your circumstances. You *definitely* don't want to allow anything
windows treats as 'special': at least / \ :, there may be more. Note
that I assign the untainted name to a new variable, as $file is special
(it's a FH as well as a string) and mustn't be replaced.

> #!c:\perl\bin\perl -T
> use strict;
> use warnings;
> use CGI;
> 
> my $q = CGI->new();
> my $file = $q->param('upfile');
> my $dir = '..\htdocs\quickbooks';
> print $q->header, $q->start_html('Uploading File');
> print $q->h1('Upload Results');
> 
> if(!$file){
>  print "Nothing Uploaded\n";
> } else {
>  print "Filename: $file<br />\n";
>  print "Destination: $dir\$file<br />\n";

You are double-quoting, so "\$" simply produces a literal '$'. Try

print "Destination: $dir\\$file<br/>\n";

or, better,

print "Destination: $dir/$file<br/>\n";

or, better still,

use File::Spec::Functions qw/catfile splitdir/;
my $path = catfile splitdir($dir), $file;
print "Destination: $path<br/>\n";

>  my $ctype = $q->uploadInfo($file)->{'Content-Type'};
>  print "MIME Type: $ctype<br />\n";
>  open(OUTFILE, ">$dir\$file") or dienice("Can't upload file: $! \n");

The same applies here. It is also better to use 3-arg open, and lexical
FHs:

open my $OUT, '>', $path or dienice ...;

or even

open my $OUT, '>:raw', $path or dienice...;

which alleviates the need for 'binmode'.

>  binmode(OUTFILE);

You should probably also investigate CGI::Carp, which can make sure that
*all* errors end up properly reported.

Ben

-- 
  The cosmos, at best, is like a rubbish heap scattered at random.
                                                         - Heraclitus
  ben@morrow.me.uk


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

Date: Fri, 28 May 2004 13:28:50 -0400
From: Richard Morse <remorse@partners.org>
Subject: Re: Why is this upload script not working
Message-Id: <remorse-80E5D8.13285028052004@plato.harvard.edu>

In article <ce43fdea.0405271651.17bb245@posting.google.com>,
 constants@mix-net.net (Mark Constant) wrote:

> I looked at a couple of scripts on how to upload a file and came up
> with the script below. Now the script acts like it uploaded the file
> by not giving errors but when I check the directory no file is there.
> The script runs from /cgi-bin/ and the quickbooks directory is chmod
> 755. What I am trying to do is upload a quickbooks file that is 50mbs.
> Here are the most important parts. I only left out how I got the time
> and date.
> 
> #!/usr/bin/perl
> use CGI;
> $q = new CGI;
> $file = $q->param("upfile");
[snip]
> sub dienice {
> 	my($msg) = @_;
> 	print "<h2>Error</h2>\n";
> 	print $msg;
> 	exit;
> 
> }

While you're figuring out how to make this work properly, I would 
suggest using CGI::Carp to get the errors -- something like:

#!/usr/bin/perl
use strict;
use warnings;

use CGI;
use CGI::Carp qw/fatalsToBrowser/;

my $q = new CGI;
#blah blah blah
die("didn't work because of $!"); # will send errors to the browser...

HTH,
Ricky

-- 
Pukku


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

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


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