Re: [SLUG] Perl Question

2008-04-02 Thread Rick Welykochy

Rick Welykochy wrote:


Peter Abbott wrote:


if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
\d).*?(\d*\.\d\d)L/) {
$box, = $1;
$name = $2;
$place = $4;
$time = $5;
$margin = $6;
$name =~ s/\.//;
}


Please write maintainable code that is easy to understand.


I'll put my money where my mouth is ...



  $match = qr/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*). ... etc/;

  if (m/$match/)
  {
  ($box,$name,$place,$time,$margin) = ($1,$2,$4,$5,$6);
  $name =~ s/\.//;
  }



i.e. my rule of matching: grab the $placement variables in the statement,
to be sure, to be sure :)

The qr/.../ creates a pattern match, precompiled. And it can be used
multiple times in your code. Easier to maintain.

It's the one thing missing from python: ease of handling regexs. Yes, yes,
there is the 're' package, but that is an O-O implementation. ot part of
the language.

It is for that reason alone that my GLPs (grungy little programs) are still
whipped up in perl instead of python.


cheers
rickw




--

Rick Welykochy || Praxis Services || Internet Driving Instructor

The best way to accelerate a PC is 9.8 m/s2
 -- anon
--
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


Re: [SLUG] Perl Question

2008-04-02 Thread Matthew Hannigan
On Wed, Apr 02, 2008 at 03:09:44PM +1100, Peter Abbott wrote:
 Can anyone with greater knowledge than myself explain this regex
 behaviour.
  [ ... ]
 if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
 \d).*?(\d*\.\d\d)L/) {
   $box = $1;
   $name = $2;
   $name =~ s/\.//;
   $place = $4;
   $time = $5;
   $margin = $6;
   }
 Undoubtedly something simple that a self taught dummy has failed to
 grasp.

Doing s/// for $name there resets the $1, $2, .. counters

Matt

-- 
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


[SLUG] Perl Question

2008-04-01 Thread Peter Abbott
Can anyone with greater knowledge than myself explain this regex
behaviour.
This code segment works as intended:


if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
\d).*?(\d*\.\d\d)L/) {
$box = $1;
$name = $2;
$place = $4;
$time = $5;
$margin = $6;
$name =~ s/\.//;
}

However if the $name substitution is inserted above $place like so it
fails to allocate values to $place, $time and $margin.


if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
\d).*?(\d*\.\d\d)L/) {
$box = $1;
$name = $2;
$name =~ s/\.//;
$place = $4;
$time = $5;
$margin = $6;
}
Undoubtedly something simple that a self taught dummy has failed to
grasp.

Regards,
Peter.

Happy  proud to be,
100% Microsoft free.


-- 
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


Re: [SLUG] Perl Question

2008-04-01 Thread Amos Shapira
On Wed, Apr 2, 2008 at 3:09 PM, Peter Abbott [EMAIL PROTECTED] wrote:
 Can anyone with greater knowledge than myself explain this regex
  behaviour.
  This code segment works as intended:


  if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
  \d).*?(\d*\.\d\d)L/) {
 $box = $1;
 $name = $2;
 $place = $4;
 $time = $5;
 $margin = $6;
 $name =~ s/\.//;
 }

  However if the $name substitution is inserted above $place like so it
  fails to allocate values to $place, $time and $margin.


  if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
  \d).*?(\d*\.\d\d)L/) {
 $box = $1;
 $name = $2;
 $name =~ s/\.//;
 $place = $4;
 $time = $5;
 $margin = $6;
 }
  Undoubtedly something simple that a self taught dummy has failed to
  grasp.

I suspect that the added line resets the back-references (the
$1..$6). Try moving it under the $margin assignment (i.e. until
after you are done with the back-references).

--Amos
-- 
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


Re: [SLUG] Perl Question

2008-04-01 Thread Gonzalo Servat
On Wed, Apr 2, 2008 at 1:09 AM, Peter Abbott [EMAIL PROTECTED]
wrote:

 [..snip..]
 if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
 \d).*?(\d*\.\d\d)L/) {
$box = $1;
$name = $2;
$name =~ s/\.//;
$place = $4;
$time = $5;
$margin = $6;
}
 Undoubtedly something simple that a self taught dummy has failed to
 grasp.


Hi Peter,

I'm not too sure about this, but I believe when you do $name =~, you're
effectively starting a new regular expression which means it clears $1, $2,
$3, $4, etc (unless you use brackets inside the new regular expression).
Maybe someone else can explain it better than me? :-)

HTH!

- Gonzalo
-- 
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


[SLUG] Perl Question

2008-04-01 Thread Peter Abbott
Thanks to all who replied. I am the wiser now.

-  
Regards,
Peter.




-- 
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


Re: [SLUG] Perl Question

2008-04-01 Thread Rick Welykochy

Peter Abbott wrote:


if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
\d).*?(\d*\.\d\d)L/) {
$box = $1;
$name = $2;
$place = $4;
$time = $5;
$margin = $6;
$name =~ s/\.//;
}


correcto



However if the $name substitution is inserted above $place like so it
fails to allocate values to $place, $time and $margin.


if ( $_ =~ m/^Box(\d) ([A-Z]+(\. | ?)[A-Z]* ?[A-Z]*).*?(\d).*?(\d\d\.\d
\d).*?(\d*\.\d\d)L/) {
$box = $1;
$name = $2;
$name =~ s/\.//;
$place = $4;
$time = $5;
$margin = $6;
}


incorrecto and hard to maintain

You've also introduced a very subtle bug that I could not, at first
glance, see. The $name substitution resets $1 ... $6.

Please write maintainable code that is easy to understand.

I wouldn't want to be given the second code example buried amongst
1000+ lines of perl and then asked to fix the obscure bug.


cheers
rickw

--

Rick Welykochy || Praxis Services || Internet Driving Instructor

The best way to accelerate a PC is 9.8 m/s2
 -- anon
--
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


[SLUG] Perl question

2004-03-07 Thread Alexander Samad
Quick question

How can I do this 
print This is the value .$x-SomeFunc();
as
print This is the value $x-SomeFunc();

seems like the substition stops at the - on the second line

Alex


signature.asc
Description: Digital signature
-- 
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


Re: [SLUG] Perl question

2004-03-07 Thread Michael (Micksa) Slade
Alexander Samad wrote:

Quick question

How can I do this 
print This is the value .$x-SomeFunc();
as
print This is the value $x-SomeFunc();

 

You can go:

print This is the value @{[$x-SomeFunc()]};

But are you sure you want to do that? ;)

Mick.

--
SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/
Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html


[SLUG] Perl question

2001-02-18 Thread Michael Lake

Hi All,

OK this is a perl Q not Linux but it's Sunday night. :-)
Am having probs opening several files in a perl script using indirect
filehandles.

#!/usr/bin/perl -w


# This script reads the ASF's Apache log files and extracts accesses by
specific users. These accesses are regularly emailed to the users by a
cron
script.


use strict;
use FileHandle;

my $fileUsers="users";  # I use IN for the file handle for this.
my $fh; 
my $fhUser; # File handle for files. 

# Here is where I open a user list and read it in. Im used to this way. 
# I am used to using direct filehandles like this ie IN.

open (IN, "$fileUsers") || die "Cannot open file $fileUsers for
reading\!";
while(IN) {
($users_login, $users_name, $users_email) = split(/:/, $_); 
push(@users, $users_login);
}
close (IN) || die "Cannot close file $fileUsers\!";

All the above is OK.
Now here I have probs. For each user I want to open a file with the 
filename being the same as the name of the user.
I want to have this file open for the duratiion of parsing an Apache
log file and write to each one so I need a filehandle for each user
file.

If I try this below:

foreach $user (@users) 
{
$fhUser = "handle".$user;
open ($shUser, " $user") || die "Cannot open file $user for
reading\!";
print $fhUser "Hi $user\n";
}

I get the error upon running of:
 "Can't use string ("handlemike") as a symbol ref while "strict refs" in
use at ./process line 90."

So I tried this from the Programming Perl book, chap 7 using the
FileHandle method:

foreach $user (@users) 
{
$fh = new FileHandle " $user";
$fhUser = $fh.$user;
if (defined $fhUser) {
print $fhUser "Hi $user\n";
print $fhUser $subject;
print $fhUser "Date File from IP Address\n";
}
else {
print "Cannot open file $user for writing\!";
}   
}

and I get 
"Can't use string ("FileHandle=GLOB(0x1202e1600)mike") as a symbol ref
while "strict refs" in use at ./process line 82."

Then all I want to do is the processing

while ()
{
  Here is where I do processing and writing stuff to those open
files 
  print $fhUser "$words[3] $words[4] $words[6] from $words[0]\n";
  etc..
}

and then close all those open files...
foreach $user (@users) 
{
print "Total logins: $users{$user}\n";
$fhUser-close;
}

It's just that I have not used indirect filehandles before and the
Learning Perl book only has examples of direct filehandles.

Mike
-- 

Michael Lake
Active caver, Linux enthusiast and interested in anything technical.
Safety Convenor, Australian Speleological Federation
Owner, Speleonics (Australia)


-- 
SLUG - Sydney Linux User Group Mailing List - http://slug.org.au/
More Info: http://slug.org.au/lists/listinfo/slug



Re: [SLUG] Perl question

2001-02-18 Thread Crossfire

Michael Lake was once rumoured to have said:
 Hi All,
 
 OK this is a perl Q not Linux but it's Sunday night. :-)
 Am having probs opening several files in a perl script using indirect
 filehandles.

[Snip]
 
 foreach $user (@users) 
 {
 $fh = new FileHandle " $user";
 $fhUser = $fh.$user;
 if (defined $fhUser) {
 print $fhUser "Hi $user\n";
 print $fhUser $subject;
 print $fhUser "Date File from IP Address\n";
 }
 else {
 print "Cannot open file $user for writing\!";
 }   
 }

Drop the $fhUser bit,  - this section is *all* wrong.  you use:

print $fh  

to print to the file, you don't mangle the object rej.

But given what it looks like you're trying to do, you probably want to
keep many filehandles open at once.. [one for each user], you probably
want a construct like:

my %userfh;
foreach my $user (@users) {
$userfh[$user] = new FileHandle " $user"; # note, this is WRONG.
if (defined $userfh[$user]) {
  
}
}

you can then close all of these filehandles using:

foreach my $user (keys %userfh) {
$userfh[$user]-close;
}



 Then all I want to do is the processing
 
 while ()
 {
   Here is where I do processing and writing stuff to those open
 files 
   print $fhUser "$words[3] $words[4] $words[6] from $words[0]\n";
   etc..
 }

Looks fine... 'cept that $fhUser bit should be $userfh[$user] if I'm
understanding what you're trying to do.

 
 and then close all those open files...
 foreach $user (@users) 
 {
 print "Total logins: $users{$user}\n";
 $fhUser-close;
 }

More crack.  $foo{blah} construcuts are valid for hashes, not arrays.

 It's just that I have not used indirect filehandles before and the
 Learning Perl book only has examples of direct filehandles.

You've got more than just that wrong.

I seriously suggest you brush up on Perl Operators, datatypes and
start using perldoc more.

C.
-- 
--==--
  Crossfire  | This email was brought to you
  [EMAIL PROTECTED] | on 100% Recycled Electrons
--==--

-- 
SLUG - Sydney Linux User Group Mailing List - http://slug.org.au/
More Info: http://slug.org.au/lists/listinfo/slug



Re: [SLUG] Perl question

2001-02-18 Thread Crossfire

Crossfire was once rumoured to have said:
 But given what it looks like you're trying to do, you probably want to
 keep many filehandles open at once.. [one for each user], you probably
 want a construct like:
 
 my %userfh;
 foreach my $user (@users) {
   $userfh[$user] = new FileHandle " $user"; # note, this is WRONG.
   if (defined $userfh[$user]) {
 
   }
 }

GRAH! I'm on crack!  this is what I get for answering questions before
I leave for work.

just replace all my ravings of $userfh[$user] with $userfh{$user}!

[x] is an array subscript.
{x} is a hash subscript.

-- 
--==--
  Crossfire  | This email was brought to you
  [EMAIL PROTECTED] | on 100% Recycled Electrons
--==--

-- 
SLUG - Sydney Linux User Group Mailing List - http://slug.org.au/
More Info: http://slug.org.au/lists/listinfo/slug