Re: trailing spaces

[email protected] (James Taylor) Fri, 22 Aug 2003 00:42:44 +0100 (BST)
Newsgroups perl.riscos
Message-ID <[email protected]>
On Thu 21 Aug, Roger Horne wrote:
> 
> On Wed 20 Aug, James Taylor wrote:
> >
> > But, more usefully, the fishing rod is:
> > 
> >     Learning Perl, 3rd edition
> >     http://www.oreilly.com/catalog/lperl3/
> 
> That was the 1st (out of many) Perl book that I bought and
> I found it awful.

Really? I found it clear and easy. I enjoyed the humour too.

> Horses for courses I suppose, but so far as I was
> concerned Programming Perl was immeasurably better. 

Agreed, every serious Perl programmer is lost without
Programming Perl: http://www.oreilly.com/catalog/pperl3/

> The one I use most is, I think, the Perl Cookbook.

Strangely, although I have it, I tend to refer to it only when
I'm completely stumped (ie. rarely). However, I agree that it
is a great book. http://www.oreilly.com/catalog/cookbook/

> A point that I have never seen dealt with is why, in order to
> trim at both ends, the recipe uses
>   $string =~s/^\s+//; 
>   $string =~s/\s+$//;
> rather than say 
>   $string =~s[^\s*(.*?)\s*$][$1];

There's a very good reason for that. The first pair do not require
any backtracking and can execute very quickly. The latter technique
can involve a great deal of backtracking and, in the worst case,
could take a very long time indeed. As a contrived example, run this:

    $string = ' a' . ' ' x 100000 . 'z ';
    print "Starting first trim method\n";
    $string =~ s/^ +//;
    $string =~ s/ +$//;
    print "Finished\n"; # Instantly

    $string = ' a' . ' ' x 100000 . 'z ';
    print "Starting second trim method\n";
    $string =~ s/^ *(.*?) *$/$1/;
    print "Finished\n"; # Six minutes later... zzzzzzz...

I understand the natural desire to express the conceptually atomic
trim operation as a single line. The idiom I sometimes use is:

    s/^ +//, s/ +$// for $string;

Even better, this generalises neatly for more than one string:

    s/^ +//, s/ +$// for $string1, $string2, $string3;
    s/^ +//, s/ +$// for @whole_file_of_lines;


PS. There's rather too much netlag on this mailing list.
When I posted my response to Colin I thought I was the first
but in fact there were four other people ahead of me, and I may
find that this post is redundant for the same reason. Sigh.

-- 
James Taylor, Cheltenham, Gloucestershire, UK.       PGP key: 3FBE1BF9