[comp.lang.perl] an easier way?

cwilson@NISC.SRI.COM (Chan Wilson [Animal]) (11/03/90)

I've got a script that distills mailserver stats down to a simple
access count.  I've got the following snippet of code:

    $file{(reverse(split(/\//,$path)))[0]}++ if ($part =~ /A1\//);

where $path is "/home/fs3/mserv/HELP" or somesuch.  

I'm curious - is there a better way to do this?  I tried a number
of regexps, but couldn't come up with one, so had fun creating
the above one liner.  :)

--Chan
Chan Wilson                                  Chief Hard-Question Answer Person
SRI Intl. Network Information Systems Center
333 Ravenswood Ave., EJ287			Internet: cwilson@nisc.sri.com
Menlo Park, CA., 94025				Phone: (415)859-4492
    "If I want to be a surfer this month, I bloody well will be."

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/03/90)

In article <23043@fs2.NISC.SRI.COM> cwilson@NISC.SRI.COM (Chan Wilson [Animal]) writes:
: I've got a script that distills mailserver stats down to a simple
: access count.  I've got the following snippet of code:
: 
:     $file{(reverse(split(/\//,$path)))[0]}++ if ($part =~ /A1\//);
: 
: where $path is "/home/fs3/mserv/HELP" or somesuch.  
: 
: I'm curious - is there a better way to do this?  I tried a number
: of regexps, but couldn't come up with one, so had fun creating
: the above one liner.  :)

That's pretty snazzy.  You could avoid the split with a temp array:

	$file{@path = split(m#/#,$path), pop @path}++ if $part =~ m#A1/#;

But it's not as beautificial as the reverse.

To pull the last component of a pathname off with a regular expression,
one can say things like:

	($file) = $path =~ m#.*/(.*)#;
	($file = $path) =~ s#.*/##;

These both use a temp variable, of course, and don't just slip right
into your expression easily, though you can use the comma operator:

	$file{($file) = $path =~ m#.*/(.*)#, $file}++ if $part =~ m#A1/#;
	$file{($file = $path) =~ s#.*/##, $file}++ if $part =~ m#A1/#;

For the first one, you can get by without a temp var, which after all is
only being used in a list to supply an array context, which can be provided
other ways:
	
	$file{join('',$path =~ m#.*/(.*)#)}++ if $part =~ m#A1/#;
    or
	$file{($path =~ m#.*/(.*)#)[0]}++ if $part =~ m#A1/#;

It might be better, however, to simply use rindex:

	$file{substr($path,rindex($path,'/')+1)}++ if $part =~ m#A1/#;

I don't know if any of these are faster than your solution, though.
Perl programming is an *empirical* science.  :-)

Larry

eastick@me.utoronto.ca (Doug Eastick) (11/05/90)

>(Chan Wilson [Animal]) writes:
>:     $file{(reverse(split(/\//,$path)))[0]}++ if ($part =~ /A1\//);

Larry writes:
>	$file{@path = split(m#/#,$path), pop @path}++ if $part =~ m#A1/#;

>	($file) = $path =~ m#.*/(.*)#;
>	($file = $path) =~ s#.*/##;

>	$file{($file) = $path =~ m#.*/(.*)#, $file}++ if $part =~ m#A1/#;
>	$file{($file = $path) =~ s#.*/##, $file}++ if $part =~ m#A1/#;

>	$file{join('',$path =~ m#.*/(.*)#)}++ if $part =~ m#A1/#;
>    or
>	$file{($path =~ m#.*/(.*)#)[0]}++ if $part =~ m#A1/#;

>	$file{substr($path,rindex($path,'/')+1)}++ if $part =~ m#A1/#;

>Larry

Bpbpbpbpbpbpbpbpbpbpb (the sound of shaking one's head back and forth
real fast and your lips slap around).  Amazing stuff.