Friday, September 06, 2013

How to sort a hash in Perl?

Gabor has a nice article about sorting hashes in Perl.

I thought I would piggy-back off Gabor's article and demonstrate how you can do something similar with a couple of CPAN modules specifically designed for processing hashes and lists.

use strict;
use warnings;
use 5.010;
use List::MoreUtils qw(natatime);
use Hash::MoreUtils qw(hashsort);

my %planets = (
    Mercury => 0.4,
    Venus => 0.7,
    Earth => 1,
    Mars => 1.5,
    Ceres => 2.77,
    Jupiter => 5.2,
    Saturn => 9.5,
    Uranus => 19.6,
    Neptune => 30,
    Pluto => 39,
    Charon => 39,
    );

# Sort the keys of the hash using the hashsort function in the  Hash::MoreUtils module
my @array_of_pairs  = hashsort \%planets;

# Leverage List::MoreUtils natatime function to create an iterator to peel off 2 items at a time
my $it = natatime 2, @array_of_pairs;
while ( (my $a, $b) = $it->() ) {
    say "$a $b";
}

__END__

Output...

Ceres 2.77
Charon 39
Earth 1
Jupiter 5.2
Mars 1.5
Mercury 0.4
Neptune 30
Pluto 39
Saturn 9.5
Uranus 19.6
Venus 0.7



Tuesday, February 17, 2009

Subroutine References

Subroutine references work somewhat like pointers to functions in C. As a consequence such references can be used to create sophisticated structures in your Perl programs. An example of such structures are:
  • Dispatch Tables - Data structures that are used to map events to subroutines references.
  • Higher-order procedures -- A higher-order procedure is one that is able to take other procedures as arguments.
  • Closures - A subroutine that packages it's own environment when created.
Subroutines can be named or anonymous. To create a "named" reference consider the following example:

sub sayHelloWorld {
    print "Hello World! \n";
}
$refToSub = \&sayHelloWorld; # Create a "named" reference to a subroutine

The following is an example of how to create an "anonymous" reference to a subroutine
$refToSub = sub {
    print "Hello World! \n";
};

When it is time to use the subroutine reference you must "dereference" the reference. An example of calling the subroutine indirectly with the reference follows:

&$refToSub(); # Call the sayHelloWorld subroutine indirectly

The arrow syntax -> can also be used as follows:

$refToSub->();

Tuesday, December 30, 2008

Reverse DNS Lookup

I am writing a web service to perform a reverse lookup on an IP address.

During the course of my search for existing packages to build on I discovered a nice Perl script that can perform either a reverse DNS lookup on an IP address or dump the IP addresses associated with a particular domain name.

If you have a need for such functionality have a look at Peter's script!

I am including it here for your convenience with a link to the author's website.

http://www.peter.com.au/perl/index.html#getdnsinfo

This script displays the IP associated with a DNS name (or vice versa).

#!/usr/bin/perl

use strict;
use warnings;

use Socket qw(AF_INET);

usage() if $#ARGV == -1;
display_info( @ARGV );

sub display_info {
foreach (shift) {
my ($ip, $host, $aliases, $addrtype, $length, @addrs);
$ip = $_;
if ( /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ ) {
print "IP is $ip\n";
($host, $aliases, $addrtype, $length, @addrs) =
gethostbyaddr( pack( 'C4', $1, $2, $3, $4 ), AF_INET );
die "Reverse lookup failed to find name for $ip\n" unless $host;
}
$host = $ip unless $host;
print "Hostname is $host\n";
($host, $aliases, $addrtype, $length, @addrs) = gethostbyname( $host );
die "Lookup failed to find address for $host\n" unless @addrs;
print "Maps to these IPs:\n";
foreach (@addrs) {
print "IP: ".join( '.', unpack( 'C4', $_ ) )."\n";
}
}
}

sub usage {
print STDERR <...
Example `getdnsinfo.pl www.interarchy.com'
EOM
exit( 0 );

}

Tuesday, December 23, 2008

Perl meets DTS

If you work with Microsoft SQL Server and maintain DTS Packages you may find the PerlDTS Package worth investigating.

Alceu Rodrigues de Freitas Junior writes "DTS offers several features to help managing ETL processes, including process automation, scheduling and notification."

Alceu's motivation was to improve his productivity because he was working with "hundreds of DTS packages to implement batch integration with Oracle Siebel CRM."

Alceu has implemented many of the DTS API classes in his PerlDTS package; however he adds "there is still a lot of other ones to implement".

If you are working with SQL Server and DTS you may want to leverage PerlDTS in your work.

http://www.sqlservercentral.com/articles/Perl/65025/

Saturday, December 20, 2008

Creating an Anonymous Reference

Perl developers sometimes have the need to pass information to functions by reference. Perl offers developers the ability to create references to anonymous arrays and hashes. This enables Perl developers the ability to create some very complex data structures.

Use the following syntax to manufacture anonymous arrays and hashes in your programs:


# Use brackets to create an anonymous array
$aref = [ "Nashville", "Chattanooga", "Knoxville", "Memphis" ]; # manufactures a *new* anonymous array

# Use braces to create an anonymous hash
$href = { "Nashville" => "Music City", "Memphis" => "BBQ Capital" }; # manufactures a *new* anonymous hash

Friday, December 19, 2008

Tried CGI::Application?

I recently began a project for a client to manage their inventory of construction heavy equipment. The application will provide users the ability to catalog equipment maintenance records and move equipment between various construction sites.

I lieu of a Java/Struts or .NET based application I decided to implement the solution using my favorite development language -- Perl.

I decided upon Mark Stosberg's excellent CGI::Application framework and have been very pleased with it's extensibility, flexibility, and ease of use.

If you haven't tried it out for one of your projects give it a try. I am including a couple of links to tutorials that will give you a nice introduction.

CPAN CGI::Application
CGI::Application Site
CGI::Application: A Simple, Extensible Web Framework

Higher-Order Perl

Mark Jason Dominus is offering his wonderful book "Higher-Order Perl" as a FREE download from his website.

http://hop.perl.plover.com/book/

Thanks to Mark and Elsevier, Inc.!

How do I associate Perl.exe...

If you're a Windows user and you want to associate Perl.exe with your Perl scripts so you don't have to execute your programs in the following fashion:

> c:\perl\bin\perl.exe PowerToPerl.plx

Issue the following commands from a command prompt:

> assoc .plx=Perl
> ftype Perl="c:\perl\bin\perl.exe" "%1" %*

Now you can execute your Perl scripts using the following syntax:

> PowerToPerl

Give it a try!

__END__

Perl defines several interesting special internal values, one of which is the aptly named __END__.

The __END__ special value denotes the logical "end of file" for your program to the Perl interpreter. Everything that follows this special constant is treated as data and may be read via the filehandle.

This terrific feature provides developers with a nice place to put test data, provide configuration information for your program, or even place your POD!

#!c:\perl\bin\perl.exe -w
# perl-test-end.pl
use strict;

while ( ) {
print;
}


__END__
first data line
second data line


c:\perlscripts\perl.exe perl-test-end.pl
first data line
second data line