IP Address To decimal and vice-versa using Perl

There can be a situation where we need to convert IPv4 Address(32 bit) from 4 octet format i.e. 127.0.0.1 to  it decimal equivalent value i.e.  2130706433 and vice-versa. We can use pack, unpack in-built Perl functions to achieve this situation or we can use Socket.pm module (if allowed) along with pack and unpack, whichever you feel easier; you can use it in your code.

How to use Perl to fetch website details

Whenever I was surfing any good technical website,  I was getting curious to know what’s its page rank, alexa rank, where it is hosted, who handles its mails, when this domain was registered and by whom, when it will get expired and so on.
For all these, I had to visit different websites to gather all such information, then I thought it’s better to write a script which will fetch all the details for me and came up with site info details script using Perl.
Fully working code is available here.

How to send a mail using Perl and sendmail in Linux

sendmail in LinuxThere will be some situations where you will not be allowed:
  • to send mail outside of your company/organization
  • to open any mail client like Gmail, yahoo or Hotmail using browser

But you wish to send mail to your outside friend. Either you will use some proxy settings or will request administrator to allow sending or receiving any mail from outside. What if we can do it using an in-built command or through script?

Yes it is possible and its much more easy if you are using Linux rather than Windows (I know even now most of us are using Windows to read this article 😉 ).

This code will work only at Linux variants. If you want to use sendmail in Windows and Linux also with command line option instead of writing a Perl script, you need to download sendEmail readymade script written in Perl by Brandon Zehm  .

  • For Linux users, just untar it and run as you run other Perl script, provided your Perl interpreter is at /usr/bin/perl else change the path at script accordingly
  • For Windows users, extract the code and run it at command line. Make sure, you have installed Perl interpreter.

Lets see the explanation using codes:
[perl]
#!/usr/bin/perl
#################################################################################
#    Author: Sanjeev Jaiswal
#    Date: July, 2012
#    Description: This script will use inbuilt command “sendmail” with -t option mainly.
#                 You can send an email to anyone from any valid email id, even if its not you.
#                 You can use it to prank your friends too or to do some serious stuffs.
#################################################################################
use strict;
use warnings;
 
# You can put as many email ids as you wish in to, cc, bcc
# But, be sure to use commas under one string. All mail ids are fake here, used just for demo 😛
# except  admin@aliencoders.org 😉
my %config = (mail_from =>’ranjan2012@gmail.com’,
              mail_to => ‘jaszi@gmail.com, sanjeejas@gmail.com’,
              mail_cc => ‘jasse@gmail.com, jassi@hotmale.com’,
              mail_bcc => ‘nazibal700@gmail.com, jasze@gmall.com’,
              mail_subject => “Just testing Sendmail”
             );
 
#Call method to send preformatted email
mail_target();
 
sub mail_target{
   #Use \n\n to make sure that it will render as HTML format
   my $message = “From: $config{mail_from}\nTo: $config{mail_to}\nCc: $config{mail_cc}\nBcc: $config{mail_bcc}\nSubject: $config{mail_subject}\nContent-Type: text/html;\n\n”;
   $message.= “<strong>Hi Dear,</strong><br>If someone knows your email id, he/she can use it without your permission if he/she is using sendmail under Linux :D<br> Only issue is it says via which server. Through this you can find out from which server and location someone has used your email id.\n”;
 
   my $MAIL_CMD = “/usr/sbin/sendmail -t -i”;
   if(!open(SENDMAIL, “| $MAIL_CMD”)){
      print “Unable to open an input pipe to $MAIL_CMD:”;
      exit(1);
   }
   print SENDMAIL $message.”\n”;
   close(SENDMAIL);
}
[/perl]

If it gives error like Can’t exec “/usr/lib/sendmail” then :
  • Verify if you are using right sendmail path by using which sendmail command at linux box. You can see the sendmail path.
  • If it says no command found then, type whereis sendmail and you will surely get the lists of sendmail. Use any of these.
You can hide the server and host information also. But you may see This message may not have been sent by:  if its Gmail or any good email clients 😀
 
Any alternatives?
Yes, try any of these listed modules in Perl:
How we can trace out that this mail is from the original sender or someone used his/her id using such scripts?
If you click at show original option under Gmail, you can see, who sent you the mail and from where you got the mail.
Tips:
  • You can use anyones email id at from section but use yours only. I used my friends id to prank them (but its not ethical though)
  • It even didnt check mail existence so you can  write from email address as bill-gates@msft.com
  • In case you forgot to use proper email format like bill-gates instead of bill-gates@msft.com then it would embed its server name as domain name like bill-gates@your-server-name.com
  • You can even attach files
  • You can send mails to many under to, cc and bcc. (Usually to should have only one email id)
Note: Use it to send mail from your mail id only. Using others identity for wrong doing is an offensive crime. Do those things at your own risk. Our work was to make you aware about working sendmail only. (Never say that I didnt warn you before doing anything unethical)
 
How we can hide host name so that no one can get the original trace even using header information.
With the help of masquerading, your outgoing email would appear  from user@aliencoders.org instead of realunixuser@server01.aliencoders.org. This will also hide your internal user name or host name from rest of the world!
So this feature rewrites the hostname in the address of the outgoing mail. This can also be used when you have centralized mail server i.e. mail hub.

Masquerading Sendmail configuration (sendmail.mc not sendmail.cf)
Open your sendmail config file which will be located at  /etc/mail/sendmail.mc:

[vim]
# vi /etc/mail/sendmail.mc
[/vim]

Append/add/modify these lines as follows: (usually these lines will be commented, so just uncomment it)
[vim]
MASQUERADE_AS(aliencoders.org)dnl
FEATURE(masquerade_envelope)dnl
FEATURE(masquerade_entire_domain)dnl
MASQUERADE_DOMAIN(aliencoders.org)dnl
[/vim]
 

Save and close the file. Replace domain name aliencoders.org with your actual domain name. Update and restart sendmail server (use as root):

Before restarting the server, lets sendmail.inc make sendmail configuration file ready using m4 command. The m4 utility is a macro processor intended as a front end for C, assembler, and other languages. Type man m4 in Linux box for more details. So, dont edit sendmail.cf manually.

[vim]
# m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
# /etc/init.d/sendmail restart
[/vim]
 

Done! Now you can hide your real user name, server details and can enjoy this beautiful feature of Linux. (Do pranks or unethical things at your own risk 😉 )

Disclaimer: This article is for educational purpose only. We are not responsible if you get sued or fired from your company while using this script or such knowledge. Use it at your own risk!

Simple steps to verify email id existence

Email id exists or notOur team always face email existence problem when they try to:

  • Verify the  registered account holder’s email id or
  • While sending mail to anonymous user who posted comment with some fake email id or
  • To check, if that email address is still valid (ex: 2 years back emailed was valid but not now)

Well it’s not possible to know 100% whether given e-mail address exists in real or not but it will be handy in majority of the cases. You can do it manually also if you are in Linux box using host or nslookup and telnet command. I would prefer host command for this purpose.

How it works:

  • Check if domain name exists or not using ping command
  • If domain name exists then check if it has any mail handlers i.e. mx records in DNS. Use host or nslookup command for it
  • If mx record exists for that domain name use that mail handler using telnet command
  • Use telnet and smtp command to verify user email id. If you get 250/Ok for user email id. You may assume that it exists.

Here many things came into the picture while testing various mail ids from various mail handlers. I will discuss it under “possible ways of failures”

Steps to check the email existence manually

1.       Get the mail id to verify (we can get domain-name from this format to use it in our next step userid@domain-name . For ex:admin@aliencoders.org)

2.       Either use nslookup command or host command to get mail server address (Lists of mx records from DNS)

a.       Using nslookup:
nslookup –type=mx domain-name

b.      Using host :
host –t mx domain-name

3.       Get the least digital value’s mx record to use it in telnet

a.       telnet mxrecord port-no i.e. telnet mail.aliencoders.org 25

b.      Once connected use SMTP commands to know if email id exists or not. It will return 250 as a return code with OK or Accepted. Depending upon mail server configuration and Linux flavors too.

Let’s see it practically with all combination of commands, inputs and outputs 😀

Output from nslookup (it will show many more things which I have not shown here)

$ nslookup -type=mx gmail.com
Non-authoritative answer:
gmail.com       mail exchanger = 20 alt2.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 30 alt3.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 5 gmail-smtp-in-v4v6.l.google.com.
gmail.com       mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.

Output from host command ( I prefer this over nslookup )

$ host -t mx gmail.com
gmail.com mail is handled by 30 alt3.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 40 alt4.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 5 gmail-smtp-in-v4v6.l.google.com.
gmail.com mail is handled by 10 alt1.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 20 alt2.gmail-smtp-in.l.google.com.

Get the value which has lowest ranked digit. In this case it is 5 so take gmail-smtp-in-v4v6.l.google.com for our purpose
Either use host or nslookup for the first stage.

Telnet outputs:

Step 1

telnet gmail-smtp-in-v4v6.l.google.com 25
Trying 173.194.77.27…
Connected to gmail-smtp-in-v4v6.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP hk4si16050652obc.168

Step 2 (type helo, if it didn’t work try helo hi, if it didn’t work too try ehlo then )

helo
250 mx.google.com at your service

Step 3 (type any valid email id. Invalid email id will say ok but after rcpt to it will throw an error and don’t skip this step)

mail from: <sanjeev@aliencoders.org>
250 2.1.0 OK hk4si16050652obc.168

Step 4 (You need to provide email which needs to be verified.  Ok means it may exists. Not 1005 guaranteed on existence but we can infer that this email id may work)

rcpt to: <jassics@gmail.com>
250 2.1.5 OK hk4si16050652obc.168

Telnet outputs on failure (Various reasons are there)

1.       Network is unreachable. (sometimes it is reachable form one host but not from others)

telnet gmail-smtp-in-v4v6.l.google.com 25
Trying 74.125.127.26…

telnet: connect to address 74.125.127.26: Connection timed out
Trying 2001:4860:8005::1b…

telnet: connect to address 2001:4860:8005::1b: Network is unreachable

telnet: Unable to connect to remote host: Network is unreachable

2.       Error at mail from:<mail-id> :

  • Don’t forget to use <> while typing email id. jassics@gmail.com is wrong. jassics@gmail.com is correct
  • Never use space before or  after mail id
  • Don’t use single quote or double quote while typing email id

3.       If email id exists but it doesn’t show up 250/ok then below reasons may justify this:

  • Server response delayed
  • Email address black listed
  • Email does not exist  (even if it existed 2 years back )

Steps to check email existence using Perl

  1. Get Mail::CheckUser module from CPAN
  2. Install it either manually or using cpan command
  3. Write simple script using this module and check the output

Good thing with this script is:

  • You don’t need to use any command like host, nslookup telnet and don’t need to remember all those SMTP commands.
  • Just pass the email id rest thing it will do.
  • Internally it checks:
  • It checks the syntax of an email address.   
  • It checks if there any MX records or A records for the domain part of the email address.
  • It tries to connect to an email server directly via SMTP to check if mailbox is valid. It can detect bad mailboxes in many cases.

Here is the fully working Perl script

Why still this trick doesn’t assure 100% proof that email id exists or not?

There can be many reasons for not trusting on this script or the above said manual steps. Best way is to send an email to the given email id. If it bounced back, means it doesn’t exist or can’t be delivered. (I chat with a person in gtalk but can’t send an email to that person. Strange isn’t it).

  • There may be server delay
  • Email id may be black listed
  • It may say it exists if it has to bypass proxies
  • Final output will depend upon server settings which may be using  an algorithm to stop spammer like stuffs
  • For instance SMTP defines the VRFY command for this purpose but gmail doesn’t support it.
  • Never send bulk emails, your mail id will be flagged as a spammers by many hosting companies
  • You may not get proper result because network is unreachable or down by that time

Note: This was just for educational purpose and found helpful for web masters or admins. Don’t use it as spam stuffs, you IP address and your mail id will be blacklisted. Like admin@aliencoders.org has been blacklisted from various mail servers.

Methods to Install Perl modules from CPAN

Installing Perl modules from CPANIf you are working on Perl and you need to work on modules which is listed in CPAN. You may need to download it, install it and use it in your box.

For that you need to know how to install Perl modules. This article will show you simple steps to download and install Perl modules in Linux box. I know its not the new topic for Perl chapter but I wrote it for our standalone repository on Perl and moreover, all these method with examples and pitfalls are not listed at many places. So, I think it will be worthy for our viewers and Perl mongers 😀

Method 1 using cpan shell(It has advantage over manual installation. Read Note section at the bottom)

1. perl -MCPAN -e shell
cpan> install HTML::Template
or
2. perl -MCPAN -e ‘install HTML::Template’
or
3. cpan -i  MIME::Lite

Method 2 Manual module installation
if you’re having problems installing with CPAN. If you’re on the command line, you can use something like wget to grab the file. Next you’ll want to unzip it with something like:

tar -zxvf HTML-Template-2.8.tar.gz

In case above command doesnt work for you, try this
gzip -d XML-Parser-2.36.tar.gz
tar -xvf XML-Parser-2.36.tar

This will unzip the module into a directory, then you can move in and poke around – look for the README or INSTALL files.

In most cases, installing a module by hand is still pretty easy, though (although not as easy as CPAN). Once you’ve switched into the base directory for the module, you should be able to get it installed by typing:(I assume you are on Linux box)
1. perl Makefile.PL
2. make
3. make test
4. make install

If everything shows fine then Thats it. You are now ready to rock and roll with newly installed Perl modues 😀
 

But what if cpan command doesnt work for method 1?
1. Check first if cpan command works in your box
$cpan
cpan: Command not found.
If you get the above result means you need to install cpan module to work from CPAN otherwise, you have cpan installed in your system and you can skim next steps 😀

2. yum install perl-CPAN

3. after successful download and installation. Type cpan for the first time use
and type o conf commit on cpan prompt
then type quit on cpan prompt

You are done!  Now Method 1 will work without fail.

 

Note: If any CPAN module is dependent on the several other modules. CPAN automatically resolves the dependencies and installs other dependent modules. 

cpanm module is more advanced for doing all these without hassle. If possible give it a try.

[ADDED LATER]
As it was commented through Facebook by one of our readers, so I thought to better update this article with his comments.

# Install cpanminus (once).
curl -L http://cpanmin.us | perl – –self-upgrade or
cpan App::cpanminus
# Install your CPAN modules.
cpanm HTML::Template
cpanm XML::Parser
 

Sorting an array and hash elements in Perl

Sorting in PerlSorting an array and hash elements in Perl
This is the answer to Ques# 17 (a) and 23  under Perl Basics in Perl Interview Questions
There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.
In Perl we have sort function which sorts a list alphabetically by default. But there is not the end. We need to sort:

  • an array numerically or
  • case insensitive strings or
  • case sensitive strings
  • hash contents by keys or
  • hash contents by values or
  • reverse of all above said points
 
How sorting  works in Perl
Sort subroutine has three syntaxes and last one is the most used syntax.
  • sort SUBNAME LIST
  • sort BLOCK LIST
  • sort LIST
In list context, it sorts the LIST and returns the sorted list value. In scalar context, the behavior of sort() is undefined.
If SUBNAME or BLOCK is omitted, sorts in standard string comparison order.

Standard string comparison means based on ASCII value of those characters. Like @arr = qw (Call all). In this case it will be sorted as Call all which was not expected. So to make it work properly we use case-insensitive sort.

 If SUBNAME is specified, it gives the name of a subroutine that returns an integer less than, equal to, or greater than 0 , depending on how the elements of the list are to be ordered. (The <=> and cmp operators are extremely useful in such routines.)

Note: The values to be compared are always passed by reference and should not be modified . $a and $b are global variable and should not be declared as lexical variables.

sort() returns aliases into the original list like grep, map etc  which should be  usually avoided for better readability.
As sorting always does string sorting, so to do numeric sorting we need to use a special syntax which a sort {$a $b} LIST. We will see these conditions using Perl codes.
 
How reverse sorting works
Systax to use reverse sort is reverse LIST. It works on sorted LIST usually. But in scalar context, it concatenates the elements of LIST and returns a string value with all characters in the opposite order.
In scalar context if argument is not passed it will reverse the value of $_

Ex:  

[perl]$_ = “dlrow ,olleH”;

print scalar reverse;  #in this case print reverse would not works because it expects a LIST  
[/perl]

How <=> and cmp work?
These are actually binary equality operator. Binary operator usually gives (0 or 1) or (true or false)  but these gives three values based on the comparison result.
Binary  “<=>” returns -1, 0, or 1 depending on whether the left argument is numerically less than, equal to, or greater than the right argument.
Binary “cmp” returns -1, 0, or 1 depending on whether the left argument is stringwise less than, equal to, or greater than the right argument.
Never mix string and numeric values in LIST else sorting result will be fearsome 🙁

Try this out:
[perl]
my @arr1 = qw(1 two 3 0 4  Two 5 six 7 8 9 ten);
my @arr2 = sort {$a cmp $b} @arr1;
print “\n@arr2\n”;
[/perl]
Let go through the codes for different scenarios:
Example 1: Sorting  an array of strings (case-sensitive and case-insensitive examples)
[perl]   
#!/usr/bin/perl
    use strict;
    use warnings;
 
    my @strarr = qw(two Two six Six alien Coders Alien coderS);
    my @sorted = sort {$a cmp $b} @strarr; # same result as of sort @strarr
    my @sortedcase  = sort { uc $a cmp uc $b } @strarr; #case-insensitivie
    print “\n@sorted\n@sortedcase\n”;
 [/perl]
Output:
 
Alien Coders Six Two alien coderS six two
alien Alien Coders coderS six Six two Two
 
Note: try to always use case insensitive for better string sorting results.
 
Example 2: Sorting an array of numbers
The Perl sort function sorts by strings instead of by numbers. If you do it in general way it would fetch unexpected result.
   [perl] #!/usr/bin/perl
    use strict;
    use warnings;
 
    my @numbers = (23, 1, 22, 7, 109, 9, 65, 3, 01, 001);
 
    my @sorted_numbers = sort @numbers;
    print “@sorted_numbers\n”;
[/perl]
The output you would see would be:
    001 01 1 109 22 23 3 65 7 9

To sort numerically, declare your own sort block and use the binary equality operator i.e. flying saucer operator <=>:
  [perl] 
   #!/usr/bin/perl
    use strict;
    use warnings;
 
    my @numbers = (23, 1, 22, 7, 109, 9, 65, 3, 01, 001);
 
    my @sorted_numbers = sort {$a <=> $b} @numbers;
    print “@sorted_numbers\n”;
[/perl]
The output would now be:
    1 01 001  3 7 9 22 23 65 109
Note that $a and $b do not need to be declared, even with use strict on, because they are special sorting variables.

Example 3: Sorting array backwards (for string and numbers)
To sort backwards you need to declare your own sort block, and simply put $b before $a. or use reverse keyword after simple sort.
For example, the standard sort is as follows:
 [perl]   #!/usr/bin/perl
    use strict;
    use warnings;
 
    my @strings = qw(Jassi Alien Coders);
 
    my @sorted_strings = sort @strings;
    print “@sorted_strings\n”;
[/perl]
The output would be:
    Alien Coders Jassi

To do the same, but in reverse order:
[perl] 
  #!/usr/bin/perl
    use strict;
    use warnings;
 
    my @strings = qw(Jassi Alien Coders);
 
    my @sorted_strings = sort {$b cmp $a} @strings; # or reverse sort @strings
    print “@sorted_strings\n”;
[/perl]
The output is:
Jassi Coders Alien

And for numbers:
[perl] 
  #!/usr/bin/perl
    use strict;
    use warnings;
 
    my @numbers = (23, 1, 22, 7, 109, 9, 65, 3);
 
    my @sorted_numbers = sort {$b <=> $a} @numbers; # or reverse sort {$a $b} @numbers
    print “@sorted_numbers\n”;
[/perl]
The output is:
    109 65 23 22 9 7 3 1
This was all about sorting array elements alphabetically or numerically. Now we will see how sorting works on hash elements.

Example 4: Sorting hashes by keys
You can use sort to order hashes. For example, if you had a hash as follows:
Suppose we want to display the members for each community sorted alphabetically or say by keys, then this code will do so:
[perl] 
  #!/usr/bin/perl
    use strict;
    use warnings;
 
    my %members = (
        C => 1,
        Java => 7,
        Perl => 12,
        Linux => 3,
        Hacking => 8,
    );
foreach my $language (sort keys %members) {
        print $language . “: ” . $members{$language} . “\n”;
    }
[/perl]
Output:
    C: 1
    Hacking: 8
    Java: 7
    Linux: 3
    Perl: 12

If you want to sort the same hash by the values (i.e. the users beside each programming language), you could do the following:
[perl]
    #!/usr/bin/perl
    use strict;
    use warnings;
 
    my %members = (
        C => 1,
        Java => 7,
        Perl => 12,
        Linux => 3,
        Hacking => 8,
    );
    # Using <=> instead of cmp because of the numbers
    foreach my $language (sort {$members{$a} <=> $members{$b}} keys %members){
                print $language . “: ” . $members{$language} . “\n”;
}
 [/perl]

Output:
    C: 1
    Linux: 3
    Java: 7
    Hacking: 8
    Perl: 12

Example: 5 Sorting complex data structures
We can also use sort function to sort complex data structures. For example, suppose we have an array of hashes (anonymous hashes) like:
[perl] 
  my @aliens = (
        { name => ‘Jassi’, age => 28},
        { name => ‘Somnath’, age => 27},
        { name => ‘Ritesh’, age => 24},
        { name => ‘Santosh’, age => 29},
        { name => ‘Ranjan’, age => 26},
        { name => ‘Kaushik’, age => 25},
    );
[/perl]
And we wish to display the data about the people by name, in alphabetical order, we could do the following:
[perl] 
  #!/usr/bin/perl
    use strict;
    use warnings;
 
    my @aliens = (
        { name => ‘Jassi’, age => 28},
        { name => ‘Somnath’, age => 27},
        { name => ‘Ritesh’, age => 24},
        { name => ‘Santosh’, age => 29},
        { name => ‘Ranjan’, age => 26},
        { name => ‘Kaushik’, age => 25},
    );
 
    foreach my $person (sort {$a->{name} cmp $b->{name}} @aliens) {
        print $person->{name} . ” is ” . $person->{age} . “\n”;
    }
[/perl]
The output is:
    Jassi is 28
    Kaushik is 25
    Ranjan is 26
    Ritesh is 24
    Santosh is 29
    Somnath is 27

Sorting the same hash by age and using a subroutine (inline function)
Rather than writing the code inline, you can also pass in a subroutine name. The subroutine needs to return an integer less than, equal to, or greater than 0. Do not modify the $a and $b variables as they are passed in by reference, and modifying them will probably confuse your sorting.
[perl]  
#!/usr/bin/perl
    use strict;
    use warnings;
 
    my @aliens = (
        { name => ‘Jassi’, age => 28},
        { name => ‘Somnath’, age => 27},
        { name => ‘Ritesh’, age => 24},
        { name => ‘Santosh’, age => 29},
        { name => ‘Ranjan’, age => 26},
        { name => ‘Kaushik’, age => 25},
    );
 
    foreach my $person (sort agecomp @aliens) {
# it just replaced {$a->{age} <=> $b->{age}} by agecomp inline function
        print $person->{name} . ” is ” . $person->{age} . ” years old\n”;
    }
 
    sub agecomp {
        $a->{age} <=> $b->{age};
    }
[/perl]
The output would be:
    Ritesh is 24 years old
    Kaushik is 25 years old
    Ranjan is 26 years old
    Somnath is 27 years old
    Jassi is 28 years old
    Santosh is 29 years old

To find out more on sort function,  run the command on Linux box:
    perldoc -f sort
 
 

How to move or copy a file using Perl

There can be n number of ways to copy or move a file using Perl programming. Like invoking system command or using Linux or windows system command through backtick. But I found using a module called "File::Copy", nice and cleaner way to accomplish the task. It will take care of Operating System issues and other dependencies.
And the good thing is, it's available in core Perl!

So we will use File::Copy module and will call copy() function to copy the file and move() function to move the files.

Ok then, How it works?

Finding the length of an array and a hash

Learn PerlDetermining the length of an array and a hash

If you are working on Perl, then you will need to find the length or size of an array, hash, and array/hash elements very often.
Meaning of Size or length depends upon for which context you are talking about.  Generally it means the number of characters in a string, or the number of elements in an array/hash.
But, if you are using Unicode characters then the number of characters in a string may be different to the number of bytes in the string. So the in-built function length may give different result for different context.

We will see it by using different examples based on different problems:

Example 1. Finding length() of string
To determine the number of characters in an expression use the length() function:
    [perl]#!/usr/bin/perl
    use strict;
    use warnings;
 
    my $name = 'Jassi';
    my $size = length($name);
 
    print "$size\n";
    exit 0;[/perl]
This example prints the number of characters in the string $name:
    5

Example 2. Find the bytes used by string using length()
What, if you want to know the bytes occupied by the string not the characters it holds?  This may not matter if  you are using ASCII characters but it may, if you are using Unicode characters.
By default the length() function returns the number of characters. You can tell it to return the number of bytes by specifying use bytes; in the program as in this example:
  [perl]  #!/usr/bin/perl
     use strict;
    use warnings;
 
    my $char = "\x{263a}";    # A smiley face
    {
         use bytes;
        my $byte_size = length($char);
        print "Bytes: $byte_size\n";
        no bytes;
    }
    # Character size here
    my $size = length($char);
    print "Chars: $size\n";
     exit 0;[/perl]
This outputs:
    Bytes: 3
    Chars: 1
 
Note: either use closure or whenever you use “use bytes” try to use “no byets” once you are done

Number of element in an array
Example 3: using array’s last index
In Perl you can determine the last element of an array easily ($#array_name) and add 1 to it to find the number of elements in that array.
   [perl] #!/usr/bin/perl
    use strict;
    use warnings;

my @alien_members = qw(jassi Ritesh Ranjan som Santosh);
    my $size = $#alien_members + 1;
    print "$size\n";
    exit 0;[/perl]
This gives us:
    5
Example 4.  Using scalar context of an array
If you assign an array to a scalar variable, it will return the number of elements of that array:
  [perl]  #!/usr/bin/perl
     use strict;
    use warnings;
 
    my @alien_members = qw(jassi Ritesh Ranjan som Santosh);
    my $size = @alien_members;
 
    print "$size\n";
    exit 0;[/perl]
This gives us:
    5
Apart from being confusing to read, this method can lead to some easy mistakes. For example, consider the following program:
   [perl] #!/usr/bin/perl
     use strict;
    use warnings;
 
     my @alien_members = qw(Jassi Ritesh Ranjan som Santosh);
    print "@alien_members\n";
    print @alien_members."\n";
     exit 0;[/perl]
What would you expect it to print?
Each array elements to a new line like
Jassi
Ritesh
Ranjan …
Nope it would print
Jassi Ritesh Ranjan som Santosh
5
When double-quotes included, it treats arrays differently. The double-quotes cause Perl to flatten the array by concatenating the values into a string. So behind the stage, something like this happened.
“Join each array element by space and assign it to a scalar variable. So it became a string.” It is something like $size = “@alien_members”; which will differ from $size = @alien_members;

try to print these two statements and see the difference.
 But check second print output. Isn’t it strange?

Example 5. Arrays: never use length() to find the number of elements in an array.
You have seen  the use of length at Example#1 but still If you try to use the length() function on an array, it won't give you the desired output.
    [perl]#!/usr/bin/perl
 
    use strict;
    use warnings;
 
    my @alien_members = qw(Jassi Ritesh Ranjan som Santosh);
    my $size = length(@alien_members);
     print "$size\n";
    exit 0;[/perl]
The output is not what you thought:
    1
This is because the length() function requires a scalar, so the array is forced into scalar context.
And we saw already (example 4) that an array in scalar context already gives us the length. The example above is giving us the length of the length i.e. the length of 5 is 1. Hope it makes sense!

Example 6. Finding the number of elements using scalar() function
No doubt that Example 3 and 4 are correct but they aren't much clear and friendly to use in our program (readability problem you can say). Perl has the scalar() function which forces the array into scalar context which will give you the length of an array (even hash too):
   [perl] #!/usr/bin/perl
 
    use strict;
    use warnings;
 
    my @alien_members = qw(Jassi Ritesh Ranjan som Santosh);
    my $size = scalar(@alien_members);
 
    print "$size\n";
    exit 0;[/perl]
This also gives us the correct answer:
    5

Example 7. Finding the number of elements in a hash
Sometimes you will also want to have the number of elements of a hash. This is easily done using the keys() function to return the keys as an list, and the scalar() function to return how many keys there are (it is very common question in interviews too):
  [perl]  #!/usr/bin/perl
 
    use strict;
    use warnings;
 
    my %alien_members_rank = (
        Jassi => 1,
        Ritesh   => 2,
        Ranjan   => 3,
        Somnath    => 5,
        Santosh => 4
    );
    my $size = scalar(keys %alien_members_rank);
 
    print "$size\n";
    exit 0;[/perl]
The output of this program is:
    5
Note: it will not give 10 as you might have thought in context of an array. It can give you no of keys elements and then you can just multiply it by 2 😀

For more details on these functions, see also
    perldoc -f length
    perldoc -f scalar
    perldoc bytes
  
 

Review on Modern Perl by Chromatic

Modern Perl by ChromaticWhat is Perl

Perl is the Swiss Army knife for scripting languages (rather call it programming language): powerful and adaptable. It was first developed by Larry Wall, a linguist working as a systems administrator for NASA in the late 1980s, as a way to make report processing easier.

Since then, it has moved into a large number of roles: automating system administration, acting as glue between different computer systems; and, of course, being one of the most popular languages for CGI programming on the Web.

For more information on Basic introduction on Perl, please click here
We have posted a small post on “Applications based on Perl”.

Why Modern Perl (2011-2012 edition)?

According to author Chromatic  “When you have to solve a problem now, reach for Perl. When you have to solve a problem right, reach for Modern Perl.”

There are lots of books available on Perl in the market then why and how it is unique and very popular amongst Perl programmers?
The reason is very simple , it’s author Chromatic is well renowned face over the Perl community and this book covers various features that are introduced in 5.10,5.12 and 5.14 and it got released on February,2012

Its list of contents looks very promising to me. No matter who you are, a novice in Perl or an expert; this book has something new, interesting and informative contents for you.

First three chapters deal with Perl Philosophy, its community and Basics of Perl Language. The contents are very informative and full summary on what you can achieve through Perl. You can start writing simple Perl code just after reading first three chapters too!

Next three chapters on Operators, Functions and Regular Expression will make you almost a Perl programmer within no time. If you don’t want to use object oriented Perl, then You will find yourself a comfortable programmer in Perl’s zone. But Perl’s power can’t be judged by stopping there. So next few chapters will show you the real implementation and object Oriented Perl

The next three chapters deal with Perl objects, style and efficacy and managing real Programs. These chapters will teach you

  • How to use Object Oriented concept effectively in Perl
  • Moose and Perl features
  • Pragmas, exceptions
  • How to maintain large programs
  • How to write effective Perl programs
  • How to use testing module
  • How to use file handling things and other fundamental things like overloading, taint etc

Then last three chapters deal with some exceptional topics which other authors or programmers avoid usually. Chromatic has explained and portrayed these things beautifully. He has explained

  • Syntax  like handling $self, named parameters, handling main, Global variables etc
  • What to avoid while writing Perl programs like barewords, prototypes etc
  • Missing defaults like strict, warnings, autodie etc.

Who is Chromatic

Well I put a small review on Modern Perl and praise author many times. Now who is Chromatic ?
He is a writer and free software programmer from USA. He is the author of many other popular books like

  • Extreme Programming Pocket Guide
  • Perl Hacks
  • Co-author of “Perl Testing: Developer’s Notebook”
  • Noted contributor to “The Art of Agile Development”

He has contributed to CPAN, Perl 5, Perl6 and Parrot too. He was the project secretary of Perl6 and Parrot Foundations too. He is the core developer for Parrot – an open source virtual machine created I n 2008.

From where we can buy it or download it

  • You can buy it from Amazon or Powells or Barnes and Noble book store.
  • You can download its electronic version in A4 or letter format too.
  • Get all the details about download options from Onyx Neon Press
  • You can download it from our website too!

Rating for Modern Perl (4.5/5)

I would recommend this book for all Perl enthusiasts. If you wish to start a career in Perl programming or you are a beginner in Perl Programming then just read its first three chapters and decide ahead. Check our other books recommendation below.

For intermediate and Advanced level Perl Programmers, it’s a must read book.

It would be really nice if it would have shown some real example with screenshots and output.

Other books on Perl

How to find the list of installed modules in Perl

This is one of the questions asked in many Perl related job interviews. See the question here: http://www.aliencoders.org/content/interview-questions-perl-freshers-and-experienced
There will be some situations when you will need to know about installed modules, its version or you may need to check if required module is installed or not with mentioned version or higher than that.

Here are few ways through which you can achieve the result that I found over the internet from different websites.

1. To list all installed Perl modules using perl script

[perl]
#!/usr/bin/perl   #change the path  with your perl location
use strict;
use warnings;
use ExtUtils::Installed;  # By default this module will be available in Perl

my $instmod = ExtUtils::Installed->new();
foreach my $module ($instmod->modules()) {
    my $version = $instmod->version($module) || “Version Not Found.”;
    print “$module version=$version \n”;
}
[/perl]

2. To list installed Perl modules using command line in Linux box

Try instmodsh command in linux box
and then type l to list modules or m to give particular module name or q to quit

[code] $ instmodsh[/code]

Output:
[code]Available commands are:
l            – List all installed modules
m    – Select a module
q            – Quit the program
cmd?[/code]
At cmd? prompt type l to list all installed modules:
[code]cmd? l[/code]
Output:
[code]Installed modules are:
Archive::Tar
CPAN
Compress::Zlib
MIME::Lite
Module::Build
Net::Telnet
PAR::Dist
Perl
Spiffy
Test::Base
Test::Simple
XML::Simple
cmd?
[/code]

This command itself is a perl script that use ExtUtils::Installed module. Try following command to see its source code:
[code]$ vi $(which instmodsh)[/code]
For more details, visit this link: http://perldoc.perl.org/instmodsh.html

3. To compare and check installed Perl modules with respect to given modules with its version

[perl]
#!/usr/bin/perl
use strict;
use warnings;
my @modules = ([‘SOAP::Lite’, 0.50],
           [‘IO::Socket’, 0],
           [‘HTML::Parser’, 3.26],
           [‘LWP’, 5.65],
          );

print “\n”,
      “==========================\n”,
      “Testing for the given  Perl modules\n”,
      “===========================\n”;
      
    for my $arr_ref (@modules) {
        my($mod, $ver) = @$arr_ref;
        print “$mod” . ($ver ? ” (version >= $ver)” : “”) . “\n”;
        
        eval(“use $mod” . ($ver ? ” $ver;” : “;”));
        if ($@) {
            my $msg = $ver ?
                      “\tEither it doesn’t have $mod installed,\n” .
                      “\tor the version that is installed is too old.\n” :
                      “\tIt does NOT have $mod installed.\n”;
            print “$msg\n”;
        }
        else {
            print “\tYour system has $mod installed ” .
                  “with version @{[ $mod->VERSION ]}\n\n”;
        }
    }

print “Module Testing Done!\n”;
[/perl]

Note: If you are putting module name dynamically, then use  @{[ $mod->VERSION ]} for version number
else $Module-Name::VERSION ex: $SOAP::Lite::VERSION

[perl]
print “SOAP::Lite Version is “. $SOAP::Lite::VERSION.”\n”;
#or
 print “$mod version is @{[ $mod->VERSION ]} \n”;
 [/perl]

4. To list Perl modules that comes preinstalled with the standard Perl package and installed from outside
[perl]
perldoc perlmodlib #lists all the modules that come with standard Perl package already
perldoc perllocal #lists all modules that is installed from outside
[/perl]
Both modules reveal lots of information about each installed modules like installation date, directory, module version etc.