Archive for Perl
Sorting Section Numbers
Posted by: | CommentsHere’s a code to sort section numbers in ascending order:
sub sort_sections { my ($data) = @_; my $sorted = (); @$sorted = map { $_->[0] } sort { my $x=1; while (defined $b->[1][$x]) { defined $a->[1][$x] or return -1; if ($x%2) { ## Strict numeric comparison return 1 if $a->[1][$x] > $b->[1][$x]; return -1 if $a->[1][$x] < $b->[1][$x]; } else { ## Non-numeric comparison return 1 if $a->[1][$x] gt $b->[1][$x]; return -1 if $a->[1][$x] lt $b->[1][$x]; } $x++; } return defined $a->[1][$x] ? 1 : 0; } map { [$_, [split(/(\d+)/, $_)]] } @$data; return $sorted; }
Here’s a test for it:
$sects = ['1.1', '1.2.2', '1.3', '1.2', '1.3.1']; print Dumper($sects); $sorted_sects = sort_sections($sects); use Data::Dumper; print Dumper($sorted_sects);
And here’s the output:
$VAR1 = [ '1.1', '1.2.2', '1.3', '1.2', '1.3.1' ]; $VAR1 = [ '1.1', '1.2', '1.2.2', '1.3', '1.3.1' ];
Found in Perlmonks.
Base Conversion
Posted by: | CommentsThe following routines will convert a number to and from among the different bases: decimal, hexadecimal, and binary.
################################################ # Convert a binary input to hex # Does not return any leading 0s # sub bin2hex { my $inpt = shift; my $hex; my $bits = length($inpt); $inpt = (32 - $bits) x '0' . $inpt; my $dec = unpack("N", pack("B32", substr("0" x 32 . $inpt, -32))); return(sprintf("%x", $dec)); } ################################################ # Convert a decimal input to binary # Arguments = decimal_number, number_of_bits # sub dec2bin { my $dec = int(shift); my $bits = shift; my $bin = unpack("B32", pack("N", $dec)); substr($bin, 0, (32 - $bits)) = ''; return($bin); } ################################################ # Convert a binary input to decimal # sub bin2dec { my $bin = shift; my $bits = length($bin); $bin = (32 - $bits) x '0' . $bin; my $dec = unpack("N", pack("B32", substr("0" x 32 . $bin, -32))); return($dec); } ############################################### # Convert a hex input to decimal # sub hex2dec { my $h = shift; $h =~ s/^0x//g; return( hex($h)); }
Verify Valid Domain
Posted by: | CommentsUse this code to verify if the domain part of an email address is valid:
use Net::DNS; $email = "user\@somedomain.org"; (undef, $domain) = split (/@/, $email); $resolver = new Net::DNS::Resolver(); $response ||= $resolver->query($domain, "MX") || $resolver->query($domain, "A"); defined ($response) ? print "$domain is valid" : print "$domain is invalid\n";
It might also be a good idea to skip known domains, such as yahoo.com, google.com, etc.
Checking Regular Expression Syntax
Posted by: | CommentsIf your program accepts a regular expression pattern, either from a user input or another module, you need to check that the pattern you receive is valid or not. To check for a valid pattern, apply the pattern against an empty string and wrap the expression in an eval.
sub my_func { my ($pattern) = @_; eval { "" =~ $pattern; }; if ($@) { die "Something wrong with your pattern: $pattern"; } # Otherwise, pattern is good and use it here. }
How To Determine Installed Modules
Posted by: | CommentsHere’s how to determine what modules have been installed after the original Perl installation, hence showing those modules not part of the core installation. Type this from a command line:
perldoc perllocal
How To Tell A Number From A String
Posted by: | CommentsOften, I need to compare two variables but I don’t know if they are numbers or strings. I need to know the type so I can pick the proper comparison operators, i.e., == or eq, > or gt.
So, here’s how to do it:
~$x ne ~"$x" ? 'numeric' : 'string'
~ is the bitwise negation operator (see perlop). It does not negate integers and strings in the same way.
Examples:
$ perl -e 'print ~1, "\n"' 4294967294 $ perl -e 'print ~"1", "\n"' Œ
(character which ASCII code is 255 – ord(’1′))
Create Dir Path
Posted by: | CommentsTo create a directory path programatically:
use File::Path; mkpath "/usr/local/apache/htdocs/articles/2003";
This will create the 2003 directory and all parent directories as needed. This is the same as mkdir -p command.
Creating Timestamp
Posted by: | CommentsSeveral times I needed a timestamp for whatever reason. Here’s one that will return a scalar containing the current timestamp as in 03Jun19-114251.
sub create_timestamp { my ($sec, $min, $hour, $mday, $mon, $year) = localtime; my $month = (qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec))[$mon]; $year %= 100; my $timestamp = sprintf("%02d%s%02d-%02d%02d%02d", $year, $month, $mday, $hour, $min, $sec); return $timestamp; }
Making Persistent Data
Posted by: | CommentsThis pair of routines will serialize and deserialize any Perl data. Useful when you have a piece of data that you want to pass accross 2 CGI applications since CGI don’t have persistent state.
sub _serialize { my ($self, $data) = @_; my $filename = "/tmp/TTS_$$.dat"; sysopen(OUTFILE, $filename, O_RDWR|O_CREAT, 0666) or die ("Can't open $filename: $!"); flock(OUTFILE, LOCK_EX) or die ("Can't lock $filename: $!"); store($data, $filename) or die ("Can't store data structure: $!"); flock( OUTFILE, LOCK_UN ) or die ("Can't unlock $filename: $!"); return $filename; } sub _deserialize { my ($self, $filename) = @_; sysopen(OUTFILE, $filename, O_RDWR|O_CREAT, 0666) or die ("Can't open $filename: $!"); flock(OUTFILE, LOCK_EX) or die ("Can't lock $filename: $!"); my $data = retrieve($filename) or die ("Can't retrieve $filename: $!"); flock( OUTFILE, LOCK_UN ) or die ("Can't unlock $filename: $!"); return $data; }
Use eval To Timeout a Section Of Code
Posted by: | Commentseval { local $SIG{__DIE__} = "DEFAULT"; local $SIG{ALRM} = sub { die "timeout" }; # Tells OS to send alarm signal after 10 secs alarm(10); # your chunk of code that could time out while(1) { # do something } }; alarm(0); if ($@ =~ /timeout/) { print "Timed out"; } elsif ($@) { # some other error caught } # the rest of your code here
Note:
- Set the alarm inside the eval.
- Can’t use eq on $@ since it will contain something like “timeout at foo.pl line 10″. Have to use pattern.