Re: script that passes args to subroutine works ok, after I unpack the args. But perlcritic says I'm not unpacking?
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?
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
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
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
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
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
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
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
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?
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?
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
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
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
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
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
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
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 '-|', '|-'
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 '-|', '|-'
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 '-|', '|-'
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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/
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/
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
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
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
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?
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
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
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
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
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
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
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
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?
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
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
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
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
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
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
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
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
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?
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
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?
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...
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!
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
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/