Re: script that passes args to subroutine works ok, after I unpack the args. But perlcritic says I'm not unpacking?

2017-01-15 Thread Rob Dixon
Hi Alan

You are unpacking `@_` in a way, but perlcritic doesn't recognise doing it this 
way.

I think you'd be better off without dereferencing the hash, and using a slice 
to assign your local variables. I would write your subroutine like this

sub modrec {
my ($args) = @_;

my ($fn, $ar, $ad, $dr) = @{$args}{qw/ FN AR AD DR /};
...
}

And if you must, you can dereference the array with

my @dr = @$dr;

but it's generally better to access the elements directly from the reference, 
with `$dr->[0]`, `$dr->[1]` etc.

Rob


   

On 15 January 2017 20:09:53 GMT+00:00, al...@myfastmail.com wrote:
>Hi,
>
>I have a simple script with a subroutine that I pass scalar & array
>arguments to,
>
>   #!/usr/bin/perl
>
>   use 5.01201;
>   use strict;
>   use warnings;
>
>   my $this_fn = "input.txt";
>   my @this_dr = qw(
> /path/1
> /path/2
>   );
>   my $this_rn = "recname";
>   my $this_ad = "1.2.3.4.";
>
>   sub modrec {
>   my %args = %{ shift @_ };
>
>   my $fn = $args{FN};
>   my $ar = $args{AR};
>   my $ad = $args{AD};
>   my @dr = @{$args{DR}};
>
>   return;
>   }
>
>   modrec (
>{
>  FN=>$this_fn,
>  DR=>\@this_dr,
>  AR=>$this_rn,
>  AD=>$this_ad,
>}
>   );
>
>The script *executes* just fine.
>
>But when I exec perlcritic on it
>
>   perlcritic --verbose 11 -harsh test.pl
>   Always unpack @_ first at line 15, near 'sub modrec {'.
> Subroutines::RequireArgUnpacking (Severity: 4)
>   Subroutines that use `@_' directly instead of unpacking the
>arguments to
>   local variables first have two major problems. First, they 
> are
>very hard
>   to read. If you're going to refer to your variables by 
> number
>instead of
>   by name, you may as well be writing assembler code! Second, 
> `@_'
>   contains aliases to the original variables! If you modify 
> the
>contents
>   of a `@_' entry, then you are modifying the variable 
> outside of
>your
>   subroutine. For example:
>
>  sub print_local_var_plus_one {
>  my ($var) = @_;
>  print ++$var;
>  }
>  sub print_var_plus_one {
>  print ++$_[0];
>  }
>
>  my $x = 2;
>  print_local_var_plus_one($x); # prints "3", $x is still 2
>  print_var_plus_one($x);   # prints "3", $x is now 3 !
>  print $x; # prints "3"
>
>   This is spooky action-at-a-distance and is very hard to 
> debug if
>it's
>   not intentional and well-documented (like `chop' or 
> `chomp').
>
>   An exception is made for the usual delegation idiom
>   `$object->SUPER::something( @_ )'. Only `SUPER::' and 
> `NEXT::'
>are
>   recognized (though this is configurable) and the argument 
> list
>for the
>   delegate must consist only of `( @_ )'.
>
>What's wrong with the way I'm unpacking the arguments passed to the
>subroutine,
>
>   my %args = %{ shift @_ };
>
>Is there a different, recommended way?
>
>AJ
>
>-- 
>To unsubscribe, e-mail: beginners-unsubscr...@perl.org
>For additional commands, e-mail: beginners-h...@perl.org
>http://learn.perl.org/

-- 
Sent from Kaiten Mail. Please excuse my brevity.

Re: How to get a called perl script to write output to a file with DIFFERENT user:group than the calling app?

2017-01-15 Thread Rob Dixon
Hi

Is that your real program, because it's rather odd?

The built-in variable `$@` holds the message from the latest error to be 
trapped by `eval`, so since you have no `eval` blocks it will probably be 
`undef`. Did you mean to assign the command-line parameter, like this?

my ($newdata) = @ARGV;

Also, your substitution

$data =~ s/some label.*/${1} $newdata} ]/x;

uses the capture variable `$1` in the replacement string, but there are no 
captures in your regular expression, so it is likely to also be `undef`. It's 
worth pointing out that the "extended syntax" modifier `/x` allows you to add 
insignificant whitespace to your regex pattern so that you can make it more 
readable, but you have no spaces in this case so it's not doing anything 
useful; it won't do any harm, though.

You appear to want to change the values of the `USER` and `GROUP` items in the 
config file `out.txt`, but it's far from clear where your new values come from. 
Are they both in `$newdata` somehow? And how do you imagine your program will 
make two unrelated  changes with only a single substitution?

You say

> output file gets CHANGED to ownership by the SAME user & group

but changing something to the same data amounts to it being *unchanged*, surely?

Can you please show your real program and data input, together with the output 
you want? We will also need to understand what parameters are being passed to 
your program, and where it gets the new values for user and group.

Thanks.

Rob Dixon



On 15 January 2017 22:45:43 GMT+00:00, al...@myfastmail.com wrote:
>I have an application that calls a perl script, feeding it input over
>STDIN.
>
>The perl script takes that input, processes it, and writes is as a
>change to an output file.
>
>I use Path::Tiny, and this works ok,
>
>   use Path::Tiny qw(path);
>
>   my $newdata = $@;
>   $newdata = (some processing);
>
>   my $file = path('/home/aj/out.txt');
>   my $data = $file->slurp_utf8;
>   $data =~ s/some label.*/${1} $newdata} ]/x;
>   $file->spew_utf8( $data );
>
>The app runs as
>
>   USER  = "appuser"
>   GROUP = "appgroup"
>
>and the perl-script's output file gets CHANGED to ownership by the SAME
>user & group, 'appuser'/'appgroup'.
>
>How do I get that output file written with owndership by some OTHER
>user, eg
>
>   USER  = "otheruser"
>   GROUP = "othergroup"
>
>?
>
>AJ
>
>-- 
>To unsubscribe, e-mail: beginners-unsubscr...@perl.org
>For additional commands, e-mail: beginners-h...@perl.org
>http://learn.perl.org/

-- 
Sent from Kaiten Mail. Please excuse my brevity.

Re: prime numbers - loop

2015-03-14 Thread Rob Dixon

On 15/03/2015 00:25, Ilan Shlossman wrote:

Hi ,

I asked this question on linkedin but I think the best place to get
answers is here ...

I have a perl cod that check a range of numbers and print for each
number if it's prime number or not prime number.
So why its not working properly ? ...

#!C:\strawberry\perl\bin\perl
use strict;
use warnings;

main;

sub main {
  Check_Prime_Number();
}

sub Check_Prime_Number {

  my $Number;
  my @Numbers = (3 .. 6);
  for (@Numbers) {
CheckIfprime($_);
  }

  sub CheckIfprime {
my $num   = shift;

my $value = 1;
my $I;
my $remainder;

our @div_array;

for ($I = 2 ; $I  $num ; $I++) {
  $remainder = $num % $I;

  # print remainder = $remainder\n;
  if ($remainder == 0) {
print  - $num is NOT a prime number -\n;
#exit;
  }
  else {
push @div_array, $remainder;
  }
}

if ($value !~~ @div_array) {# if value is not in the array
  print  - $num is A prime number -\n;
}
  }

}


---

the output:
  - 3 is A prime number -
  - 4 is NOT a prime number -
  - 4 is A prime number -
  - 5 is A prime number -
  - 6 is NOT a prime number -
  - 6 is NOT a prime number -
  - 6 is A prime number -


Hi Ilan

I've reformatted your program so that it's a little easier to read. It
would make it easier for you to work on your own code if you indented it.

I'm not clear what your array @div_array is for, as you only ever test
that it contains the number 1 ($value never changes). What is happening
is that, even for the non-primes, the `for` loop comes to an end and is
A prime number is printed for everything. To fix it you need to add a
`return` statement where your commented `exit` is. That will exit the
subroutine as soon as a divisor is found.

Here's a few more points:

- You don't need a shebang line at the top of your program when you are
working on Windows. It doesn't do any harm, but perl will ignore it
except for some command-line switches

- Don't use an ampersand when calling subroutines. just `main()` is
correct. Whatever source taught you to do that is about twenty years out
of date

- You don't need so many separate subroutines. I think just one that
checks whether a number is prime is fine

- Don't declare one subroutine within another. It doesn't limit the
scope of the inner subroutine, and just makes your code slightly less
readable

- Variables should be declared as late as possible, preferably at the
point they are first used

- People familiar with perl will thank you for using only lower-case
letters in your local identifiers. Capitals are reserved for global
identifiers such as package names

- It is much clearer to iterate over a range than to use a C-style `for`
loop. The line

for ($I = 2 ; $I  $num ; $I++)

is better written

for my $i (2 .. $num-1)

- The smart match operator ~~ has been marked as experimental and its
use is no longer considered good practice

I've shown how I would write your algorithm below. I've dropped the use
of @div_array as I didn't understand its relevance, and the code works
fine without it. I hope that helps.

Rob


use strict;
use warnings;

my @numbers = (3 .. 6);
check_if_prime($_) for @numbers;

sub check_if_prime {
  my ($num) = @_;

  for my $i ( 2 .. $num-1 ) {
my $remainder = $num % $i;

if ( $remainder == 0 ) {
  print  - $num is NOT a prime number -\n;
  return;
}
  }

  print  - $num is A prime number -\n;
}

**output**

 - 3 is A prime number -
 - 4 is NOT a prime number -
 - 5 is A prime number -
 - 6 is NOT a prime number -


---
This email has been checked for viruses by Avast antivirus software.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: why is if (! @ARGV) skipped

2014-11-18 Thread Rob Dixon

On 18/11/2014 22:46, Harry Putnam wrote:


I'll probably be battered for general poor perlmanship but still
risking posting my whole script (fairly brief).

The problem I'm having with it, that I don't see how to debug is that
it breaks out on code inside Find.pm instead of breaking out on the
if clause designed to catch the advent of user forgetting to supply a
target directory.

The `if (!@ARGV) {[...] bleh; exit}' thing.

I'm pretty sure it is some other bit in there causing the grief but I
don't understand what.

Only thing I did to debug was to make sure `use File::Find; comes
after if (!@ARGV), but that seems not to matter.

If I run the script below without supplying a directory target I see:

rmti.pl
invalid top directory at /usr/share/perl/5.20/File/Find.pm line 472.

---   ---   ---=---   ---   ---

#!/usr/bin/perl

use strict;
use warnings;

if (!@ARGV) {
   usage();
   print At least one directory name is required\n;
   print Usage tripped: line:  . __LINE__ . \n;
   exit;
} elsif ($ARGV[0] eq help) {
   usage();
   print Usage tripped: line:  . __LINE__ . \n;
}

my $myscript;
($myscript = $0) =~ s/^.*\///;

## BEGIN GETOPTS SECTION =
# [HP 12/03/07_20:31:55 Don't use `use vars' anymore ]
our ($opt_f);
use Getopt::Std;
my $optstr = f;
getopts($optstr);

my $FORCE; # expects boolean content
if($opt_f) { ## force unlink ... no ask
   $FORCE = 'TRUE';
}

my @trgs = @ARGV;
@ARGV = ();

for (@trgs) {
   if (! -d) {
 print Whoops, no directory $_ found on system .. skipping\n;
 my $ditchme = shift @trgs; # Get rid of non-starters
 $ditchme = ''; ## zero it out ??
   }
}

use File::Find;
use Cwd 'abs_path';

find(
  sub  {
return unless -f;
 my $file = $_;
 my $abs_path = abs_path($file);
 if (/~$|\#|\.sw[po]$/) {
   if (! $FORCE) {
 print \\FOUND: $abs_path\n,
Shall we unlink delete it? y/n ;
 my $ans = STDIN;
 if ($ans =~ /^y$/) {
   unlink $abs_path  or die Can't unlink $abs_path: $!;
   printf %-60s %s\n,$abs_path, unlinked;
   ## We need to use $_ rather than $File::Find::name because
   ## The latter doesn't work in all situations.  And since the
   ## File::Find program is recursing right along with the search
   ## $_ will always work
 } else {
  printf %-60s %s\n, $abs_path, skipped
}
  } else {
unlink $abs_path  or die Can't unlink $abs_path: $!;
printf %-60s %s\n, $abs_path, unlinked;
  }
}
  }, @trgs
);
sub usage{
print 
   Purpose: Recurse thru list of directories and search out all editor leavings
   (some~ .some.swp some.bak etc), but also includes things like #some# or the 
like.
   Usage:`$myscript dir1 dir2 ... dirN'
;
}


There are a few issues with your code, but nothing that would cause the
symptoms you describe. Are you sure you're running the code you think
you are?

Rather than

if (!@ARGV) { ... }

I would prefer to see

if ( @ARGV == 0 ) { ... }

which makes the intention much clearer.

You also need to define `$myscript` *before* that `if` statement, as
otherwise there is nothing for `usage` to use. It would be best written as

my ($myscript) = $0 =~ m{([^/]+)$};

Finally, you need to ensure that `@trgs` isn't empty after removing any
non-existent directories. I would write it like so

my @trgs;

for (@ARGV) {
  if (-d) {
push @trgs, $_;
  }
  else {
print Whoops, no directory $_ found on system .. skipping\n;
  }
}

die No valid directories found unless @trgs;


I'm sorry I can't be more helpful.

Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Argument isn't numeric warning in if statement

2014-09-18 Thread Rob Dixon

On 18/09/2014 00:34, SSC_perl wrote:

On Sep 17, 2014, at 3:32 PM, Rob Dixon wrote:

As you have presented them, those code fragments are identical in meaning.


That was my understanding as well, but the inline 'if' gave an error
while the block didn't. Running the code by itself in TextWrangler
does not produce the warning. However, inside of my script, it does.
Strange.

This probably doesn't have anything to do with it, but I'm logging
during tests with this code:

BEGIN {
   use CGI::Carp qw(carpout);
   open(my $log, '', 'temp_logs/error.log') or warn(Unable to open error.log: $! 
\n);
   carpout($log);
}


You're mistaken. There's something else at play here that you've
overlooked.

   if ($item-{optionprice}) {
  $item-{unitprice} += $item-{optionprice};
   }

is *identical* to

   $item-{unitprice} += $item-{optionprice} if $item-{optionprice}

and is also the same as

   $item-{optionprice} and $item-{unitprice} += $item-{optionprice}


$item-{unitprice} += $item-{optionprice} if ($item-{optionprice});


Just so I'm clear on this, am I correct in thinking that Perl
evaluates an inline 'if' from right to left - meaning that if
$item-{optionprice} is NOT true, then the addition will not even be
seen? Or does Perl look at the entire line before performing it?


I'm not clear what you mean by an *inline* if statement. If you mean the
post-fixed if, as in

   $item-{unitprice} += $item-{optionprice} if $item-{optionprice}

then yes, the statement to the left of `if` won't be evaluated unless
the expression after it is true.

Rob


---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Argument isn't numeric warning in if statement

2014-09-17 Thread Rob Dixon

On 17/09/2014 01:37, SSC_perl wrote:


I just ran across something puzzling. Why are these two statements
not  equivalent when it comes to warnings?

if ($item-{'optionprice'}) {
$item-{'unitprice'} += $item-{'optionprice'};
}

and

$item-{'unitprice'} += $item-{'optionprice'} if ($item-{'optionprice'});

Given the following values:

$item-{'unitprice'}   = '12.16';
$item-{'optionprice'} = '';

the 2nd statement returns an Argument '' isn't numeric in addition
(+) warning, while the 1st one doesn't.



I thought I read where Peal reads a statement like the 2nd one from
right to left. It looks like it doesn't, since $item-{'optionprice'}
is evaluated in spite of the 'if'.

Am I mistaken?

Perl 5.10.1


As you have presented them, those code fragments are identical in
meaning. The code I used to prove it is below, and it give the output

{ optionprice = , unitprice = 12.16 }

which is unchanged from the initial settings.

The probable error I can see is that, even if `$item-{optionprice}` is
true, it need not be numeric, and so would raise the `not numeric` warning.

Rob



use strict;
use warnings;
use 5.010;

my $item;

$item-{unitprice}   = '12.16';
$item-{optionprice} = '';

if ($item-{optionprice}) {
  $item-{unitprice} += $item-{optionprice};
}

$item-{unitprice} += $item-{optionprice} if ($item-{optionprice});

use Data::Dump;
dd $item;



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: return the list content

2014-09-10 Thread Rob Dixon

On 09/09/2014 02:20, Ken Peng wrote:



The second option creates the same array and populates it, but then
copies it to another anonymous array, deletes the first array, and
returns a reference to the copy.


Since this is a shadow copy, I don't think the first array will be
deleted completely. Isn't it?


The second option is this

sub myfunc {
   my @x=(1,2,3);
   return [@x];
}

And yes, the array @x is created, populated, and deleted completely
every time the subroutine is called.

In the first option

sub myfunc {
   my @x=(1,2,3);
   return \@x;
}

the array isn't deleted as long as the reference returned by the
subroutine is held somewhere, but as all references to it are gone it
too will be deleted.

Rob


---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: return the list content

2014-09-08 Thread Rob Dixon

On 18/08/2014 09:17, Ken Peng wrote:


sub myfunc {
   my @x=(1,2,3);
   return \@x;
}

# or,

sub myfunc {
   my @x=(1,2,3);
   return [@x];
}

which one is the better way to return the list content? And if the
method is an instance method?


The first version of the subroutine is the best choice in the code shown
because it is less wasteful and has no external effect. It simply
creates an array, populates it, and returns a reference to that array.

The second option creates the same array and populates it, but then
copies it to another anonymous array, deletes the first array, and
returns a reference to the copy.

The big difference that is being missed so far is that, if the array was
static in some way, then returning a reference to it is very different
from returning a reference to a copy.

Consider this, where array @xx continues to exist and keeps its values
across calls to either subroutine

my @xx = ( 1, 2, 3 );

sub mysub1 {
  \@xx;
}

sub mysub2 {
  [ @xx ];
}

Now mysub1 will supply a reference to @xx itself, while mysub2 gives a
reference to a snapshot of @xx at the time of the call. Which of these
is best depends entirely on your purpose.

None of this seems relevant to your question about an instance method,
which in general will reflect the current state of the object. If you
explain the behaviour of the object better than we can help you more.

HTH,

Rob




---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: How to parse XML content using lwp agent or XML Smart

2014-08-22 Thread Rob Dixon
On 22/08/2014 11:27, angus wrote:
 Hi,
 
 Hi,
 
 I have some sample code that posts some XML content to an URL using 
 LWP agent and XML Smart.  The response to this comes back as some 
 custom XML.  I now need to try and parse the response and find the 
 REDIRECTURL value and redirect the client to that destination.
 
 I am having issues parsing the output here is what I have tried.
 
 my $response = $ua-post($webpage, Content_Type = 'text/xml', 
 Content = $message); $response-decoded_content;
 
 if ($response-is_success) { my $xml = new XML::Smart( 
 $resonse-content , 'XML::Smart::HTMLParser' ); my $xml = new 
 XML::Smart( $resonse-content , 'html' ); print \n\n 
 FOUND:$xml\n; # comes back with a null value
 
 ## # another 
 attempt below ###
 
 my $response = $ua-post($webpage, Content_Type = 'text/xml', 
 Content = $message); $response-decoded_content;
 
 if ($response-is_success) { my $html = $response-content; while ( 
 $html =~/REDIRECT/g ) { print I found: $1\n; } else { print 
 “nothing found\n”; };
 
 The find the value REDIRECT as the script prints out “I found: “ and 
 not “nothing found” but I need the url value….
 
 Here is a sample of what the xml looks like that I am trying to 
 parse.
 
 PHC_LOGIN\r VERSION3.0/VERSION\r 
 PARTNERID11/PARTNERID\r USERLOGINJohn.doe/USERLOGIN\r 
 ERROR_CODE0/ERROR_CODE\r ERROR_DESCRIPTIONLogin 
 Successful/ERROR_DESCRIPTION\r 
 REDIRECTURLhttps://example.com/cust/login.asp/REDIRECTURL\r 
 /PHC_LOGIN

There are a few problems here. I am concentrating on your first attempt,
as regular expressions are very rarely an appropriate way of processing XML.

- You need to save the content of the incoming message so that you can
pass it to the parser, but you have written

   $response-decoded_content

in void context, so the result will be just thrown away

- In the line

   my $xml = new XML::Smart( $resonse-content ,
'XML::Smart::HTMLParser' );

you mustn't put the method call in quotation marks.It will try to
stringify `$response` (which, incidentally, you have misspelled) and
result in something like

   HTTP::Response=HASH(0x2c68544)-content

Plus, to be safe, you should be calling `decoded_content` instead of
just `content`.

- There is no need to specify a parser in the second parameter unless
you need specific behaviour, so that line should be

   my $xml = XML::Smart-new( $resp-decoded_content )

after which you can simply access the elemetn you need using

   $xml-{PHC_LOGIN}{REDIRECTURL}

I have put a semi-complete program below. It needs values for $webpage
and $message, but the rest of the code is in place, and it runs fine.

HTH,

Rob



   use strict;
   use warnings;
   use 5.010;

   use LWP;
   use XML::Smart;

   my $ua = LWP::UserAgent-new;

   my $webpage = '';
   my $message = '';

   my $resp = $ua-post($webpage, Content_Type = 'text/xml', Content =
$message);

   my $xml = XML::Smart-new( $resp-decoded_content );
   say $xml-{PHC_LOGIN}{REDIRECTURL};

**output**

   https://example.com/cust/login.asp


-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Which perl for Windows?

2014-08-06 Thread Rob Dixon

On 06/08/2014 18:13, Andy Bach wrote:


On Tue, Aug 5, 2014 at 9:50 PM, Rob Dixon rob.di...@gmx.com
mailto:rob.di...@gmx.com wrote:

DWIM Perl has a version for Microsoft Windows that contains Padre,
the Perl IDE and all the CPAN modules you'll ever need.


So it's nice that there's a working IDE


I've have heard lots of good things about Padre as a Perl IDE which can
be used w/ any distro.  I'm a vim user myself so take this all w/ a
grain of NaCl2 but brian d foy and Damien C. recommend it:
http://damienlearnsperl.blogspot.com/2009_09_01_archive.html

others
http://theory.uwinnipeg.ca/CPAN/perl/pod/perlfaq3/Open_Perl_IDE.html


Sure. I have used it and I agree. But Padre is available on CPAN and
there is no need to choose a distribution that already contains it.

Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Which perl for Windows?

2014-08-05 Thread Rob Dixon

On 05/08/2014 22:20, ESChamp wrote:


Which perl should I (an occaisonal perl user, a rare perl programmer)
use? I see

cygwin
strawberry perl
activestate perl
dwim perl


- Cygwin is an attempt to put a Unix-like environment on top of Windows.
If you want to work with a Windows command line then it's not for you.

- ActivePerl used to have a problem with installing modules that weren't
prebuilt for the platform. I understand it is better now.

- I have no experience with DWIM Perl, but this worries me:


DWIM Perl has a version for Microsoft Windows that contains Padre,
the Perl IDE and all the CPAN modules you'll ever need.


So it's nice that there's a working IDE, but it implies that you will
have trouble if you want to install a module other than anything they
have decided you could possibly need.

- Strawberry has a working tool set that allows you to install any CPAN
module I have found that could possibly work on Windows without
modification.

Go Strawberry, and learn the language properly - you will love it.

Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Suddenly.... Part 2

2014-08-05 Thread Rob Dixon

On 05/08/2014 19:13, ESChamp wrote:


Here's a small portion of my script:


Excuse me for my confusion as I missed Suddenly - Part 1.

Are Peter Holsberg and ESChamp one and the same, as they both seem to be 
driving this thread?


Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Date::Parse and strange dates

2014-07-25 Thread Rob Dixon

On 25/07/2014 17:54, Chris Knipe wrote:

Hi All,

I have the odd (very rare) case where I am given a date in an incorrect
format.  I already use Date::Parse to convert the dates to a unix
timestamp, and it’s working incredibly well.  However, on the rare case
that I get incorrect dates, Date::Parse does not like them either and
errors out.  The formats in question that I can’t parse basically looks like

Thu, 23 Oct 2008 12:06:48+0400

Note the lack of a space between the seconds and the timezone.


Date::Parse is amiss here because (at least) the time part of that
string complies with ISO 8601. i.e. the space *shouldn't* be there.

Ridiculously, you must *pay* ISO to get a copy of their standard, but
W3C's version is here

http://www.w3.org/TR/NOTE-datetime

To fix the immediate problem I would amend every date-time string using

s/\S\K([-+][0-9]+)\z/ $1/

but I also think it's worth emailing

Graham Barr gb...@pobox.com

the author of Date::Parse to get his angle on this.

Rob







---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Apologetic request for simple one-off script

2014-07-14 Thread Rob Dixon
On 14 July 2014 14:22:55 BST, John SJ Anderson geneh...@genehack.org wrote:
Hi. List Mom here.

Please take this off list, it's not on-topic.

John: Thank you for answering the OP's question. However, Shlomi is
right, the two argument form of open() is something that the general
Perl community considers to be a deprecated style that should not be
used with new code. This list is not the place to argue that, that
ship has sailed.

Shlomi: line-by-line teardowns of scripts people post in response to
questions are generally not helpful, particularly when the script
_will_ work as written. It makes people feel attacked and leads to
defensive responses that make the list appear to be an unfriendly
place. If you think you can write a better or more correct script,
just provide it; this type of critique ends up being an overall
negative contribution.


thanks,
john,
perl-beginners list mom

John,

I was thrilled with your initial work as list moderator, and sent you a 
personal email to say so. I had been asked if I wanted the position myself, and 
was delighted that it finally fell to you as you initially achieved far and 
beyond anything that I was capable of.

Some years on it is sad that your input has become more judgemental and far 
less humble. These days, your head pops up over the parapet only to aim a 
shotgun, or occasionally to answer a question yourself that has taken your 
fancy. Your “It makes people feel attacked and leads to defensive responses 
that make the list appear to be an unfriendly place” applies just as much to 
your own posts, and for many months I have been disinclined to contribute as a 
direct result.

I trust that you have been monitoring activity on this list as part of your 
responsibility, and I am sure that you will have seen a steady downward trend 
on recent years.

I hope it isn't too much to hope that the fair but modest hand that you first 
exercised could make a return?

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Apologetic request for simple one-off script

2014-07-14 Thread Rob Dixon
On 14 July 2014 15:18:31 BST, John Delacour johndelac...@gmail.com wrote:

On 14 Jul 2014, at 14:11, Shlomi Fish shlo...@shlomifish.org wrote:

 perldoc -f open

 This is irrelevant. Two-args open is dangerous - always use
three-args open:
 
 * http://perl-begin.org/tutorials/bad-elements/#open-function-style

Who wrote that?  Ah...a certain Shlomi Fish.

I have made exactly that point before, but John Anderson as list moderator 
determined that there was no need for anyone to declare an interest in anything 
they linked.

To be fair, Shlomi has regularly explained that he is responsible for 
perl-begin, but it still worries me that he never claims authorship of the 
articles themselves.

I believe a similar problem exists with people posting recommendations for 
their own CPAN modules without any declaration of interest. This too is now 
within the rules.

I have never known a public forum run on such strange principles, but of course 
it is for John to choose and dictate how the site works.

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Planning to buy Hard Copy Book

2014-06-11 Thread Rob Dixon

On 11/06/2014 11:23, Frank Vino wrote:


   Could you please let me know which publisher and author name are good
in Perl Book, I am planning to buy a hard copy.


There are several worthy Perl 5 tutorial books available, but the
definitive Perl manual is Programming Perl, now in its fourth edition.
It covers versions of Perl 5 up to 14.

Rob


---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: How to parse C#, javascript, lisp source code for quoted literal strings

2014-05-22 Thread Rob Dixon

On 22/05/2014 10:04, siegfr...@heintze.com wrote:

I need to extract some information from source code.

How can I write a perl regular expression that will match a literal
string in languages like C#, javascript, java and lisp?

Here is my naive approach:

/[^]*/

This of course does not accommodate backslashes in the string that perl,
C, C# javascript use.

\sdfds\\\r\\t\\m.

How can I write a regular expression in perl to look for a double quoted
literal string in these languages?


There are many complications to something like this that can't be
properly resolved without parsing the language as a whole. However, this

/(?:\\.|[^])*/

will cope with escaped quotes.

Rob




---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: about open with pipe '-|', '|-'

2014-05-09 Thread Rob Dixon

On 09/05/2014 21:58, Shawn H Corey wrote:

On Fri, 09 May 2014 16:41:02 -0400
Harry Putnam rea...@newsguy.com wrote:

Agreed. I wished they used something like: | and |


Hey Shawn

You should raise a bug using `perlbug` on the command line. I amd sure
it would be considered carefully and you would get a reasoned response.

I think I would go with `|` and `|` though, which allows for `|` if
there is ever a real read/write open mode.

Rob





---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: about open with pipe '-|', '|-'

2014-05-09 Thread Rob Dixon

On 09/05/2014 21:41, Harry Putnam wrote:

I guess I need a mnemonic device to trick myself into remembering
which way the pipe with dash symbol goes.

   And I suppose I should apologize for the cry baby rant in
advance:

Even now I'm flopping around trying to remember...

I've written scripts involving sending mail with sendmail from perl.
Or capturing the output of rsync etc.

I used a piped open like this:

   open my $ch, '|-', $sendm or die
  Can't open $sendm: $!;

   while ($sch){
 print $ch bleh;
 print $ch blah;
  }

Or perhaps it was like this:

   open my $ch, '-|', $sendm or die
[...]

It may have been either way.  I don't have it handy.  But one way,
string $bleh and $blah get sent as mail.

My question is not so much which was right for that usage (although
that would be helpful too), but how to know at a moments thought, how
to setup the pipe for that usage.

One way might inject mail into sendmail with a while loop, the other
might allow one to track (or search etc.) the output of some command
in a while loop.

One way fails and can cause some confusion in tracking the
problem.

So the need here (beyond importing someone elses' brain) is how
to remember which way.

There must be something that would make even an intellectually
challenged sort like me ... remember.

Yes, yes, I know I can test and get it right which I've done
repeatedly. Here, I'm looking for a way to fix it in my mind.

As soon as I think I've got it right by thinking:

   ok, left side is into the command
  right side is out.


Hi Harry

Information flow is left-to-right, the same as when you use pipes to
chain a string of commands on the terminal.

I sympathise, but if you remember the history - first of all that larry
Wall wrote the language from the point of view of a linguist - and
secondly that

open my $ch, '| command p1 p2'

means to open a pipe to `command p1 p2`. This format happens to use the
shell to do its stuff.

This was improved in Perl 5 version 6-ish to make this work with the
three-parameter form of `open`, like this

open my $ch, '|-', 'command', 'p1', 'p2'

So the hyphen, or dash, is an *it* pronoun like `$_`, and this syntax
opens a pipe to *it*, where *it* is the given command and parameters.

The same applies to using a mode of `-|`, where the *it* is still the
command and parameters, but it is on the left of the pipe, so the Perl
program is opening a pipe *from* the command.

I hope that helps.

Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: about open with pipe '-|', '|-'

2014-05-09 Thread Rob Dixon

On 10/05/2014 03:48, Uri Guttman wrote:

On 05/09/2014 04:58 PM, Shawn H Corey wrote:

On Fri, 09 May 2014 16:41:02 -0400
Harry Putnam rea...@newsguy.com wrote:


As soon as I think I've got it right by thinking:

   ok, left side is into the command
  right side is out.

If I start pondering over that ... it begins to seem it is the other
way.

Gack I'm sick of it.


Agreed. I wished they used something like: | and |


they use - as that is also the magic name for stdio. in many unix tools
you can pass - as the filename (in or out) and the program will use the
appropriate i/o direction of stdio instead.

so it is an easy way to remember. |- has the pipe going out to the - so
that means stdout will be connected to the handle. -| has the - going in
to the pipe so that means stdin will be connected to the handle. and i
mean stdin/out of the process being forked. and you can't do both ways
as that would likely cause hanging with blocking i/o.

and if you want finer control, then use IPC::Open[23]


This is far from definitive, as there is no way of intuiting whether `-`
refers to the Perl program's STDIO or to the child process's. In fact

  open my $fh, '-'

opens a handle to the Perl program's STDOUT, whereas

  open my $fh, '|-', 'command'

opens a handle to the child process's STDIN

So there is no consistency

Rob





---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: small puzzle

2014-04-25 Thread Rob Dixon

On 26/04/2014 02:16, Uri Guttman wrote:

On 04/25/2014 12:55 PM, Harry Putnam wrote:

Uri Guttman u...@stemsystems.com writes:


why would you expect anything but 1 as the value? shift will return 1
value or undef. that anon array will be dereferenced to an array with
1 entry. the array is in scalar context which returns its
size. elementary!

 ^ my dear Watson.

Thank you Mr Uri (The Snot) Guttman, for the usual helpful but snotty
response.  I do appreciate it.


i do support all the time for pay and for free. your response is
snottier than anything i said. i was talking about your code, not YOU.
you were insulting me directly. there is a difference. also my replies
about code are for all on this list to learn from. don't take code
review so personally.


It is a common defence to claim that you were not criticising a *person*
but instead something that they created / did / believed etc. Randal
Schwartz used it a lot when he posted here more regularly.

In the same vein, Harry wasn't insulting *you* directly, he was
criticising your *response* and your *attitude*, and I agree with him.

I am sure that makes you feel much better.

Rob




---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: about HTML

2014-03-13 Thread Rob Dixon

On 13/03/2014 13:33, Ariel Hosid wrote:

Hi there!
I am needing a module to parse a HTML page and to take action on it.
Any idea?

--
 Ariel


There are several candidates. I would look at HTML::TreeBuilder first.

Rob


---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Build Perl keyword hash

2014-03-13 Thread Rob Dixon

On 13/03/2014 13:29, Alex Chiang wrote:


I'd like to build a hash mapping from keyword = value. By keyword, I
mean all reversed words in http://learn.perl.org/docs/keywords.html. Do
you guys know any csv or text file containing all these words?
I don't want to hard code all these reversed words into list, then
creating hash for parsing.


Hi Alex

If I understand you, you just want a file containing all the 
identifiers, which you can get by copy-pasting from your browser.


Like this http://pastebin.com/8xGKqYfy

HTH,

Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Build Perl keyword hash

2014-03-13 Thread Rob Dixon

On 13/03/2014 13:56, Alex Chiang wrote:

Yes. Thanks for your help.

How do you copy and paste from browser ?  When I tried this, all I got
is hyperlink and metadata.


You probably need to use a decent browser. Are you using Internet 
Explorer? Give Firefox or Chrome a try.


Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: about HTML

2014-03-13 Thread Rob Dixon



On 13/03/2014 18:13, Ariel Hosid wrote:

2014-03-13 10:43 GMT-03:00 Rob Dixon rob.di...@gmx.com

On 13/03/2014 18:13, Ariel Hosid wrote:

On 13/03/2014 13:33, Ariel Hosid wrote:

Hi there!
I am needing a module to parse a HTML page and to take action on it.
Any idea?



There are several candidates. I would look at HTML::TreeBuilder first.


I'm using the Perl Package Manager and couldn't find the
HTML::TreeBuilder module, but I found the HTML::Element-Library module.
Does it include the TreeBuilder module functionality?


It is standard practice to bottom-post on this list.

The module you need is called HTML-Tree. It includes both
HTML::TreeBuilder and HTML::Element.

Rob


---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: regex and parse

2014-03-11 Thread Rob Dixon

On 11/03/2014 17:01, Ariel Hosid wrote:


Can anyone recommend me literature that treats regular expressions and
how to analyze files?


The best documentation on regular expressions is Perl's own here

http://perldoc.perl.org/perlre.html

Analysing files is an enormous subject that is difficult to generalise.
Perhaps you should read what you can find on the internet and come back
here if you have a specific problem?

Rob


---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: return just a match from an array without changing the array

2014-03-04 Thread Rob Dixon

On 03/03/2014 23:35, shawn wilson wrote:

So, when I do this:
   my $src = (grep {/.*(ARIN|APNIC).*(\n)?/; $1} @ret)[0];
I get a full line and not just the capture:
# ARIN WHOIS data and services are subject to the Terms of Use

When I do this:
   my $src = (grep {s/.*(ARIN|APNIC).*(\n)?/$1/} @ret)[0];
I get just the match but it also alters the array


Both `map` and `grep` will process *every* element of `@ret before
producing a result, even if the first element matches.

The most efficient is a `for` loop, like this

use strict;
use warnings;

my @ret = (
  '# Line 1',
  '# ARIN WHOIS data and services are subject to the Terms of Use',
  '# Line 3',
);

my $src;
for (@ret) {
  if (/(ARIN|APNIC)/) {
$src = $1;
last;
  }
}

which prints `ARIN`.

HTH,

Rob




---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: check list if values meet criteria

2014-02-25 Thread Rob Dixon

On 25/02/2014 23:46, Bill McCormick wrote:

On 2/25/2014 4:36 PM, Bill McCormick wrote:

On 2/25/2014 4:30 PM, Bill McCormick wrote:

What would be the perl'ish way using map or some other sugar to check if
a list of values meet some criteria? Instead of doing something like

my @issues = qq(123,456,a45);
my $max = 999;

for (@issues) {
   die if $_  0 or $_  $max;
}


Revision:

for(@issues) {
   print issue=[$_]\n;
   die $_ not a number\n if $_ ne $_+0;
   die $_ not in range\n if $_  0 || $_  $max;
}


Thanks everyone for the speedy replies. I was looking to just use raw
perl for this. This is for an svn PRE_COMMIT hook, where issues is a
list of bz issues.


Hi Bill

As far as I can tell Ron's solution is the better one. The Scalar::Util
module has been part of core perl since version 7.3 of Perl 5, which was
released in March of 2002. Unless your version is over twelve years old 
you can consider `looks_like_number` to be part of raw Perl.


Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: OO perl programming

2014-02-10 Thread Rob Dixon

On 07/02/2014 01:11, Sam wrote:


The oreilly Learning Perl teaches one to use the ampersand when
calling subroutines, which most perl'ers will disagree with. I did it
for years with out even questioning it until it bit me because I had
read that book.


I believe that most of the recent dislike of Perl comes from its use of
sigils for everything. The original design was a result of Larry Wall's
linguistic background, so his sigils were a way of expressing the
plurality of value in the same way that we add a suffix `s` to most
nouns to show a plural, or `ly` do denote an adverb.

It's a nice idea, and is very comfortable once you are used to it, but
it can look kinda crazy when you're used to bare variable names. I
believe it's much nicer than the awful Hungarian Notation, which comes
up with stuff like `arru16Ids` for an array of unsigned sixteen-bit
identifiers.

The move to object-orientation in Perl 5 rather messed this idea up, as
it didn't make sense to call methods as `{ $object-method }`, so the
requirement for the ampersand was dropped in ordinary subroutine calls
as well as method calls.

I dislike Learning Perl for other reasons: paticularly that, despite
being a senior partner of Stonehenge, on whose courses the book is
based, doesn't seem to comprehend the problems that people have with
learning and understanding Perl.

However, later editions of Learning Perl include this section

http://hellolixian.tumblr.com/post/5569953537/omitting-the-ampersand

that goes some way to explaining the circumstances where an ampersand is
necessary.

My rule of thumb is that you should use the ampersand if you are
treating the subroutine as an item of data: you should drop it if you
are just calling it as a function.

Rob



---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Replacing the first line of a text file

2014-02-04 Thread Rob Dixon

On 04/02/2014 01:12, SSC_perl wrote:

use strict;
use warnings;

my $filename = 'products.csv';
open (my $fh, '+', $filename) || die can't open $filename: $!;
my $line = $fh;
$line =~ s/tag_//gi;
seek $fh, 0, 0;
printf {$fh} $line;
close $fh;



If it is satisfactory to leave the original file with trailing spaces at
the end of the first line, then you can do so like this

use strict;
use warnings;

my $filename = 'products.csv';
open (my $fh, '+', $filename) || die can't open $filename: $!;

chomp(my $line = $fh);
(my $new_line = $line) =~ s/tag_//gi;
my $pad_size = length($line) - length($new_line);

seek $fh, 0, 0;
printf {$fh} $line, ' ' x $pad_size;

close $fh or die $!;


or much more simply you could use the Tie::File module, like this

use strict;
use warnings;

use Tie::File;

my $filename = 'products.csv';

tie my @file, 'Tie::File', $filename or die can't open $filename: $!;
$file[0] =~ s/tag_//gi;
untie @file;


HTH,

Rob


---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: baby perl to get the right date

2014-01-28 Thread Rob Dixon

On 28/01/2014 07:32, Luca Ferrari wrote:

Hi all,
often I find myself writing something like the following to get the
human date:

my ($day, $month, $year) = (localtime())[3..5];
$month++, $year += 1900;
print \nToday is $month / $day / $year \n;


I was wondering if there's a smarter pattern to get the right value in
one single line. At least there's no simple map I can think of.


Hi Luca

It is probably best to use the Time::Piece module, which has been part 
of core Perl 5 since version 10 so you shouldn't need to install it.


The program below shows how you would use it.

HTH,

Rob



use strict;
use warnings;

use Time::Piece;

my $date = localtime-strftime('%m / %d / %Y');

print \nToday is $date\n;

**output**

Today is 01 / 29 / 2014

---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Identifying the current opened filehandle for writing as I'm getting undefined variable concatenation errors

2014-01-14 Thread Rob Dixon

On 15/01/2014 03:09, Matt McAdory wrote:

Is there a method for determining the currently selected filehandle?
should I always check for undef and open my filehandle before writing to it?

use strict;
use warnings;
use autodie qw (:all);

use My:CustomMod_with_FH_write;

open (my $FH, , filename.txt);

my $var = My:CustomMod_with_FH_write-new;
my @array = $var-sub1(); #writes to it's FH, but returns me an array of stuff
print $FH, some stuff\n; # works great.
while (@array) {
 chomp;
 my @array2 = $var-sub2($_);  #gets some new stuff in another array, 
prints again to the module FH
 while (@array2) {
 chomp;
 my $thing = $var-sub3($_); # returns a scalar
 print $FH $thing\n; 
# BOOM!?!?
 }
}




the last print always give me a . . . . concatenate (.) to undefined
variable $FH near line . . . . and I can't understand where I'm scoping
out and my $FH gets closed. Add the open below and it works. Granted
this is some dummy code, I'm not in the office right now to give
specifics, but sub calls to the module work fine. Write to the my
filehandle works fine . . . until I get to a certain level of nesting
and then it bombs and I don't understand why nor can I find a way to
print the active filehandle. What am I doing wrong? The module FH and my
FH are different files in different directories. I probably need to find
a different way of doing what I'm doing.

Should that BOOM always be:

if (undef $FH) {open (my $FH, , filename.txt);}
print $FH $thing\n;
close $FH;

A friendly page in the fine manual to read. A nudge towards a llama or
camel reference would be appreciated. Several days show my googlefu to
be lacking. Where is my rookie mistake?


In this case the currently-selected file handle is irrelevant as all
your print statements specify the file handle explicitly.

Your problem isn't with a closed file handle, which would report

print() on closed filehandle

but with the contents of $thing. The statement

print $FH $thing\n

will report

Use of uninitialized value $thing in concatenation (.) or string

if $thing is undefined.

Rob

---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Help with a RE

2014-01-09 Thread Rob Dixon

On 09/01/2014 09:55, Gary Stainburn wrote:

On Thursday 09 January 2014 09:53:35 Gary Stainburn wrote:

Oops, Missed a bit, try

s/^[0-9]+[a-c]{0,1}[-_]//;


/[a-c]{0,1}/ is normally written as /[a-c]?/

---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Gigantic file size processing error

2014-01-03 Thread Rob Dixon

On 02/01/2014 15:21, mani kandan wrote:

Hi,

We have file size of huge size 500MB, Need to Manipulate the file, some
replacement and then write the file, I have used File::slurp and works
for file size of 300MB (Thanks Uri) but for this huge size 500MB it is
not processing and come out with error. I have also used Tie::file
module same case as not processing, any guidance.


Slurping entire files into memory is usually overkill, and you should
only do it if you can aford the memory and *really need* random access
to the entire file at once. Most of the time a simple sequential
read/modify/write is appropriate, and Perl will take care of buffering
the input and output files in reasonable amounts.

According to your later posts you have just 2GB of memory, and although
Windows XP *can* run in 500MB I wouldn't like to see a program that
slurped a quarter of the entire memory.

I haven't seen you describe what processing you want to do on the file.
If the input is a text file and the changes can be done line by line,
then you are much better off with a program that looks like this

use strict;
use warnings;

open my $in, '', 'myfile.txt' or die $!;
open my $out, '', 'outfile.txt' or die $!;

while ($in) {
  s/from string/to string/g;
  print $out $_;
}

__END__

But if you need more, then I would guess that Tie::File is your best
bet. You don't say what problems you are getting using this module, so
please explain.

Rob




---
This email is free from viruses and malware because avast! Antivirus protection 
is active.
http://www.avast.com


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: perlre(1) and substitution evaluations

2013-11-30 Thread Rob Dixon
Lars Noodén lars.noo...@gmail.com wrote:
perlre(1) seems to be missing information about substitution
evaluations
with the /e option.  The functionality is present in perl:

   perl -e '$_=2; s/2/1+3/e; print'

But it is not listed in the pod documentation for v5.16.3 or v5.18.1.
The modifier /e is described in Programming Perl, 4th ed, pp 186,
254-255.

Where should suggestions for corrections be sent?
Could something like the text below be added?

Regards,
/Lars

$ diff perlre.pod perlre.pod.orig
108,113d107
 =item e
 X/e

 Treat the replacement portion as an interpreted expression.
 Each additional C/e modifier after the first functions as an eval()
around the code to execute.


The substituted string isn't a regular expression. The substitute operator s/// 
is described in `perlop`.

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Reading a sequence data from a file

2013-11-15 Thread Rob Dixon

On 12/11/2013 23:24, Michael Brader wrote:

Hey Femi,

Instructions and example code for doing all the things you want can be
found in the standard Perl manual. You should be able to find it by
opening a terminal window and using the perldoc command:


A superb answer Michael. Well done.

Rob




--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Using a function in a variable

2013-11-09 Thread Rob Dixon

On 09/11/2013 13:33, Unknown User wrote:


I have a variable that has a function in it, e.g.

   my $newtime = time() + 30;

How can i use it in code so that it always returns  time() + 30 when it
is called?


Does it *have* to be in a string like this? Where has the string come from?

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hello from a newbie

2013-10-26 Thread Rob Dixon

On 26/10/2013 13:59, Shawn H Corey wrote:

On Sat, 26 Oct 2013 07:28:09 -0400
htchd...@live.com wrote:


How about python?
Many people consider it's better than Perl and it becomes more and
more popular.


This is why:


Why what? I assume you're promoting Python, which is a bit strange on
this list.

 
  $ python
  Python 2.7.4 (default, Sep 26 2013, 03:20:26)
  [GCC 4.7.3] on linux2
  Type help, copyright, credits or license for more information.
  1/2
  0
  exit()


  $ perl -ple'$_=eval'
  1/2
  0.5
  exit

I don't know what you think that demonstrates, apart from Python
assuming integer arithmetic?

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: OT: Python

2013-10-26 Thread Rob Dixon

On 26/10/2013 23:55, David Christensen wrote:

On 10/26/13 04:28, htchd...@live.com wrote:


How about python? Many people consider it's better than Perl and
it becomes more and more popular.


There are a lot of really smart people who like Python.


Maybe, but it seems that you are not one of them since you ignore the
list administrator's very clear warning *not* to raise the subject.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Need help with a programming problem

2013-10-05 Thread Rob Dixon
On 04 Oct 2013 06:33, Shlomi Fish wrote:
 On 02 Oct 2013 Uri Guttman wrote:
 On 02 Oct 2013 08:56 PM, Rob Dixon wrote:
 On 03 Oct 2013 01:39, Uri Guttman wrote:

 I do recommend you try to use File::Slurp to read in and write out your
 files.

 It would help a lot if you declared your interest in File::Slurp. It is
 disingenuous to recommend your own modules.

 i don't see why? it is just a tool to help him. i get no compensation
 other than it helps to use it. also in my reply to him i did say i was
 going to add a feature idea to the todo list.

 i recommend my modules when they are appropriate and don't always say
 they are mine. there actually isn't much (if any) competition on cpan
 for a couple of them.

 
 Rob has been bothering me as well with similar complaints for recommending
 XML::LibXML instead of XML::XPath, just because I happen to maintain
 XML::LibXML (even though I mention it) and has been voicing similar complaints
 about me referring people to the various resources on http://perl-begin.org/
 which I also maintain. It seems he has an obsession with people recommending
 resources that they originated or are maintaining, even if these resources are
 100% open source/open content and are not likely to yield substantial monetary
 benefits.
 
 So I suggest that both you and I just ignore those exits by Rob about these
 things from now on. Like the old Internet adage go: “Those who can - do. Those
 who can’t - complain.”.

Hi Shlomi

This applies equally to the exchanges we have had in the past on this
topic, and to my recent note to Uri.

I am sorry you consider my comments to be bothering you. I only ever
made a single comment, as I did to Uri here, and answered any questions
you had in your replies.

The problem I see is that it should be up to the reader to decide
whether to accept your recommendations *based on clear knowledge of any
investments you may have*. Whether that is an emotional or financial
interest is irrelevant; your advice *must* be evaluated in the light of
your likely impartiality.

Uri, I rarely see File::Slurp recommended other than by yourself.
usually it is in the context of a work-around for Perl's lack of support
for a regex version of $/. I have also never had occasion to use it
myself, despite a working understanding of its facilities. I accept that
you believe your advice to be equitable, but it is inevitable that a
rosy glow will surround anything that is the product of your own labours.

Shlomi, the same applies to your XML::LibXML, which is an excellent
module, and probably the only real contender to pole position for
modules not based on XML::Parser. However I don't remember seeing you
recommend anything else in any circumstance, and that worries me.

As for your web site, I am puzzled why you would not want people to know
that your perl-begin.org was the work of your own fair hand? It isn't
mentioned in your sig, and even the site itself is coy about declaring
it to be pretty much all your own work apart from what is said in the
Contributors List.

What concerns me most is that, if you refer to your own site in the
context of this list, unless you indicate that you are referring to more
of your own words on the same topic, it will be seen as a third-party
endorsement of your point of view.

Since I raised the issue, you have been adding semi-legalese like this

 * http://perl-begin.org/uses/multitasking/#threads
 
 (**NOTE**: http://perl-begin.org/ is a site I originated and still maintain -
 all caveats apply.)

which I guess is OK, but all that is necessary is something less formal like

 See what I wrote about this on my site
 http://perl-begin.org/uses/multitasking/#threads

which declares that you are both the author of the words and proprietor
of the site in far less verbiage.

Similarly, where Uri writes

 i do recommend you try to use File::Slurp 

all that I see is necessary is

 i do recommend you try my own File::Slurp module

and, again, I am surprised that you wouldn't want to boast ownership in
the first place.

Maybe I have been misunderstood before, in which case I apologise and
hope that this has helped to explain my point of view. If not, and if
there is still antipathy to my thoughts, then I would like to see it
spelled out. I am copying this to John SJ Anderson, the list manager,
whose judgement I have found in the past to be impeccable, and whom I
trust completely to make a correct call on this.

Shlomi, I don't know what typo led to `exits` in this

 So I suggest that both you and I just ignore those exits by Rob about
 these things from now on. Like the old Internet adage go: “Those who
 can - do. Those who can’t - complain.”.

but the paragraph is insulting and inappropriate on a public list. I am
sure Uri is quite capable of making their own decision to ignore me if
they so wish, and you are out of order in exorting him to do so.

I am sure you will let me know your thoughts.

Kind regards,

Rob Dixon


-- 
To unsubscribe, e-mail

Re: I'm doing something stupid

2013-10-03 Thread Rob Dixon
shawn wilson ag4ve...@gmail.com wrote:
From position 0 to 7 should be whatever GREP_COLOR export is defined
as. There might be issues with how I'm doing that but my main issue (I
think) is how I'm looping (and/or how I'm using substr).

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my $line = 'foo bar baz ball';
my $match = [
  [
[
  '0'
],
[
  '7'
]
  ]
];

my $color = $ENV{GREP_COLOR};
# The environment looks like 1;32 but we need to send \e[32m
$color =~ s/1;/\e[/;
$color .= 'm';

print match  . Dumper($match);
# Each regex
foreach my $ereg (@$match)
{
  print ereg  . Dumper(@$ereg);
  print blah  . $ereg-[0][0] . \n;
  # Each match
  foreach my $epat (@$ereg)
  {
print epat  . Dumper(@$epat);
substr($line, $epat-[0], 0, $color);
substr($line, $epat-[1], 0, '\\e\[0m');
  }
}

print $line

I'm unclear what you intend, but the `foreach my $epat` executes *twice*, first 
with
$epat set to [ '0' ] and then with $epat set to [ '7' ].

So in the first iteration $epat-[0] is '0' and in the second iteration it is 
'7'. In both cases there
is no $epat-[1], hence the warnings.

Perhaps what you want is $ereg-[0][0] and $ereg-[1][0]?

Rob

(Sorry about this awful email - I'm using a tablet on a train!)




--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: How Much is Too Much?

2013-10-02 Thread Rob Dixon

I'm not bucking for net nanny but, while full solutions and
follow-on discussions can be enlightening, I wonder if they're
really advantageous to the OP. Not to embarrass anyone but there
was no mention of DIY attempts, no soliciting of hints or
approaches, or even mention of being stuck or frustrated thinking
about how to start.


On the other hand, any program under 200 lines is trivial and is a
warm-up exercise. ;)

How are newbies going to learn good coding practices without reading
good code?


Indeed. People learn in different ways. Some people, myself
included, learn through seeing examples which then can be used to
read up further with a better insight and understanding of what
they're looking at/reading. Others, can simply pick out information
from books and learn without much guidance. Sometimes, the text
written by people may not be as intuitive to others reading it as
the author may believe. Of course, that doesn't mean those learning
shouldn't make an effort to understand first and rely solely on the
examples and guidance of others


Agreed - and that's why I think the examples can be enlightening for
every level.  However,  this example while demanding a fair level of
skill wasn't brain surgery and even newbies and students should be able
to make an initial attempt at a solution and report what they saw or
where they got stuck.   Or even preface their post with  I tried
'split' but even thinking about the next step gives me a headache. What
would you  suggest?.   Now the  expectation is tilting  to  Solve it
for me... you got nothing better to do and I'm busy... too busy to waste
my time detailing what if anything I did to help myself.


I tend to publish rather more code than is necessary so as to provide a
proof of concept, rather than to do the OP's work for them. However I
know there is a tendency to ask for fish, rather than help to catch them

This blog post talks about it exceptionally well

http://mattgemmell.com/2008/12/08/what-have-you-tried/

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Need help with a programming problem

2013-10-02 Thread Rob Dixon

On 02/10/2013 20:44, Peter Holsberg wrote:

Shawn H Corey has written on 10/2/2013 2:29 PM:


my @files = grep { /^\d{6}\.htm$/i } glob( '*.htm' );


Well, I'm more of a beginner than I thought I was!

The /i to grep is to ignore case?

Why are you globbing *.htm?


Hi Peter

All that Shawn has shown you is how to get the list of files; although
not saying so seems very unhelpful to me.

Yes, the /i modifier on any regex makes it ignore the case of the text
it matches.

glob( '*.htm' )

returns a list of the files in the files in the current directory that
end with `.htm`, while

grep { /^\d{6}\.htm$/i }

filters that list to include only those that begin with six decimal digits.

When you say


The file's name is \d{6}.htm


do you mean that literal name, or do you want to include *.htm files
that start with six decimal digits? Jim Gibson has assumed the former,
while Shawn, the latter.

If you are modifying just a single file, then I would choose a text
editor to do the job, not Perl or any other language.

If you clarify your requirement then I will gladly help, but it would go
down much better if you showed the work you had done already.

Rob





--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Need help with a programming problem

2013-10-02 Thread Rob Dixon

On 03/10/2013 00:19, Shawn H Corey wrote:


It would be difficult to get a file with a backslash in it.


perl -e open X, q/\d{6}.htm/

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Need help with a programming problem

2013-10-02 Thread Rob Dixon

On 03/10/2013 01:39, Uri Guttman wrote:


I do recommend you try to use File::Slurp to read in and write out your
files.


It would help a lot if you declared your interest in File::Slurp. It is
disingenuous to recommend your own modules.

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Need help with a programming problem

2013-10-02 Thread Rob Dixon

On 02/10/2013 18:22, Peter Holsberg wrote:

Hi,

I have tried to do this for hours but it looks like it is just too
difficult for me.

I would like a script to open a file in the current directory and edit
it. The file's name is \d{6}.htm

The script then needs to search for a line that begins:

a class=nolinkunderline

and delete that line and the one underneath it.

Then then it should append an existing file \d(6).txt (i.e, a file with
the same filename as the
first file but with TXT as its filetype) to the end of the line that is
in its entirety

pre

Finally, it should jump to the line

/div/body

and replace it with

/div
script type=text/javascript
var sc_project=8607440;
var sc_invisible=1;
var sc_security=f3cd5e09;
var scJsHost = ((https: == document.location.protocol) ?
https://secure.; : http://www.;);
document.write(sc+ript type='text/javascript' src=' +
scJsHost+
statcounter.com/counter/counter.js'/+script);
/script
noscriptdiv class=statcountera title=web analytics
href=http://statcounter.com/; target=_blankimg
class=statcounter
src=http://c.statcounter.com/8607440/0/f3cd5e09/1/;
alt=web analytics/a/div/noscript
/body


OK here's a working solution. I'm not at all happy about this as you
have made no visible effort of your own.

The original `123456.htm` is copied to `123456 - Copy.htm`, which is
tied to an array using the Tie::File module.

The three changes that I think you intend are made to the array, and it
is then untied to close the file.

Exceptions are raised along the way if there is not exactly one matching
file, or if its contents are not as expected.

HTH,

Rob



use strict;
use warnings;

use Tie::File;
use File::Copy 'copy';

my $dir = '/path/to/my/directory';

opendir my ($dh), $dir;

# Find all files in the directory that match \d{6}\.htm
# Die if none or multiple files found
#
my @files = grep /\A\d{6}\.htm\z/i, readdir $dh;
die 'No matching files found' unless @files;
die 'Multiple matching files found' if @files  1;
my $file = $files[0];

# Copy the file for safety
# Tie it to an array
#
(my $copy = $file) =~ s/(\.htm)\z/ - Copy$1/i;
copy $file, $copy;
tie my @lines, 'Tie::File', $copy;

my $index;

# Find the first line starting with a class=nolinkunderline
# Remove it and the following line
#
($index) = grep $lines[$_] =~ /\Aa class=nolinkunderline/, 0 .. $#lines;
die 'No class=nolinkunderline found' unless $index;
splice @lines, $index, 2;

# Find the first line equal to pre
# Append the contents of the file with the same name and a .txt type
#
($index) = grep $lines[$_] eq 'pre', 0 .. $#lines;
die 'No pre found' unless $index;
(my $txtfile = $file) =~ s/\.htm/.txt/i;
my $text = do {
  open my $fh, '', $txtfile or die qq{Unable to open $txtfile: $!};
  local $/;
  $fh;
};
$lines[$index] .= $text;

# Find the first line equal to /div/body
# Replace it with the contents of the DATA segment
#
($index) = grep $lines[$_] eq '/div/body', 0 .. $#lines;
die 'No /div/body found' unless $index;
chomp(my @replace = DATA);
splice @lines, $index, 1, @replace;

untie @lines;

__DATA__
/div
script type=text/javascript
var sc_project=8607440;
var sc_invisible=1;
var sc_security=f3cd5e09;
var scJsHost = ((https: == document.location.protocol) ?
https://secure.; : http://www.;);
document.write(sc+ript type='text/javascript' src=' +
scJsHost+
statcounter.com/counter/counter.js'/+script);
/script
noscriptdiv class=statcountera title=web analytics
href=http://statcounter.com/; target=_blankimg
class=statcounter
src=http://c.statcounter.com/8607440/0/f3cd5e09/1/;
alt=web analytics/a/div/noscript
/body



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Need help with a programming problem

2013-10-02 Thread Rob Dixon

That should read as follows:




use strict;
use warnings;

use Tie::File;
use File::Copy 'copy';
use File::Spec;

my $dir = '/path/to/my/directory';

opendir my ($dh), $dir;

# Find all files in the directory that match \d{6}\.htm
# Die if none or multiple files found
#
my @files = grep /\A\d{6}\.htm\z/i, readdir $dh;
die 'No matching files found' unless @files;
die 'Multiple matching files found' if @files  1;
my $file = File::Spec-catfile($dir, $files[0]);

# Copy the file for safety
# Tie it to an array
#
(my $copy = $file) =~ s/(\.htm)\z/ - Copy$1/i;
copy $file, $copy;
tie my @lines, 'Tie::File', $copy;

my $index;

# Find the first line starting with a class=nolinkunderline
# Remove it and the following line
#
($index) = grep $lines[$_] =~ /\Aa class=nolinkunderline/, 0 .. $#lines;
die 'No class=nolinkunderline found' unless $index;
splice @lines, $index, 2;

# Find the first line equal to pre
# Append the contents of the file with the same name and a .txt type
#
($index) = grep $lines[$_] eq 'pre', 0 .. $#lines;
die 'No pre found' unless $index;
(my $txtfile = $file) =~ s/\.htm/.txt/i;
my $text = do {
  open my $fh, '', $txtfile or die qq{Unable to open $txtfile: $!};
  local $/;
  $fh;
};
$lines[$index] .= $text;

# Find the first line equal to /div/body
# Replace it with the contents of the DATA segment
#
($index) = grep $lines[$_] eq '/div/body', 0 .. $#lines;
die 'No /div/body found' unless $index;
chomp(my @replace = DATA);
splice @lines, $index, 1, @replace;

untie @lines;

__DATA__
/div
script type=text/javascript
var sc_project=8607440;
var sc_invisible=1;
var sc_security=f3cd5e09;
var scJsHost = ((https: == document.location.protocol) ?
https://secure.; : http://www.;);
document.write(sc+ript type='text/javascript' src=' +
scJsHost+
statcounter.com/counter/counter.js'/+script);
/script
noscriptdiv class=statcountera title=web analytics
href=http://statcounter.com/; target=_blankimg
class=statcounter
src=http://c.statcounter.com/8607440/0/f3cd5e09/1/;
alt=web analytics/a/div/noscript
/body


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: formatting a list

2013-09-28 Thread Rob Dixon

On 28/09/2013 06:59, Rajeev Prasad wrote:

hello,

following is obtained by concatenating 3 values using an underscore to
produce a list:

|abc_12_4567
xy4z_xtr4_sdf
PQRSDR_xcvf_scc234|

i want them to look neat, something like this: where they look in line.
I do not know before hand how long each word would be

|abc124567
xy4z___xtr4__sdf
PQRSDR_xcvf__scc234|


how could i use the sprintf to obtain such an effect?


You could build a format into a separate variable, using the maximum
length of each column as the field size.

Because sprintf will pad only with spaces (or zeroes) you need to
transliterate once the lines are built.

This program demonstrates. Note that the statement modifier

for 1 + max map length($_-[$i]), @data;

doesn't loop at all: it just serves to contextualize the calculation
into $_.

Rob


use strict;
use warnings;

use List::Util 'max';

my @data = (
  [qw/ abc 12 4567 /],
  [qw/ xy4z xtr4 sdf /],
  [qw/ PQRSDR xcvf scc234 /],
);

my $format;
for my $i (0.. $#{$data[0]}-1) {
  $format .= %-${_}s for 1 + max map length($_-[$i]), @data;
}
$format .= %s\n;

for my $row (@data) {
  (my $line = sprintf $format, @$row) =~ tr/ /_/;
  print $line;
}

**output**

abc12___4567
xy4z___xtr4_sdf
PQRSDR_xcvf_scc234


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: formatting a list

2013-09-28 Thread Rob Dixon

On 28/09/2013 06:59, Rajeev Prasad wrote:

hello,

following is obtained by concatenating 3 values using an underscore to
produce a list:

|abc_12_4567
xy4z_xtr4_sdf
PQRSDR_xcvf_scc234|

i want them to look neat, something like this: where they look in line.
I do not know before hand how long each word would be

|abc124567
xy4z___xtr4__sdf
PQRSDR_xcvf__scc234|


how could i use the sprintf to obtain such an effect?


If you prefer, or if there is any possibility that the fields may 
themselves contain spaces, you can build an array of maximum field 
widths and use a bespoke pad subroutine.


Rob

use strict;
use warnings;

use List::Util 'max';

my @data = (
  [qw/ abc 12 4567 /],
  [qw/ xy4z xtr4 sdf /],
  [qw/ PQRSDR xcvf scc234 /],
);

my @widths;
for my $i (0.. $#{$data[0]}) {
  push @widths, max map length($_-[$i]), @data;
}

for my $row (@data) {
  my $line;
  $line .= pad($row-[$_], 1+$widths[$_]) for 0 .. $#$row-1;
  $line .= $row-[-1];
  print $line, \n;
}

sub pad {
  my ($string, $length) = @_;
  for ($length - length $string) {
$string .= '_' x $_ if $_  0;
  }
  $string;
}

**output**

abc12___4567
xy4z___xtr4_sdf
PQRSDR_xcvf_scc234


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: checking for file existence

2013-09-26 Thread Rob Dixon

On 25/09/2013 20:38, RENATO AUGUSTO CORREA DOS SANTOS wrote:

Hi, all.

I am a very begginer in PERL starting today in this mailing list! :-) I
will try to work especially with Bioinformatics.

I am trying to verify the existence of a file in PERL; however, is seems
not to work. It always returns The file $file_seqs does not exist!!!.

Do you know where I am making a mistake?

code
#!/usr/bin/perl

use strict;

my $file_seqs;

$file_seqs = $ARGV[0];

 if (!-e $file_seqs) {
 print The file $file_seqs does not exist!!! \n;
 exit(0);
 }
 else{
 print The file $file_seqs exist!!! \n;
 }


Hello Renato and welcome.

You should also *always*

use warnings;

as it will help you to debug your Perl code.

The rest of your program presumably depends on the existence of the
input file, and you need to open and read it. because of this it is
usual to leave it to the `open` statement to check whether there is a
problem of _any_ sort opening the file, so you would write

use strict;
use warnings;

my $file_seqs = $ARGV[0];

open my $fh, '', $file_seqs or die Unable to open $file_seqs: $!;

print The file $file_seqs existsand has been opened\n;

And if there is no such file you would get

Unable to open 'myfile': No such file or directory at 
E:\Perl\source\open.pl line 6.


HTH,

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash function and combining function/operator

2013-09-23 Thread Rob Dixon

On 23/09/2013 23:17, David Christensen wrote:

beginners:

I'm looking for a hash function and a related function or operator such
that:

 H(string1 . string2) = f(H(string1), H(string2))

 H(string1 . string2) = H(string1) op H(string2)


Hi David

My immediate thought is that the only hash function that can work like
this is the identity function (or any one-one mapping) because, by
extension, the hash of a string must be equal to f(the hash of each of
its characters).

Not that I can prove this at present, of course!

Could you explain the problem you're trying to solve?

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Puzzled by ouput from this script

2013-09-11 Thread Rob Dixon

On 11/09/2013 23:04, Harry Putnam wrote:


Posted below is a shortened down version of a larger script that tries
to show the phenomena I'm seeing and don't understand.

open my $fh, '', $log  or die Can't open $log: $!;
print  $dtf START $rsync $shortargs\n   $longargs\n  $src/ $dst/\n\n;
open my $cmdh, '-|', $rsync $shortargs $longargs $src/ $dst/ or die ERROR running 
$rsync: $!;

while ($cmdh) {
   print $fh;
   print;
}


The problem is with the line `print $fh`. I presume you intend it to
print the contents of $_ to the file handle $fh. Unfortunately that
isn't the guess that Perl makes: it assumes you want to print the
*value* of $fh to file handle STDOUT. Fix it by writing

print $fh $_;

I also suggest that you don't write multi-line output with a single
print statement like that. It is much clearer written as

print  $dtf START $rsync $shortargs\n;
print$longargs\n
print   $src/ $dst/\n\n;

or you could use a here document and write it like this

print END;
 $dtf START $rsync $shortargs
   $longargs
  $src/ $dst/

END

but you have to be very careful with indentation if you do that, as
leading and trailing space is significant, and Perl will be looking for
a line that contains *exactly* `END`, with no spaces before or after it.
Note that you can use any string you like instead of `END`; the only
condition is that the characters after `` must exactly match the line
that terminates the string.

HTH,

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Filtering Characters

2013-09-04 Thread Rob Dixon

On 04/09/2013 03:58, Michael Rasmussen wrote:

On Wed, Sep 04, 2013 at 02:31:30AM +0100, Rob Dixon wrote:

John's solution:
 next if /[^[:lower:]_\d\-. ]/;


Doesn't work in this test environment:
 michael@bivy:~$ cat tpl  ./tpl
 #!/usr/bin/perl
 use strict;
 use warnings;

 print \nJohn's solution\n;
 while(DATA) {
 print Seen line: $_;
 next if /[^[:lower:]_\d\-. ]/;
 print;
 }

 __DATA__
 a good line
 Testing John code
 a #!! should not print line
 _ Should be OK line
 finish with a printing line

 John's solution
 Seen line: a good line
 Seen line: Testing John code
 Seen line: a #!! should not print line
 Seen line: _ Should be OK line
 Seen line: finish with a printing line


John's solution is to take this original program

while (IN) {
  chomp;
  next if /^#/;
  # do stuff
}

and correct it by altering the `next` statement to this

next if /[^[:lower:]_\d\-. ]/;

The resulting program executes the line `# do stuff` with only

a good line
finish with a printing line

which is correct. Your line `_ Should be OK line` is excluded because it
contains capital letters.

Rob








--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Recursive Validation Function

2013-09-03 Thread Rob Dixon

On 03/09/2013 02:23, John Aten wrote:

Hello all,

I am writing a script to rename files. The script prompts the user
to enter tokens which will comprise part of the file name. These are
 made of letters and numbers separated by a dot, ie: R.3. The
letters can be R, I or C, upper or lowercase. The first number can be
one through eight, and if it is a six there can be an additional dot
followed by a one or two. To make sure that I don't make any
mistakes when putting in these tokens, I have tried to write a
function to make sure that they are valid:

sub validate_tokens {
if ($_ !~ /^[ric]\.[1234578]$/i) {
if ($_ !~ /^[ric]\.6(\.[1|2])?$/i) {
print Enter valid tokens: ;
my $new_token = STDIN;
chomp $new_token;
validate_tokens($new_token);
}
}
return $_;
}


I'm calling it like this:

print Enter Tokens: ;
my $token = STDIN;
chomp $token;
my $valid_token = validate_tokens($token);


Too bad it doesn't work! Even if I put in valid tokens on the first shot, there 
are errors:

Use of uninitialized value $_ in pattern match (m//) at bulk.pl line 65, 
STDIN line 3.
Use of uninitialized value $_ in pattern match (m//) at bulk.pl line 66, 
STDIN line 3.

Lines 65 and 66 are the ones with the two if statements, lines 2 and
3 of the first code snippet above. Each time I run it, the STDIN
line number in the error message increases by one. The script goes
into an infinite loop, prompting for valid tokens, but even if valid
ones are entered it continues. What am I missing?


As has been explained, the parameter to your subroutine is in @_. $_ 
could contain anything, and clearly is undefined at this point.


It is also a misuse of recursion as it stands. You should use the 
subroutine just for verification, and put a reprompt loop outside it.


Try this for your subroutine

sub validate_tokens {
  $_[0] =~ /^[ric]\.(?:6\.[12]|[1-8])$/i;
}

and call it like this

my $token;
print Enter Tokens: ;
while () {
  $token = STDIN;
  chomp $token;
  last if validate_tokens($token);
  print Enter valid tokens: ;
}

HTH,

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Recursive Validation Function

2013-09-03 Thread Rob Dixon

On 03/09/2013 06:56, Jim Gibson wrote:


For readability, use the extended form and the more modern
zero-width  assertions \A and \z:

if ( $_[0] !~ m{ \A [ric] \. (?:[1-578]) | (?:6 (\.[12])? ) \z }ix ) {


Hi Jim

You have incorrect parentheses. Your regex matches

\A [ric] \. (?:[1-578])

or

(?:6 (\.[12])? ) \z

which isn't what is wanted at all!

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Filtering Characters

2013-09-03 Thread Rob Dixon
Matt matt.mailingli...@gmail.com wrote:
I have this:

while (IN) {
chomp;
next if /^#/;
# do stuff
}


It skips to the next item in the while loop of the string begins with
# and works fine.  I would also like to skip to the next item in the
loop if the string contains anything other then lowercase,
underscores, numbers, dashes, periods, and spaces.  I do not want
uppercase characters and any sort of other special characters.  How
would I do that?

The solution from John Krahn is superior by far, and there is no need for any 
other suggestions.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Make a sub routine return

2013-08-28 Thread Rob Dixon

On 28/08/2013 16:48, Harry Putnam wrote:


The code below was a script by itself but now I need to turn it into a
function inside a larger script... I've done something that sort of
works but fails on a specific file name that looks like `.#somefile'.


What does fails mean? Does it crash?, produce an error message?, seem
to work but have no effect?...

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-28 Thread Rob Dixon

On 28/08/2013 19:06, John W. Krahn wrote:

Rob Dixon wrote:


use strict;
use warnings;
use autodie;

my $rsync = 'rsync';
my $tmplog = 'one.log';
my $tmplog2 = 'two.log';

my %logs = map {
open my $FH, '', $_;


What if open fails?!


I have `use autodie`.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-27 Thread Rob Dixon

On 27/08/2013 23:06, John W. Krahn wrote:

Harry Putnam wrote:


I happen to be scripting something that needs to have two logs written
to and was sort of taken by how awkward this construction looked:

(Simplified for discussion, from a longer script)

   my $rsync = 'rsync';
   my $tmplog = 'one.log';
   my $tmplog2 = 'two.log';
   open(LOG,$tmplog)or die Can't open $tmplog : $!;
   open(LOG2,$tmplog2)or die Can't open $tmplog2: $!;
   print LOG  kdkdkdkd Output from:\n$rsync cmdflgs;
   print LOG2 kdkdkdkd Output from:\n$rsync cmdflgs
   close(LOG);
   close(LOG2);

Is there some smooth way to write to more than one log?


my %logs = (
 'one.log' = undef,
 'two.log' = undef,
 );

for my $name ( keys %logs ) {
 open my $FH, '', $name or die Cannot open '$name' because: $!;
 $logs{ $name } = $FH;
 }

for my $log_FH ( values %logs ) {
 print $log_FH kdkdkdkd Output from:\n$rsync cmdflgs;
 }


Nice John

It compacts neatly to

use strict;
use warnings;
use autodie;

my $rsync   = 'rsync';
my $tmplog  = 'one.log';
my $tmplog2 = 'two.log';

my %logs = map {
open my $FH, '', $_;
($_ = $FH);
} $tmplog, $tmplog2;

print $_ kdkdkdkd Output from:\n$rsync cmdflgs\n for values %logs;


Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: string match question

2013-08-21 Thread Rob Dixon

On 21/08/2013 18:32, Natxo Asenjo wrote:

hi,

thanks all for your advice. I have just used one of your suggested
regex to accomplish this task:

if ( $text =~ /.*(critical alarm.*?)\./i ) {
 my $message = $1;
 print $message, \n;
}

This captures everything starting with critical alarm until it finds a
dot (non greedy).

I agree with Rob Dixon I should be parsing the html, but unfortunately
getting it was proving more complicated than this. If this check
breaks with a firmware update then we will have to see wat we do then,
these things do not get updates so often, fortunately.


There is no problem getting the HTML of the page.

In the same place where you have

$mech-text

you can write

$mech-content

and you will get the unparsed HTML instead of the text will the HTML
stripped out.

HTH,

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: string match question

2013-08-20 Thread Rob Dixon

On 20/08/2013 15:02, Natxo Asenjo wrote:

hi,

for a nagios (monitoring system) check I need to scrape a web site
(this is for a network device, a UPS, whatever). This particular
device only offers some functionality through a web interface.

I am only interested in the text '1 Critical Alarm PresentA site
wiring fault exists'; is it possible to match this is a simple way (in
fact, the text after 'Critical Alarm Present' may vary, it would be
awesome to be able to get that easily. Otherwise I am afraid I will
have to start parsing html with HTML::TableExtract


Parsing the HTML is absolutely the right way to do this. It's not that
hard. If you put a sample of the HTML up (perhaps on pastebin?) then
someone will code it for you. Better that way than writing some
unreliable regular expression that may fail one day with a text string
you haven't thought of, or an update to the device firmware.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Single equals operator inside an if statement

2013-08-14 Thread Rob Dixon

On 14/08/2013 18:21, Alexey Mishustin wrote:


If I make a typo and write a single equals operator here:

if ($foo = 2) {
print yes\n;
}

...then the warnings pragma works OK and tells me Found = in
conditional, should be ==...

But if I make the same typo and write a single equals operator there:

if ($foo = $bar) {
print yes\n;
}

... then I get no warning; the script output is yes.

Why is it so?

How could I catch such typos?


The `warnings` pragma catches the first form because the value of the
conditional is a *constant* 2, so the body of the `if` will *always* be
executed and it is a fair guess that the problem is `=` instaed of `==`.

In the second case the execution depends on the value of `$bar`, and it
is a reasonable thing to write if, say, you wanted to test a value and
assign it to a temporary variable at the same time. Perl cannot know
that the code was unintentional and will not warn you.

I have checked both Perl::Critic and B::Lint, and neither of these check
for an assignment operator in a conditional expression. The only thing
way I can think of doing this is to write a plugin for B::Lint, which
accepts Module::Pluggable plugins. It may be possible to write something
that will do what you want.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: parsing html

2013-08-08 Thread Rob Dixon

On 08/08/2013 18:18, David Precious wrote:

On Thu, 8 Aug 2013 22:42:01 +0530
Unknown User knowsuperunkn...@gmail.com wrote:


What would be the best module available for parsing html in your
opinion? My intention is to parse html that contains a table of 5
columns and any number of rows


For parsing HTML tables, you want HTML::TableExtract, IMO.


Yes. It would help if you explained more about what you want to do, and
showed some HTML rather than just the desired data structure, but
HTML::TableExtract seems to be the right module for this.

There are better HTML parsers for general purposes. XML::LibXML will
handle HTML, and HTML::TreeBuilder is nice.

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Parsing Data

2013-07-23 Thread Rob Dixon

On 23/07/2013 14:39, Shlomi Fish wrote:

Hi Rob,

I recommend against using XML::XPath because it's been undermaintained, is
slower than XML::LibXML's XPath support, may be more incomplete and I believe
it has poorer support for XML namespaces.

Instead one should use https://metacpan.org/module/XML::LibXML::XPathContext ,
which is part of XML-LibXML, which for completeness' sake I'd like to note that
I am its primary maintainer, so I may be biased. But recommending to use XPath
for that ( http://en.wikipedia.org/wiki/XPath ) is a good idea.


Hello Shlomi

Thank you for declaring your interest in the subject of your evangelism.
As you say, XML::LibXML is *your* module (or at least, you are
maintaining it) just as perl-begin.org is *your* website, and common
wisdom says that in such circumstances you should refrain from promoting
either of them altogether. If you insist on doing so anyway then I wish
you would make your declarations a *lot* more prominent, i.e. the
*first* thing you say in your post, rather than a subsidiary clause in a
secondary paragraph.

I try to avoid recommending XS-based modules when I sense that the OP
may have trouble digging himself out of a hole when a CPAN module has
failed to install. XML::XPath works fine here. It is plenty fast enough,
and the data doesn't use namespaces. You have no reason to disparage it.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Parsing Data

2013-07-23 Thread Rob Dixon

On 23/07/2013 19:00, Shlomi Fish wrote:


Why do you feel that I've been promoting XML::LibXML in this thread?


Because you say


Instead one should use [XML::LibXML]


I call that promotion.


Why does the fact that I'm affiliated with it, prevent me from
recommending it over a different alternative, which I believe (and
can prove) that is inferior?


Because it is all but impossible for you to be impartial with your
recommendations when you have a specific interest in one of the
alternatives.


If you insist on doing so anyway then I wish you would make your
declarations a *lot* more prominent, i.e. the *first* thing you say
in your post, rather than a subsidiary clause in a secondary
paragraph.


Why do you feel I should do so? What was wrong with the disclaimer as
it stood?


Because I missed it the first time I read your post, so it isn't
unlikely that others would also overlook it.


I try to avoid recommending XS-based modules when I sense that the OP
may have trouble digging himself out of a hole when a CPAN module has
failed to install.


Well, XML::XPath depends on XML::Parser which is an XS module (and not a core
one)


This is one of those facts that I thought I had once established for
certain and have never looked at again. I am grateful to be corrected.

However, I believe the XS component of XML::LibXML relies, in turn, on
the libxml2 library, which also needs compiling and linking. With yet
another process involved in installing the module I am still hesitant to
recommend (although I have the highest regard for Libxml2 itself).


XML::XPath works fine here. It is plenty fast enough,
and the data doesn't use namespaces. You have no reason to disparage it.


The original poster may need to use namespaces, and he may run into a bug that
has crept in XML::XPath since its last release in 2003, and the data may be
larger than you are trying it on. As a result, I can no longer recommend it in
the general case.


In my original answer I wrote


This program shows just how easy it is to use `XML::XPath`. There are
several other modules that will do the job if this one isn't to your taste.


So I hope I wasn't understood to be recommending XML::Xpath in the
general case. In part I was trying to give another module some exposure,
when the limelight is usually shared between XML::LibXML and XML::Twig.
It certainly works fine with the data in question and I would not choose
to avoid it just because of its age when I know that there are many
instances of much older installations of Perl itself. There are many
examples of much less satisfactory modules, such as the dreadful but
still-popular XML::Simple which was updated just a year ago.

I hope this clarifies my standpoint.

Rob






--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: grab pattern from start and end block

2013-07-13 Thread Rob Dixon

On 12/07/2013 12:44, Agnello George wrote:

hi

i have raw data that is like this in a flat file .

start
name:agnello
dob:2 april
address:123 street
end
start
name:babit
dob:13 april
address:3 street
end
start
name:ganesh
dob:1 april
address:23 street
end


i need to get the data in the following format

name:agnello, dob:23 april ,address:123 street
name:babit,dob:13 april,address:3 street
name:ganesh,dob:1 april,address:23 street


perl -0777 -ne s/\s*\n/,/g;s/start,//g;s/,end,/\n/g; print data.txt

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: grab pattern from start and end block

2013-07-12 Thread Rob Dixon

On 12/07/2013 12:44, Agnello George wrote:

hi

i have raw data that is like this in a flat file .

start
name:agnello
dob:2 april
address:123 street
end
start
name:babit
dob:13 april
address:3 street
end
start
name:ganesh
dob:1 april
address:23 street
end


i need to get the data in the following format

name:agnello, dob:23 april ,address:123 street
name:babit,dob:13 april,address:3 street
name:ganesh,dob:1 april,address:23 street

i came up with this , is there a better way to do this :
===
#!/usr/bin/perl

use strict;
use warnings;

open my $FH , 'data.txt' or die cannot open file $!;
read $FH, my $string, -s $FH;
close($FH);


my @string = split ( /start/ , $string ) ;

my %data;

foreach  ( @string ) {
chomp;
next if /^$/ ;
s/^ $//g;
s/end//;

my @data = split(/\n/, $_);
   foreach my $i (@data) {
print $i,;

  }
print \n;
}


Hi Agnello

Your code (almost) works, but it isn't very Perlish. Here are some
comments that I hope will help you.

- Your open is good because it uses a lexical file handle, checks the
success of the open, and puts $! in the die string. But the file handle
identifier should be lower case (upper case is reserved for globals) and
you should have an open mode '' for the second parameter.

- That is an unconventional way to read the entire file into memory.
Usually you would temporarily undefine the input record separator $/ and
just use $fh to read the entire file in one go.

- @string is a poor choice of identifier for a list of records.

- `next if /^$/` isn't very useful as it will have no effect unless
there are two `start` lines in succession.

- s/^ $//g deletes the whole record if it is a single space. That can't
happen. I think you meant s/^ // to delete spaces from the beginning of
the record. Better still is s/^\s+//, which will also delete the newline
remaining after `start `.

- It is almost never correct to put scalar variables on their own inside
double quotes. You want `split(/\n/, $_)` or, since $_ is the default
parameter, just `split /\n/`.

- $i is a poor choice of identifier for lines in a record. $i is usually
used for an array index.

Combining those, your program looks like this

use strict;
use warnings;

my $string;
{
  open my $fh, '', 'data.txt' or die cannot open file $!;
  local $/;
  $string = $fh;
}

my @records = split /start/, $string;

foreach (@records) {
  chomp;
  s/^\s+//g;
  s/end//;

  my @data = split /\n/;
  print $_, for @data;

  print \n;
}

As for how I would do it, I am always inclined to read data into an
internal Perl data structure and then output it again. That allows for
manipulation of the data before it is displayed and gives far more
control over the output.

This is what I would write. It keeps the data in each record in hash
%data, which is emptied when a `start` line is seen and printed when an
`end` line is seen.

use strict;
use warnings;

open my $fh, '', 'data.txt' or die $!;

my %data;
while ($fh) {
  if (/start/) {
%data = ();
  }
  elsif (/end/) {
print join(',', map $_:$data{$_}, qw/ name dob address /), \n;
  }
  else {
chomp;
my ($k, $v) = split /:/;
$data{$k} = $v if $v;
  }
}

giving the output

name:agnello,dob:2 april,address:123 street
name:babit,dob:13 april,address:3 street
name:ganesh,dob:1 april,address:23 street





--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: grab pattern from start and end block

2013-07-12 Thread Rob Dixon

On 12/07/2013 13:30, Agnello George wrote:


could i use local $/   instead of   $INPUT_RECORD_SEPARATOR


Yes, and you should do that. The extended variable names are almost 
never used and will mostly confuse people familiar with Perl.


Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: grab pattern from start and end block

2013-07-12 Thread Rob Dixon

On 12/07/2013 13:56, Shawn H Corey wrote:

On Fri, 12 Jul 2013 13:51:01 +0100
Rob Dixon rob.di...@gmx.com wrote:


On 12/07/2013 13:30, Agnello George wrote:


could i use local $/   instead of   $INPUT_RECORD_SEPARATOR


Yes, and you should do that. The extended variable names are almost
never used and will mostly confuse people familiar with Perl.


Except that Damian Conway of Perl Best Practice recommends:

use English   qw( -no_match_vars );  # Avoids regex performance penalty


Yes, he says that, but he says nothing about using
$INPUT_RECORD_SEPARATOR. His principle is

 use English for the less-familiar punctuation variables.

and there is a good case for claiming that $/ is a more familiar such
variable.

I, for one, would have to check `perlvar` to make sure that
$INPUT_RECORD_SEPARATOR and $/ were in fact the same thing, and most
others would as well.

What is also misleading in your code is the use of

use charnames qw( :full :short   );

which has no effect whatsoever on the rest of the program, and so
should be ommitted.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: printing content of a pipe

2013-06-28 Thread Rob Dixon

On 28/06/2013 02:32, Uri Guttman wrote:


you don't need
ever to set $| on stderr as it is not buffered like stdout is. and you
rarely need to set it on stdout as any print with a \n will flush stdout.


That isn't true.

Perl will buffer STDOUT up to 8KB regardless of whether a newline has
been printed, unless `autoflush` has been enabled when it will flush
after every print `statement`.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: accessing variables in subroutines

2013-06-27 Thread Rob Dixon

On 27/06/2013 11:58, lee wrote:

Shlomi Fish shlo...@shlomifish.org writes:


lee l...@yun.yagibdah.de wrote:


the following example doesn't compile:

use strict;
use warnings;

sub test {
 print $counter . \n;
}

my $counter = 0;
while($counter  5) {
 test();
 $counter++;
}


It says Global symbol $counter requires explicit package name 
When I put the subroutine after the 'while' loop, it works just fine, so
what's the problem?


The subroutine does not see the lexical $counter variable because it was
declared after its scope.


The subroutine is never called before $counter is declared, so it is
always available to the subroutine.  There should be an error only for
instances when the subroutine is called before $counter is declared.


For more information, see:

* http://www.plover.com/FAQs/Namespaces.html


Ok, so perl has a totally broken design with variables :(  What's the
solution to this problem?  I do not want to:


+ define the subroutines after the program

+ carry the needed variables all over the place as parameters to every
   function that might need it

+ declare the variables on top of the program because that increases
   their scope too much


Reading [1] would indicate that it is an extremely bad idea in perl to
have global (package) variables because they cannot be local to the
program that uses them because all programs are packages the variables
of which can be accessed from other packages.  You also cannot use a
package name and use that for variables like $Mypackage::counter because
in case you ever change the name of the package, you'll have to go
through all the code and adjust the names of such variables.  It
wouldn't really solve the problem, either, because the variables could
still be accessed from outside the program.  So now I don't want to have
global (package) variables, either.


In the particular application I have this problem with, I could create a
hash holding all the information that might be needed by subroutines and
carry that all over the place in their parameters.  In C, I would create
a structure containing the needed information and simply carry a pointer
to the structure.  That would be much more efficient than handing over a
hash, effectively copying all the data the hash may contain every time.

How do you do that in perl?


I don't think it's possible to satisfy your wishes Lee. You want a 
subroutine that's declared *before* a variable to have access to that 
variable, yet you don't want to declare the variables on top of the 
program because that increases their scope too much.


Surely, giving a subroutine access to a variables that are yet to be 
declared also increases their scope too much?


It is certainly a bad idea to predeclare everything, but a Perl variable 
must be declared before all the code that accesses it. The usual way is 
to declare variables immediately before their first point of use (as in 
your sample code) and put subroutine definitions at the end of the 
program. Since you particularly object to putting subroutine 
declarations you should look at another language, although none come to 
mind that allow a variable to be accessed prior to its declaration.


There are other solutions depending on the program's control flow. In 
this case the variable should clearly be a parameter anyway, and the 
code should look like this


use strict;
use warnings;

sub test {
  my ($val) = @_;
  print $val\n;
}

for my $counter (0 .. 4) {
  test($counter);
}

Your description of creating an aggregate data item and passing it 
everywhere sounds much like using a global variable to me, however it is 
quite possible. Something like this may help you


use strict;
use warnings;

do_something({ title = 'TEST', value = 42 });

sub do_something {
  my ($params) = @_;
  print $params-{title}, \n;
  do_something_else($params) for 1 .. 3;
}


sub do_something_else {
  my ($params) = @_;
  print $params-{value}, \n;
}

HTH,

Rob










--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: last

2013-06-27 Thread Rob Dixon

On 27/06/2013 16:03, Shawn H Corey wrote:

On Thu, 27 Jun 2013 07:45:17 -0700
Jim Gibson jimsgib...@gmail.com wrote:


Note that the statement modifier syntax allows you to write a
do-while or do-until loop, where at least one pass is made through
the loop before the loop termination test is performed:

do {
   …
} while condition();

The while here is a statement modifier, and the do{} is a single
statement with one or more internal statements grouped as one.


Please don't use a do...while loop. Technically, it's not a loop and
`last`, `next`, and `redo` won't work as you would expect. They will
either jump back to the last `for` or `while` loop, or exit the
subroutine.


That advice is unnecessarily prescriptive. The best you can say is that
it is as well to be aware of those restrictions when using the
do...while construct. I hope you can refrain from ordering people about.

do...while is less likely to be used together with embedded flow-control
commands, because it is a very specific loop structure on its own.
Without it the loop would have to be written

while () {
CODE;
last if CONDITION;
}

which is unnecessarily ugly. Or even worse

CODE;
while (CONDITION) {
CODE;
}

which is unadvised because of the repetition of identical code sequences.

Far better to use just

do {
  CODE;
} while CONDITION;

and bear in mind the provisos that you list.

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Please exempt the book Modern Perl from Web Commercials on http://perl-begin.org/

2013-06-26 Thread Rob Dixon

On 26/06/2013 10:32, Shlomi Fish wrote:


Hi,

  Could you please let me know how to reverse a string without using built
in function.


Do you want to avoid using the http://perldoc.perl.org/functions/reverse.html
built-in function or any built-in function whatsoever? Assuming the latter you
can do this:

[CODE]
#!/usr/bin/perl

use strict;
use warnings;

sub my_reverse
{
 my ($s) = @_;

 my $ret = ;

 for my $idx (0 .. length($s) - 1)
 {
 $ret = substr($s, $idx, 1) . $ret;
 }

 return $ret;
}

my $string = shift(@ARGV);

print Reversed is:\n, my_reverse($string), \n;
[/CODE]

Running it gives you:

[SHELL]

shlomif@telaviv1:~$ perl my-reverse.pl Hello
Reversed is:
olleH
shlomif@telaviv1:~$ perl my-reverse.pl Franklin
Reversed is:
nilknarF
shlomif@telaviv1:~$

[/SHELL]


I don't understand. You say you are providing a solution that avoids
any built-in function whatsoever, and then use `length` and `substr`.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Fw: Please exempt the book Modern Perl from Web Commercials on http://perl-begin.org/

2013-06-26 Thread Rob Dixon

On 26/06/2013 10:18, Franklin Lawerence wrote:


Hi,

  Could you please let me know how to reverse a string without using built
in function.


Hi Franklin

Is this homework? I can think of no other reason to need what you are
asking for.

It is best to say if you are asking for help with homework, as the
answers will be phrased to help you to learn instead of helping you out
of a hole.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Lines written to a file are not contiguous

2013-05-08 Thread Rob Dixon

On 08/05/2013 10:24, Shlomi Fish wrote:


This is better:

http://perl-begin.org/tutorials/bad-elements/#properly_autoflushing


print `cat * foo.out`;  # [2] qx//


This is the same as «system('cat *  foo.out')» (only more costly), and the
command in this case should not emit any output (because it is redirected to a
file). Furthermore, many non-UNIX-like systems don't contain a cat command. See:

http://perl-begin.org/tutorials/bad-elements/

Regards,

Shlomi Fish



It would make me feel a lot better if you would declare your interest in
your own web site when you link to it. It's hardly an endorsement if you
link to something else you have written yourself.

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Lines written to a file are not contiguous

2013-05-08 Thread Rob Dixon

On 08/05/2013 14:16, Shlomi Fish wrote:

See:

http://perl-begin.org/tutorials/bad-elements/

Regards,

Shlomi Fish



It would make me feel a lot better if you would declare your interest in
your own web site when you link to it. It's hardly an endorsement if you
link to something else you have written yourself.


I'm giving that page on Perl-Begin, as a resource where people can find
more information about my advice, not as an act of endorsement.


Whatever your reasons, I wish you would make it clear that it was just
more of your own words.

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Pattern match operator

2013-05-04 Thread Rob Dixon

On 04/05/2013 14:26, Florian Huber wrote:


I'm parsing a logfile and don't quite understand the behaviour of m//.

 From a previous regex match I have already captured $+{'GFP'}:

use strict;
use warnings;

(...)

$text =~ m/ (?GFPFILTERS .*? WRT)/x;# I simply have my whole
logfile in $text - I know there are better solutions.
print $+{'GFP'}, \n;

prints this:
FILTERS GFP,GFP,100% ACTSHUT 17 AVG 4,1.00 WRT

Now I want to go on parsing $+{'GFP'}. To be more precise, I want to
capture AVG 4:

If I do:

$+{'GFP'} =~ m/(?AVGAVG\s\d);
print \$+{'GFP'} is $+{'GFP'}.\n;

I get a warning that I'm using an uninitialised value and:

$+{'GFP'} is .
$+{'AVG'} is AVG 4.

So first question: Apparently some return value of $+{'GFP'} =~
m/PATTERN/; messes with this hash value. So from what I can remember,
the return value will indicate if the substitution was successful or
not. Then why don't I get some value like 0 or 1 in $+{'GFP'} but just
an uninitialised value?

If the match is not successful, $+{'GFP'} will stay untouched:

  $+{'GFP'} =~ m/(?AVGAVG\s\d nothere);
print \$+{'GFP'} is $+{'GFP'}.\n;
print \$+{'AVG'} is $+{'AVG'}.\n;

will print:
$+{'GFP'} is FILTERS GFP,GFP,100% ACTSHUT 17 AVG 4,1.00 WRT.
$+{'AVG'} is .

Not surprisingly, $+{'AVG'} is uninitialised here.

It didn't quite make sense to me but I figured that the problem might be
that m// in list context returns a list of the capture variables created
in the match. So I tried:

$+{'GFP'} =~ scalar m/(?AVGAVG\s\d)/;
print \$+{'GFP'} is $+{'GFP'}.\n;
print \$+{'AVG'} is $+{'AVG'}.\n;

prints this:
$+{'GFP'} is FILTERS GFP,GFP,100% ACTSHUT 17 AVG 4,1.00 WRT.
$+{'AVG'} is .

So now the match suddenly fails?!?


Hello Florian

First a couple of points

- Don't use named captures for simple regexes like this. They make the
code harder to understand, and are really only useful when using complex
patterns with multiple captures

- The built-in variables that relate to regular expressions are modified
by every successful pattern match. It is safer to save values that you
may want to use later in a sperate variable. In particular, your regex
m/(?AVGAVG\s\d)/ matches and, because there is no capture named `GFP`
it sets the corresponding element of %+ to undef. However $+{AVG} is now
set, as you did have a capture with that name.

The pattern match

   $+{'GFP'} =~ m/(?AVGAVG\s\d);

is in void context (i.e. the result is being discarded. That is mostly
equivalent to scalar context as far as operator behaviour is concerned.
And you have made things worse by writing

$+{'GFP'} =~ scalar m/(?AVGAVG\s\d)/;

which is equivalent to

$+{'GFP'} =~ ($_ =~ /(?AVGAVG\s\d)/);

so it applies the pattern to the $_ variable, and uses the resut of that
match as another regex and applies that to $+{GFP}.

It would help to be able to see the format of your input data. If you
know that reading the entire file in is a bad idea then you shouldn't be
doing it.

This short piece of code does what you need, but I am sure there is a
better way.

$text =~ m/(FILTERS.*?WRT)/;
my $gfp = $1;

$gfp =~ m/(AVG\s+\d)/;
my $avg = $1;

HTH,

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Email::Sender::Simple how to set priority?

2013-04-26 Thread Rob Dixon

On 27/04/2013 00:21, Rajeev Prasad wrote:

following is still coming out as normal priority email.



use strict;
use warnings;
use Email::MIME;
use Email::Sender::Simple qw(sendmail);


my @mesg=qw(fox jumps over the);

my $subject='IMP mesg';

my $message = Email::MIME-create(
   header_str = [
 From= 'x...@abc.com',
 To  = ''y...@abc.com',
 Subject = $subject,
   ],
   attributes = {
 encoding = 'quoted-printable',
 charset  = 'ISO-8859-1',
 'X-Priority' = 1,
 'X-MSMail-Priority' = 'High',
   },
   body_str = @mesg,
);

sendmail($message);


Which email client are you using? Priority is a non-standard email
feature and it depends which headers the client looks at.

You might also want to try

Importance = 'High'

HTH,

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Any alternative for substr() function

2013-04-12 Thread Rob Dixon

On 12/04/2013 12:23, kavita kulkarni wrote:


Thanks all, got many ideas from you..

My script took ~7 min to run with data file of ~50,000 lines with
substr()/unpack() enabled and same script took ~2 min after disabling
substr()/unpack().
That led me to the conclusion that substr/unpack is taking maximum of my
time (and that I should reduce).

I have updated changes like using @_ instead of shift,  with very small
performance improvement.

For Devel::NYTProf, I need to check if my SA if he will allow me to
install.


I am worried about your figures. Two minutes for 50,000 lines is 2.4ms
per line, and that is a *huge* amount of time.

I think you should show us your data and code, as it sounds like
something is going wrong.

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Any alternative for substr() function

2013-04-10 Thread Rob Dixon

On 10/04/2013 16:45, Bob goolsby wrote:

G'Mornin' Kavita --

Before you go off on a goose chase, how do you know that substr() is going
to be a problem for you?  Have you bench-marked it?  If your file is as
large as you say, I strongly suspect that your bottleneck is going to be
I/O and any differences between unpack() and substr() will be lost in the
noise band below 1%.


Hint:

Try adding

  return ;

as the first statement of `extractFieldValue` (i.e. so that it does
nothing and returns a null string) then run your program and see how
long it takes just doing the IO.

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: no warnings inside a loop

2013-04-03 Thread Rob Dixon

On 04/04/2013 00:29, Angela Barone wrote:


I'm just curious about this.  If you put no warnings inside a loop,
is it good only for that loop, or will it be in effect until the end
of the script?


Hi Angela

The `warnings` pragma is *lexically* scoped. That means it applies to
the (rest of) the smallest enclosing block or file.

If your loop looks like

  for my $i (@list) {
no warnings;
...
  }

or

  while (my $line = ) {
no warnings;
...
  }

then the `no warnings` applies to the block enclosed by braces {...}

If you have used a statement modifier

  no warnings;
  print $_\n for @data;

then it applies from there on to the next end of block or end of file.

HTH,

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: no warnings inside a loop

2013-04-03 Thread Rob Dixon

On 04/04/2013 00:29, Angela Barone wrote:

I'm just curious about this.  If you put no warnings inside a loop,
is it good only for that loop, or will it be in effect until the end
of the script?


Also see `perllexwarn`

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: large files

2013-03-05 Thread Rob Dixon

On 05/03/2013 20:41, Chris Stinemetz wrote:

Hello List,

I am working on a script to parse large files, by large I mean 4 million
line+ in length and when splitting on the delimiter ( ; ) there are close
to 300 fields per record, but I am only interested in the first 44.

I have begin testing to see how fast the file can be read in a few
different scenarios:

while(  ) {
}

It only takes about 6 seconds to read 4,112,220 lines.

But when I introduce split as such:

while () {
 chomp($_);
 my @tokens = split( ;, $_ );
}

It takes around 7 minutes to reach eof.

I also tried using a LIMIT on split as shown below:
It helped greatly by only taking a little over 1 minute but I am curious if
there is a way to still improve the time to read in the file or is this a
reasonable time.

while () {
 chomp($_);
 my @tokens = split( ;, $_, 44 );
}



Hi Chris

My first thought is that that is probably the best you are going to get.
Note, though, that you want a limit of 45 on split to get the first 44
fields, as otherwise the 44th field will have the rest of the line attached.

Actually, assigning only the first 44 fields may speed things up, rather
than copying the trailing 256 fields to the array when you don't need
them. Try

my @tokens;
@tokens[0..43] = split /;/, $_, 45;

or perhaps

my @tokens = (split /;/, $_, 45)[0..43];

HTH,

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: separating code in two files

2013-03-02 Thread Rob Dixon

On 02/03/2013 14:37, Chris Stinemetz wrote:

On Fri, Mar 1, 2013 at 3:37 PM, Chris Stinemetz chrisstinem...@gmail.comwrote:




On Fri, Mar 1, 2013 at 11:00 AM, Shlomi Fish shlo...@shlomifish.orgwrote:


Hi Jim,

On Thu, 28 Feb 2013 11:21:59 -0800
Jim Gibson jimsgib...@gmail.com wrote:



On Feb 28, 2013, at 10:31 AM, Chris Stinemetz wrote:


I want to put a hash declaration in a separate file from the main

script.

How do I do this correctly?

perl.pl ( main script )

#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;

require lib.pl;

print Dumper \%hash;

lib.pl ( library script )

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

my %hash = (
   Version = 0,
   SRT = 11,
   SRFC = 12,
   CFC = 21,
   CFCQ = 22,
   ICell = 29,
   ISector = 30,
   Cell = 31,
   Sector = 32,
);

1;

The error I am getting:

Global symbol %hash requires explicit package name at perl.pl line

8.

Execution of perl.pl aborted due to compilation errors.


Put the following line in the main script:

our %hash;

Change the my %hash = ( ... ); declaration in lib.pl to our %hash =
(...);.

In your original versions, %hash was a lexical variable in lib.pl, and

thus

not in scope within perl.pl. Using 'our' instead of 'my' makes %hash a
package variable (in package main::), and as such is accessible by both
perl.pl and lib.pl, The 'our' declaration also lets you leave off the

package

name when you access the variable.



It is a better idea to put this inside a module and export a subroutine
for
accessing it (or use an object-oriented interface). See:

http://perl-begin.org/topics/modules-and-packages/

Untested code:


## This is the file MyModule.pm - don't call it that.
package MyModule;

use parent 'Exporter';

our @EXPORT = (qw(get_ref_to_global_hash));

my %global_hash = (
 'donald' = 'duck',
 'mickey' = 'mouse',
 'goofy' = 'dog',
);

sub get_ref_to_global_hash
{
 return \%global_hash;
}

# Module should return a true value.
1;




Regards,

 Shlomi Fish



With Shlomi's approach how would I access each element in the %global_hash
within the main script calling the function?

Below is what I have attempted.

**Containers.pm**

## This is the file Containers.pm
package Containers;

use parent 'Exporter';

our @EXPORT = (qw(get_global_hash));

my %global_hash = (
 'donald' = 'duck',
 'mickey' = 'mouse',
 'goofy' = 'dog',
);


sub get_global_hash
{
 return \%global_hash;
}

1;

**try.pl**

#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;

use Containers;

print Hello, \n;

# our %global_hash;

print get_global_hash;

# print Dumper \%global_hash;


Hey Chris

There is no need to export an accessor subroutine - you can export any
package identifier so you can export the hash itself. For instance

Containers.pm

package Containers;

use strict;
use warnings;

use parent 'Exporter';

our @EXPORT_OK = ('%global_hash');

our %global_hash = (
  'donald' = 'duck',
  'mickey' = 'mouse',
  'goofy' = 'dog',
);

1;

main.pl

use strict;
use warnings;

use Containers '%global_hash';

use Data::Dump;
dd \%global_hash;

Output

{ donald = duck, goofy = dog, mickey = mouse }

HTH,

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: obfuscating code

2013-02-13 Thread Rob Dixon

On 12/02/2013 22:50, David Crouse wrote:


Seriously, I took it as just funny... get off your soapbox.
I'm fairly sure that the comment was just in good fun.

As a systems admin, i've had to decipher my share of perl,
and while it can be written great, it can also be written poorly.


David, as a Perl programmer I am sure you come across the prejudice that
we all do - that Perl is inherently incomprehensible. The crown once
belonged to APL, but despite our efforts at evangelism Perl now gets a
kicking that it doesn't deserve.

Tribal behaviour is inevitable, but when global ideas are berated a lot
of damage can be done.

I'm sure you will agree that Perl is a current, useful and vibrant
language. Yet there is also a problem with its perception - it is
believed to be difficult to read and write, and far from the
cutting-edge of technology.

This perception is far from the truth. Perl can be written very well and
very neatly, and often betters similar languages. In comparison C is far
too easily abused, and platform compatibility is a struggle.

If you're after fun, try visiting your neighbour reeking of last
night. There are some things that stick, and we would rather you didn't
spread them about.

Perl is a tidy and expressive language.

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: other ways to parse emails from html?

2013-02-01 Thread Rob Dixon

On 31/01/2013 19:49, Jeswin wrote:

Hi again,
I tried to use the treebuilder modules to get emails from a webpage
html but I don't know enough. It just gave me more headaches.

My current method get the emails is to go to the site, put the source
code in MS Word, and run a regex to get all the emails in that html
page.

I think I can get the list of sites in a file and probably download
the html source codes and parse offline. Can't I just use regex to
parse the emails? What can go wrong?

I'm a noob at perl and not a programmer.

Thanks for the input


Hi Jeswin

As Timothy asked you, did you look at my previous email that included
working code for you to use directly? If there is a problem with that
solution then please say so and we can fix it for you.

Rob




--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: trying to understand HTML::TreeBuilder::XPath

2013-01-29 Thread Rob Dixon
On 26/01/2013 20:44, Jeswin wrote:
 Hi,
 I'm trying to parse out the emails addresses from a webpage and I'm
 using the HTML::TreeBuilder::XPath module. I don't really understand
 XML and it's been a while since I worked with perl*. So far I mashed
 up a code by looking through past examples online. The HTML portion
 for the email is like:
 
 li class=iiEmail: a href=mailto:n...@place.edu;n...@place.yyy/a/li
 
 The code I put together is:
 
 #!/usr/bin/perl
 use strict;
 use warnings;
 
 use HTML::TreeBuilder::XPath;
 
 my $html  = HTML::TreeBuilder::XPath-new;
 my $root  = $html-parse_file( 'file.htm' );
 
 my @email = $root -findnodes(q{//a} );
 
 for my $email(@email) {
 
 print $email-attr('href');
 }
 
 The problem is that it also outputs the link found in another portion
 of the HTML ( a href=http://sites.place.yyy/name;). So I get a list
 of websites and emails, one after another. How can I just output the
 email section?
 
 I also don't understand how the path for findnodes(q{//a} ) works.
 What's the q for? How do I understand the structure of nodes?
 
 Thanks for any advice,
 JJ
 
 *I'm not a programmer; I have a list to compile for work and thought I
 might automate it to make my life easier.

Hi Jeswin

q{...} is just another way of writing single quotes. '//a' will do just
fine.

The // means descendant, so '//a' finds any a element beneath the root
of the document.

I'm not sure what you mean by How do I understand the structure of
nodes? Do you know any HTML? If not then this is going to be very
difficult.

Since you're using HTML::TreeBuilder::XPath there are some easier
options open to you. You can write

my $html  = HTML::TreeBuilder::XPath-new_from_file('file.htm');

my @links = $html-findnodes_as_strings('//@href[starts-with(., 
mailto:;)]');

which will find all the href=... attributes that start with 'mailto:'
and put their values into @links. Then you can print them all out using

print $_\n for @links;

If you want to go further and remove the 'mailto:' from the beginning,
then its just

for (@links) {
my $mail = s/^mailto://r;
print $mail\n;
}

HTH,

Rob

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: need suggestion stat vs Devl::Size for checking size very very frequently

2013-01-25 Thread rob . dixon
Rajeev Prasad rp.ne...@yahoo.com wrote:

i have a lot of data coming/pouring in from this:

my ($rout, $pid) = $ssh-pipe_out($cmd);
while (my $line = $rout) {
    print filehandle $line;
}

I want to stop writing after certain size is written (say 1gb).

so i can try this: (it is working). But I am worried I am doing too
many stat (and i am imagining it would be very expensive operation).
there are about 500,000 lines coming in for 500mb data file, so below
is doing stat 500 thousand times!!!


my ($rout, $pid) = $ssh-pipe_out($cmd);
while (my $line = $rout) {

  my
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)=
stat(filehandle);
  if ($size  $huge_limit ){
       print $tmp_fh  $line;
       } else {
          seek($tmp_fh, 0, 0);
          print $tmp_fh file size limit reached\n;
           kill TERM = $pid;
          last;
    }
} ###end while


so i am 'thinking' to try this: storing output in local temp array and
checking when it reaches 10mb ($huge_limit) then save it to file and
increase counter, when it happens total of $huge_limit_counter times
(50 for 500mb limit). I close the channel and proceed. Here I am
thinking, checking size of array 500,000 times (a 500k line array) is
somehow 'more efficient' then checking file-size using stat.


            my $counter=1;my @tmp_arr;
                my ($rout, $pid) = $ssh-pipe_out($cmd);
                    while (my $line = $rout) {
                        push(@tmp_arr,$line);
                        if (size(\@tmp_arr)  $huge_limit){
                            $counter++;
                            if ($counter = $huge_limit_counter){
                                kill TERM = $pid;
                                last;
                            } else {
                            print $tmp_fh @tmp_arr;
                            undef(@tmp_arr);
                            }
                        }
                        }
                    if(tell($rout) != -1){close $rout;}


Please advice any suggestion for increasing efficiency of this code.

thank you.
Rajeev

You should use the `tell` operator on the output file handle to discover how 
much data has been printed.

HTH,

Rob

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: need suggestion stat vs Devl::Size for checking size very very frequently

2013-01-25 Thread Rob Dixon

On 26/01/2013 05:58, Rajeev Prasad wrote:


*From:* rob.di...@gmx.com rob.di...@gmx.com


Rajeev Prasad rp.ne...@yahoo.com mailto:rp.ne...@yahoo.com wrote:


i have a lot of data coming/pouring in from this:

my ($rout, $pid) = $ssh- pipe_out($cmd);
while (my $line = $rout ) {
   print filehandle $line;
}

I want to stop writing after certain size is written (say 1gb).

so i can try this: (it is working). But I am worried I am doing too
many stat (and i am imagining it would be very expensive operation).
there are about 500,000 lines coming in for 500mb data file, so below
is doing stat 500 thousand times!!!


my ($rout, $pid) = $ssh- pipe_out($cmd);
while (my $line = $rout ) {

 my
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)=
stat(filehandle);
if ($size  $huge_limit ){
  print $tmp_fh  $line;
  } else {
 seek($tmp_fh, 0, 0);
 print $tmp_fh file size limit reached\n;
  kill TERM = $pid;
 last;
   }
} ###end while


so i am 'thinking' to try this: storing output in local temp array and
checking when it reaches 10mb ($huge_limit) then save it to file and
increase counter, when it happens total of $huge_limit_counter times
(50 for 500mb limit). I close the channel and proceed. Here I am
thinking, checking size of array 500,000 times (a 500k line array) is
somehow 'more efficient' then checking file-size using stat.


   my $counter=1;my @tmp_arr;
   my ($rout, $pid) = $ssh- pipe_out($cmd);
   while (my $line = $rout ) {
   push(@tmp_arr,$line);
   if (size(\@tmp_arr)  $huge_limit){
   $counter++;
if ($counter  = $huge_limit_counter){
   kill TERM = $pid;
   last;
   } else {
   print $tmp_fh @tmp_arr;
   undef(@tmp_arr);
}
   }
   }
   if(tell($rout) != -1){close $rout;}


Please advice any suggestion for increasing efficiency of this code.

thank you.
Rajeev


You should use the `tell` operator on the output file handle to discover
how much data has been printed.

HTH,

Rob


oops ! sorry. this is not working.



Please reply to the Perl Beginners group and not directly to me.

Please also put your response /after/ the message you are quoting, as it 
is the standard for this group.


What doesn't work exactly? You can see how much data has been printed to 
your output file using `tell`. The code snippet below shows an example.


Rob



my ($rout, $pid) = $ssh-pipe_out($cmd);

while (my $line = $rout) {

  if (tell $tmp_fh  $huge_limit) {
print $tmp_fh \nFile size limit reached\n;
kill 'TERM', $pid;
last;
  }

  print $tmp_fh $line;
}

close $rout;



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: finding head and tail in data structure

2013-01-10 Thread Rob Dixon

On 10/01/2013 10:01, budi perl wrote:

Hi,

I have this following hash:

#!/usr/bin/perl
#
use strict;
use Data::Dumper;

my %MYROUTES = (
 ROUTE-252 = {
 #  src = dest
427 = ABEP,
ABEP = 441,
441 = 427,
427 = 444,
444 = MGWQ,
MGWQ = CDEF
 },

 ROUTE-432 = {
AAA = BBB,
BBB = CCC,
CCC = DDD,
XXX = YYY,
YYY = ZZZ
 }
);

print Dumper %MYROUTES;

__END__

Expected results:

ROUTE-252: 427 - ABEP - 441 - 427 - 444 - MGWQ - CDEF
ROUTE-432: Error: can not follow the route!

or if possible can be more specific on how many link founds:
Error, some path is missing:
ROUTE-432: AAA - BBB - CCC -DDD
ROUTE-432: XXX - YYY -ZZZ

I put data in order for brevity, actual data may not.

Can someone shed some light how to find head then follow the path as above?


This calls for a proper module that has been thoroughly tested. The
program below uses Graph::Directed. Beware that it does no checks for
things like cyclic links, but it does print the path to /all/ end points
starting at each source.

HTH,

Rob


use v5.10;
use warnings;

use Graph::Directed;

my %routes = (
  ROUTE-252 = { 427 = 444, 441 = 427, 444 = MGWQ, ABEP = 441, 
MGWQ = CDEF },
  ROUTE-432 = { AAA = BBB, BBB = CCC, CCC = DDD, XXX = 
YYY, YYY = ZZZ },

);

while (my ($label, $edges) = each %routes) {

  my $graph = Graph::Directed-new;

  while (my ($start, $end) = each %$edges) {
$graph-add_edge($start, $end);
  }

  my @sinks = $graph-sink_vertices;
  for my $source ($graph-source_vertices) {
for my $sink (grep $graph-is_sink_vertex($_), 
$graph-all_successors($source)) {

  say $label: , join ' - ', $graph-path_vertices($source, $sink);
}
  }
}

**output**

ROUTE-252: ABEP - 441 - 427 - 444 - MGWQ - CDEF
ROUTE-432: AAA - BBB - CCC - DDD
ROUTE-432: XXX - YYY - ZZZ


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: grouping in regex

2012-12-24 Thread Rob Dixon

On 23/12/2012 13:27, punit jain wrote:

Hi,

I am doing grouping but seeing some weird behavior :-

the strings in a file are like :-
AccessModes =
(18,Mail,POP,IMAP,PWD,WebMail,WebSite,Relay,Mobile,FTP,MAPI,TLS,LDAP,WebCAL);

...
.
multiple lines

I am seeing which lines have both POP and Webmail as below :-

if( $line =~ /AccessModes\s*=\s*.*(WebMail)*.*(POP).*(WebMail)*.*/ ) {
 if(defined $2) {
 print $2 $1.$line.\n;
 }
 }


However I get these below :-

   POPUse of uninitialized value in concatenation (.) or string at
test.plline 283, GEN85 line 2.
   POPUse of uninitialized value in concatenation (.) or string at
test.plline 283, GEN86 line 2.
   POPUse of uninitialized value in concatenation (.) or string at
test.plline 283, GEN87 line 2.

Any clue why ?


You would be bettre off using a look-ahead, which doesn't care what
order the two options appear in the list. The program below shows an
example.

Rob

use strict;
use warnings;

while (my $line = DATA) {
  if ($line =~ /AccessModes\s*=\s*(?=.*(\bPOP\b))(?=.*(\bWebMail\b))/) {
print $1 $2\n;
  }
}


__DATA__
AccessModes = 
(18,Mail,POP,IMAP,PWD,WebMail,WebSite,Relay,Mobile,FTP,MAPI,TLS,LDAP,WebCAL);
AccessModes = 
(18,Mail,IMAP,PWD,WebMail,WebSite,Relay,Mobile,FTP,MAPI,TLS,LDAP,POP,WebCAL);


**output**

POP WebMail
POP WebMail


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: grouping in regex

2012-12-24 Thread Rob Dixon

On 24/12/2012 13:08, Paul Johnson wrote:

On Sun, Dec 23, 2012 at 06:57:38PM +0530, punit jain wrote:

Hi,

I am doing grouping but seeing some weird behavior :-

the strings in a file are like :-
AccessModes =
(18,Mail,POP,IMAP,PWD,WebMail,WebSite,Relay,Mobile,FTP,MAPI,TLS,LDAP,WebCAL);

...
.
multiple lines

I am seeing which lines have both POP and Webmail as below :-

if( $line =~ /AccessModes\s*=\s*.*(WebMail)*.*(POP).*(WebMail)*.*/ ) {
 if(defined $2) {
 print $2 $1.$line.\n;
 }
 }


However I get these below :-

   POPUse of uninitialized value in concatenation (.) or string at
test.plline 283, GEN85 line 2.
   POPUse of uninitialized value in concatenation (.) or string at
test.plline 283, GEN86 line 2.
   POPUse of uninitialized value in concatenation (.) or string at
test.plline 283, GEN87 line 2.

Any clue why ?

Regards.


It's unclear to me why, having specified what you are searching for, you
then ask what was found.  The only reason I can see for doing that would
be to find out in which order you found the items.

In any case, the easiest way to find out whether two substrings appear
in the same same string is to program the way you define the problem:

if (/WebMail/  /POP/) { ... }


Hi Paul

I think


why, having specified what you are searching for, you then ask what was found


could be expressed better, or at least needs an explanation.

Rob





--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Regex help

2012-12-22 Thread Rob Dixon

On 22/12/2012 11:15, punit jain wrote:

Hi,

I have a file like below : -

BEGIN:VCARD
VERSION:2.1
EMAIL:te...@test.com
FN:test1
REV:20101116T030833Z
UID:644938456.1419.
END:VCARD

 From (S___-0003) Tue Nov 16 03:10:15 2010
content-class: urn:content-classes:person
Date: Tue, 16 Nov 2010 11:10:15 +0800
Subject: test
Message-ID: 644938507.1420
MIME-Version: 1.0
Content-Type: text/x-vcard; charset=utf-8

BEGIN:VCARD
VERSION:2.1
EMAIL:te...@test.com
FN:test2
REV:20101116T031015Z
UID:644938507.1420
END:VCARD



My requirement is to get all text between BEGIN:VCARD and END:VCARD and all
the instances. So o/p should be :-

BEGIN:VCARD
VERSION:2.1
EMAIL:te...@test.com
FN:test1
REV:20101116T030833Z
UID:644938456.1419.
END:VCARD

BEGIN:VCARD
VERSION:2.1
EMAIL:te...@test.com
FN:test2
REV:20101116T031015Z
UID:644938507.1420
END:VCARD

I am using below regex  :-

my $fh = IO::File-new($file, r);
my $script = do { local $/; $fh };
 close $fh;
 if (
$script =~ m/
 (^BEGIN:VCARD\s*(.*)
 ^END:VCARD\s+)/sgmix
 ){
 print OUTFILE $1.\n;
 }

However it just prints 1st instance and not all.

Any suggestions ?


This is very simply done with Perl's range operator. See the program
below.

Rob


use strict;
use warnings;

open my $fh, '', 'vcard.txt' or die $!;

while ($fh) {
  print if /^BEGIN:VCARD/ .. /^END:VCARD/;
}

**output**

BEGIN:VCARD
VERSION:2.1
EMAIL:te...@test.com
FN:test1
REV:20101116T030833Z
UID:644938456.1419.
END:VCARD
BEGIN:VCARD
VERSION:2.1
EMAIL:te...@test.com
FN:test2
REV:20101116T031015Z
UID:644938507.1420
END:VCARD


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: variable definition error not caught when using strict and warnings

2012-11-09 Thread Rob Dixon

On 09/11/2012 17:08, Nemana, Satya wrote:

Hi

I am a little confused with this program

Program:
use strict;
use warnings;

if ($999 == 1056)
{
 print (\nequal);
}
else
{
 print (\nnot equal);
}

What I expect: Perl to throw me an error as $999 variable is not defined, but 
perl executes the code with a warning.(I don't expect the code to compile at 
all)

Output:
Use of uninitialized value in numeric eq (==) at wrong1.pl line 4.

not equal


However, if I replace $999 with $num (which is not defined or initialized), I 
get the following error

Global symbol $num requires explicit package name at wrong1.pl line 4.
Execution of wrong1.pl aborted due to compilation errors.

What is happening with the top program?


Hello Satya

The variable $999 holds the 999th capture from the most recent regular
successful expression match. Since you have no regular expressions in
the program it is left undefined. It would be very unusual to have so
many captures in a regex but Perl does support it.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: perl interpreter output meaning?

2012-09-22 Thread Rob Dixon

On 22/09/2012 08:45, Anne Wainwright wrote:

Hi,

this is the output.

Use of uninitialized value $9 in concatenation (.) or string at pg_delim2htm_01.pl 
line 89,  line 1.
Use of uninitialized value $9 in concatenation (.) or string at pg_delim2htm_01.pl 
line 89,  line 4.
Use of uninitialized value $9 in concatenation (.) or string at pg_delim2htm_01.pl 
line 89,  line 6.

and so on

What do the  with the 'lines' to the right mean?

(I do seem to have a problem on line 89 which is a regex with the /x
modifier)


Hello Anne

The error means that you have used $9 in a string, either

the ninth capture is $9

or the equivalent

the ninth capture is  . $9

but $9 has no value. It would be set by a successful regex that has nine
or more captures, so either a regex hasn't matched or the capture is in
a branch of the regex that hasb't matched. Or you've counted your
captures wrongly etc.

The

... at pg_delim2htm_01.pl line 89,  line 4.

means perl was executing line 89 of the pg_delim2htm_01.pl program,
having read 4 lines from the input file using 

HTH,

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: My long script

2012-09-16 Thread Rob Dixon

On 16/09/2012 05:03, Robert Wohlfarth wrote:

On Sat, Sep 15, 2012 at 4:46 PM, jmrhide-p...@yahoo.com wrote:


The user clicks on a button (A or B),  which fires back a string that
reawakens the script and shows it what  answer the user chose. The script
inspects the cooky-jar to determine  the state of the script, compares the
user's selection with its  expectation, and fires back one of two new web
pages.
If the user chose  the right answer, he gets congratulations and a new
problem.
If it was a  wrong answer, he gets a correction, which includes the correct
term,  definition, vignette, and a sound-file with pronunciation of the
term.
Then the user has to click to continue the tutorial. That click sends a
  string
that re-awakens the script and cues it to send a new question.



I assume from this description that the while loops are picking terms at
random, and you don't want to repeat a term in the same question. I noticed
several loops that use int( rand( 5 ) ) to get 3 unique numbers. Since
rand returns decimals, it's plausible that the loop can't find three
unique integers. For example, rand keeps returning decimal numbers
between 3 and 4, like 3.4526180 and 3.9876261 and 3.1182304.

Instead of picking answers at random, what about shuffling the answers and
take the top 5? They're still in a random order. And you eliminate even the
possibility of an infinite loop. A module like Array::Shuffle (
http://search.cpan.org/~salva/Array-Shuffle-0.03/lib/Array/Shuffle.pm)
should work nicely.


List::Util has been in core since Perl v5.7 and provides a perfectly
good shuffle()

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: File/string formatter script?

2012-09-15 Thread Rob Dixon
On 15/09/2012 02:52, newbie01 perl wrote:
 Hi all,
 
 I have a config file that contains some text as below:
 
 server01:/u01/app/oracle/admin/db01/adump  :*.dmp,5
 :compress :/bin/gzip
 server01:/u01/app/oracle/admin/db04/adump :*.aud,5
 :remove :/bin/rm
 server01:/u01/app/oracle/admin/db06/adump  :*.log,5
 :remove :logrotate
 
 But am wanting to run a script that will take this file as an input and
 produced the following output:
 
 server01:/u01/app/oracle/admin/db01/adump  :*.dmp,5
 :compress   :/bin/gzip
 server01:/u01/app/oracle/admin/db04/adump  :*.aud,5
 :remove :/bin/rm
 server01:/u01/app/oracle/admin/db06/adump  :*.log,5
 :remove :logrotate
 
 Can anyone advise how is the best way to be able to format the text so that
 they lined up neatly? Perhaps anyone already have a script that does what
 am wanting to do?
 
 At the moment, am doing it manually reading one line at a time and using
 awk and printf using the max string of each column as the basis for the max
 length of the column for each field. Am wanting to be able to use Perl
 instead.
 
 Any feedback much appreciated. Thanks in advance.

I assume the data has been wrapped by your email client and the lines
aren't in fact broken after the third field?

I suggest you read through the data, collecting the fields from each
record and keeping a maximum width of each column. Then you can build a
format string dynamically and use it to print each record of the
original data.

The program below should give you a start.

HTH,

Rob



use strict;
use warnings;

my @data;
my @widths;

while (DATA){
  my @fields = split;
  my $i = 0;
  for my $field (@fields) {
my $len = length $field;
$widths[$i] = $len unless $widths[$i] and $widths[$i] = $len;
$i++;
  }
  push @data, \@fields;
}

my $format = join(' ', map %-${_}s, @widths).\n;
printf $format, @$_ for @data;

__DATA__
server01:/u01/app/oracle/admin/db01/adump  :*.dmp,5 
:compress :/bin/gzip
server01:/u01/app/oracle/admin/db04/adump :*.aud,5 :remove  
   :/bin/rm
server01:/u01/app/oracle/admin/db06/adump  :*.log,5 :remove 
:logrotate

**output**

server01 :/u01/app/oracle/admin/db01/adump :*.dmp,5 :compress :/bin/gzip
server01 :/u01/app/oracle/admin/db04/adump :*.aud,5 :remove   :/bin/rm  
server01 :/u01/app/oracle/admin/db06/adump :*.log,5 :remove   :logrotate


-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: My script is...

2012-09-14 Thread Rob Dixon

On 14/09/2012 14:31, Rob Coops wrote:

On Fri, Sep 14, 2012 at 2:52 PM, jmrhide-p...@yahoo.com wrote:


I appreciate the helpful input.

It appears from my server stats that the script in question has only run a
couple of times a day on average, so that's fewer than a thousand
instances in
the past year. I ran LOTS of tests of the script, none of which hung or
produced
unexpected output.

If the output was as expected, then the script had to execute correctly to
the
end of the output stage at least. But the only thing after that is a brief
sub
that advises the user that they must enable cookies in order to use the
script.
If that code were executing, then the output I see when I run the script
would
not be as expected.

The While(1) loops all occur PRIOR to the output stage. All they do is
generate
a random integer, make sure it's not the same as the last one, and move on.

So I still don't get it!


Basically every one on this list has said the same. The script is a mess it
is hard to read hard to maintain and should be cleaned up before we can
really comment on this.

To not be to rude to you script it looks like it was run over by a
truck, repeatedly. You might have applied a good dose of ducktape and
staples but it is simply not really maintainable anymore. It actually is
bad enough for everyone to say please clean it up before asking for help as
we just can't read it. And these are for a large part perl professionals
writting code on a daily basis...

On top of that it could very well be that you script in your development
environment is running on a different version of Apache or Perl also it
could very well be that the modules installed in the production environment
Apache (mod_perl maybe?) are the cause of all these troubles.

In any case I would advise the same as every one else did before, clean up
the script first so it is a lot simpler to read.
After that figure out what modules you production Apache is running with
and identify their potential impact on your script by running these your
self or reading the documentation of course (though you will always have to
prove what you read in the documentation in the real world so a lot of us
are at least tempted to skip the boring reading bit). If none of that helps
(I am reasonably sure it will) have a look at the Perl version your
provider is using and make sure that you are using the same version as well
there might be a difference there.


Hi John

In my previous post I have given you a perltidied version of your code
which already is much easier to read. Please use it

As well as being courteous to those who you ask for help, it is an
obligatory start to remove the comments from `use strict` and `use
warnings` at the head of your program. `use diagnostics` is of little
use on its own. You should also remove the huge block of predeclarations
and declare your variables at the first point of use within the smallest
scope possible

You have a Jenga tower of code that will break if you make the slightest
change. This will not be the last bug you find, I am sure, so please do
yourself a favour and write something that is maintainable, otherwise
this will all keep happening over and over again

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: My script is OUT OF CONTROL!

2012-09-13 Thread Rob Dixon
On 13/09/2012 23:42, jmrhide-p...@yahoo.com wrote:
 
 I installed the following script last year and it seemed to be working fine.
 Yesterday, however, my hosting service took down my site because the script 
 was
 tying up so much of their server resources that it was a threat to their
 business. One of the folks I talked to there said he thought it was starting
 multiple copies of itself that were never terminated. The logs didn't show the
 script being accessed more than a few times a day on average.
 
 I would appreciate help debugging this thing:

Hi John

You have offered us a collapsed building and asked how to restore it to
somewhere fit to live in

Your program has become a monster, and clearly needs a rewrite

You should be able to understand your own software completely, and
explain every line in it, and when and why it is being executed

Instead I think you have chipped away at an existing program, changing
things here and there until it seems to work OK

Doing this again and again has resulted in the code that you have, where
no one knows why and how it works or how to fix it

Assuming that you don't have the means to write a replacement from
scratch, you should start by reformatting the code so that the
indentation is consistent, correct, and readable

Then you should uncomment the `use strict` and `use warnings` lines, and
declare everything at its first point of use

How you proceed beyond that depends on the behaviour of the new program

I can offer you a reformat, courtesy of `perltidy`, that will help you
on your way

HTH,

Rob


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

use CGI;
my $cgi = new CGI;
my (
$topic, $score, $lastnum,  $answer,  $anum,
$bnum,  $cnum,  $dnum, $enum,$smarts,
$playlevel, $c_topic,   $c_smarts, $c_playlevel, $c_score,
$c_lastnum, $c_goodans, $stimulus, $texta,   $textb,
$textc, $textd, $texte,$defnum,  $smiley,
$feedback,  $goodans,   $restart,  @data,@cat,
@term,  @def,   @story,@candidate,   @termnum,
$sound
);
my $instructions = (Click the button next to the best response);
my $ops  = 0;

use diagnostics;

# GET COOKIES
$topic = $cgi-cookie('topic');
$smarts= $cgi-cookie('smarts');
$playlevel = $cgi-cookie('playlevel');
$score = $cgi-cookie('score');
$lastnum   = $cgi-cookie('lastnum');
$goodans   = $cgi-cookie('goodans');

# IF NEW CATEGORY THEN (RE)START TUTORIAL, ELSE GET USER ANSWER
if ($cgi-param('Category')) {
$restart   = 1;
$topic = $cgi-param('Category');
$smarts= 0;
$playlevel = 0;
$score = 0;
$lastnum   = 0;
}
elsif ($cgi-param('Answer')) { $answer  = $cgi-param('Answer'); }
elsif ($cgi-param('Next'))   { $restart = 1; }

if ($topic) {# RUN TUTORIAL

if ($answer and ($playlevel  3)) {

# SUBSTITUTE SPACE FOR '+' IN $answer
$_ = $answer;
s/\+/ /g;
$answer = $_;

# RTRIM $answer AND MAKE SURE IT'S ALL LOWER CASE
$answer =~ s/\s+$//;
$answer = lc($answer);

# FIX FRENCH CHARACTERS

if($answer eq deja entendu) { $answer = déjà entendu; }
elsif ($answer eq deja vu)  { $answer = déjà vu; }
elsif ($answer eq deja vecu){ $answer = déjà vécu; }
elsif ($answer eq folie a deux) { $answer = folie à deux; }
elsif ($answer eq jamais vecu)  { $answer = jamais vécu; }
elsif ($answer eq d%e9j%e0 entendu) { $answer = déjà entendu; }
elsif ($answer eq d%e9j%e0 vu)  { $answer = déjà vu; }
elsif ($answer eq d%e9j%e0 v%e9cu)  { $answer = déjà vécu; }
elsif ($answer eq folie %e0 deux)   { $answer = folie à deux; }
elsif ($answer eq jamais v%e9cu){ $answer = jamais vécu; }

}# END PLAYLEVEL 4

# LOAD DATA
open FH, /home1/theinfp0/public_html/psychdef/tutorial.fil or die $!;
while (FH) {
if ($topic eq REVIEW) { $termnum[$ops++] = $_; }
elsif (/$topic/) { $termnum[$ops++] = $_; }
}
close FH;

$defnum = $ops;# NUMBER OF TERMS IN DATA SET

# PARSE $_ TO GET $term(32) $cat(16) $def(64) $story(128) via @data:
$ops = 0;
foreach (@termnum) {
@data   = /(.{16})/g;
$cat[$ops]  = $data[0];
$term[$ops] = $data[1] . $data[2];
$def[$ops]  = $data[3] . $data[4] . $data[5] . $data[6];
$story[$ops] =
  $data[7]
. $data[8]
. $data[9]
. $data[10]
. $data[11]
. $data[12]
. $data[13]
. $data[14];

# RIGHT TRIM STRINGS
$cat[$ops] =~ s/\s+$//;
$term[$ops]=~ s/\s+$//;
$def[$ops] =~ s/\s+$//;
$story[$ops++] =~ s/\s+$//;
}

# EVALUATE RESPONSE AND PROVIDE FEEDBACK, ADJUSTING SCORES

if ($answer and ($answer ne $goodans)) { $answer = 0; }

if ($answer) {

Re: Using different libraries dynamically

2012-09-12 Thread Rob Dixon

On 12/09/2012 15:18, Mark Haney wrote:

I've got what I hope is an easy question to answer.  I've got a perl web
app that I've setup with a 'live' version (more like a beta actually)
and a dev version for me to make changes to that might break the other
site.

The way I inherited it was as a single site using 'use lib' with the
library files to a working site being used as the dev version.  I've
moved the files around to match the first paragraph setup.  Two
different sets of files, one live the other development.

For the time being I've manually change the 'use lib' statement before
uploading the changed/fixed code to the live site, but this is getting a
bit silly, not to mention completely not standard practice.

My question is, what IS standard practice for this?  Honestly, I've
never built a web app in this manner despite writing a lot of perl code.
  So?  What should I do?  Any suggestions are appreciated.


Hey Mark

I suggest you use set the MYLIBPATH environment variable to the
directory you want to use and then do

  use lib $ENV{MYLIBPATH}

at the head of your program

HTH,

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




  1   2   3   4   5   6   7   8   9   10   >