Forum Moderators: coopster & phranque

Message Too Old, No Replies

Double Variables within my () when defining

         

med267

6:02 am on Jan 25, 2005 (gmt 0)

10+ Year Member



Would someone mind walking me through what this means
between the first parentheses & the use of $0.

my ($d_home, $f_self) = ($0 =~ m#(.+)/([^/]+)$#

I have seen the regex before, but never with the use of $0.

Sincerely,

Jeff

med267

6:17 am on Jan 25, 2005 (gmt 0)

10+ Year Member



okay, I understand this double variable between the first () to mean both variables are being defined at once.
The $0 stands for the name of the currently operating script.

Now I am wondering what (.+) means. Does it mean 'one or more period characters' or 'one or more or any character'?

Nedals

7:22 am on Jan 25, 2005 (gmt 0)

10+ Year Member



.+ is any char one or more times
\.+ is a period (note the escape) one or more times

med267

9:43 pm on Jan 25, 2005 (gmt 0)

10+ Year Member



Thank You.

wruppert

7:18 pm on Jan 28, 2005 (gmt 0)

10+ Year Member



As mentioned, $0 is the full path and name of the running program. The code splits it into the path ($d_home) and program name ($f_self).

The overall structure is a list assignment similar in concept to:


my ($a, $b) = (1, 2);

which assigns 1 to $a and 2 to $b.

The right side of the assignment uses the match to generate a list of two values to be assigned to the variables of the left side. Here is how to think about the match:


$0 =~ m#(path stuff)/(program name stuff)$#

The #'s are used to delimit the match instead of the normal / since / is used a lot in the pattern. The "$" at the end anchors the match to the end of the string. The characters that match in the two sets of parentheses are returned as a list of two values, used for the assignment to the right.

The program name part of the pattern is critical. With the end-of-line anchor it says "match all non-slash character from the end of the line to the last slash." The $ is what makes it "think backwards." The path name part is just there to suck up everything before the program name part. The slash that separates them is discarded.

This code has a serious bug - it fails if there is no path.

Here is your code with a sample path (instead of $0) and some print statements. Also, ");" is needed at the end of your statement to make it work:


my $in = "/usr/home/wruppert/perl/myprog.pl";
my ($d_home, $f_self) = ($in =~ m#(.+)/([^/]+)$#);
print $d_home, "\n";
print $f_self, "\n";

Produces the output

/usr/home/wruppert/perl
myprog.pl

Of course, there are modules already written to do this correctly and in an OS independent fashion.


use File::Basename;
my ($name, $path) = fileparse($in);
print $path, "\n";
print $name, "\n";

Produces output

/usr/home/wruppert/perl/
myprog.pl

It also works correctly when there is no path, producing a "./".

med267

9:23 pm on Jan 28, 2005 (gmt 0)

10+ Year Member



Thank you for that further description. I can see I still didn't have a full understanding of that it was generating a path name & that there was a module.

Thank you again