Archive for Perl

Jul
02

Sorting Section Numbers

Posted by: | Comments (0)

Here’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.

Categories : Notes, Perl
Comments (0)
Jul
01

Base Conversion

Posted by: | Comments (0)

The 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));
}
Categories : Notes, Perl
Comments (0)
Dec
22

Verify Valid Domain

Posted by: | Comments (0)

Use 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.

Categories : Notes, Perl
Comments (0)
Nov
18

Checking Regular Expression Syntax

Posted by: | Comments (0)

If 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.
}
Categories : Notes, Perl
Comments (0)
Aug
27

How To Determine Installed Modules

Posted by: | Comments (0)

Here’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
Categories : Notes, Perl
Comments (0)
Aug
13

How To Tell A Number From A String

Posted by: | Comments (0)

Often, 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′))

Categories : Notes, Perl
Comments (0)
Jun
21

Create Dir Path

Posted by: | Comments (0)

To 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.

Categories : Perl
Comments (0)
Jun
19

Creating Timestamp

Posted by: | Comments (0)

Several 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;
}
Categories : Perl
Comments (0)
Apr
17

Making Persistent Data

Posted by: | Comments (0)

This 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;
}
Categories : Perl
Comments (0)
Apr
16

Use eval To Timeout a Section Of Code

Posted by: | Comments (0)

eval {
    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:

  1. Set the alarm inside the eval.
  2. Can’t use eq on $@ since it will contain something like “timeout at foo.pl line 10″. Have to use pattern.
Categories : Perl
Comments (0)