A couple of things I love about Perl

Published by at 27th October 2010 12:15 am

In the time that I've been learning Perl, I've slowly grown to appreciate the strengths of the language more and more. There's two things in particular that I like about Perl. Once that I really don't think anyone is going to be surprised by is CPAN. It's a fantastic resource - there are a huge quantity of Perl modules available for virtually any task under the sun, and they're incredibly useful.

The other is just how good the documentation is - I've never considered myself to be someone who learns terribly well from Unix man pages, but perldoc seems to have very good documentation indeed, including that for CPAN modules. Also, it helps that if you don't do well with the man page format, you have the option of running podwebserver and getting the documentation formatted as web pages.

To give an example, I'm particularly interested in all kinds of network programming, be it web development, IRC, Jabber or whatever, and I'd heard of the Net::IRC module so I decided to start using it to create a simple IRC bot (yes, I know I should really be using POE::Component::IRC instead!). Using the information gleaned from perldoc Net::IRC it was easy to get started writing a bot, and I've now come up with the following simple bot:

1#!/usr/bin/perl -w
2
3use strict;
4use Net::IRC;
5
6my $irc = new Net::IRC;
7my $nick = "mattsbot";
8my $server = "irc.freenode.net";
9my $channel = "#botpark";
10my $port = 6667;
11my $ircname = "My wonderful bot";
12my $owner = "mattbd";
13
14sub on_connect
15{
16 my $self = shift;
17
18 print "Joining $channel\n";
19 $self->join($channel);
20 $self->privmsg($channel,"Ready to go!");
21}
22
23sub on_disconnect
24{
25 my $self = shift;
26 $self->join($channel);
27 $self->privmsg($channel, "Sorry about that - dropped out for a sec.");
28}
29
30sub on_join
31{
32 # Get the connection and event objects
33 my ($conn, $event) = @_;
34
35 # Get the nick that just joined
36 my $newnick = $event->{nick};
37
38 # Greet the new nick
39 $conn->privmsg($channel, "Hello, $newnick! I'm a greeting bot!");
40}
41
42sub on_msg
43{
44 # Get the connection and event objects
45 my ($conn, $event) = @_;
46
47 # Get nick of messaging user
48 my $messager = $event->{nick};
49
50 # Respond negatively
51 $conn->privmsg($messager, "Sorry, I'm just a bot. Please don't message me!");
52}
53
54sub on_public
55{
56 # Get the connection and event objects
57 my ($conn, $event) = @_;
58
59 # Get nick of messaging user
60 my $messager = $event->{nick};
61
62 # Get text of message
63 my $text = $event->{args}[0];
64
65 # Check to see if text contains name of bot - if so message the user negatively
66 if($text =~ m/$nick/)
67 {
68 $conn->privmsg($channel, "Sorry, $messager,I'm just a simple bot!");
69 }
70}
71
72my $conn = $irc->newconn(Nick =>$nick,Server=>$server,Port=>$port,Ircname=>$ircname);
73$conn->add_global_handler('376', \&on;_connect);
74$conn->add_global_handler('disconnect', \&on;_disconnect);
75$conn->add_global_handler('msg', \&on;_msg);
76$conn->add_global_handler('join', \&on;_join);
77$conn->add_global_handler('msg', \&on;_msg);
78$conn->add_global_handler('public', \&on;_public);
79$irc->start();

Now, this bot isn't exactly hugely capable - all it does is greet new joiners, and tell you to leave it alone if you try to talk to it, but it was pretty easy to code it, thanks to the documentation, and it's a good base to build on. From here, it's easy to extend the on_public and on_msg subroutines to deal with other messages - for instance, I could use a regular expression to look for "!respond" in the text of the message and if it's found, respond with any appropriate text.

I've hard-coded the appropriate details into the script in this case to make it quicker and easier to test it, but it would be trivial to change it to either accept settings passed as arguments from the command line, or have it grab these from a separate text file.

My initial doubts about Perl are really wearing off. It's a powerful language and one that, now I've picked up the basic syntax, I'm having little trouble getting work done with.