rpetre has asked for the wisdom of the Perl Monks concerning the following question:

My Perl "career" got to the point where I'm trying to write an IRC bot (yeah, I'm 10 years behind). So far I've discovered Bot::BasicBot and it's pretty cool, but I'd like it to have a background thread that does things (for now, watch for new SVN revisions in our internal repo and announce them on IRC).

So I wrote a sub called watch_svn which is basically an infinite loop that prints messages on STDOUT and I'm calling it with a Bot::BasicBot::forkit method in the connected() routine of the bot.

Problem is I don't see anything printed by the bot (though it seems to be looping, i see /usr/bin/svn being spawned from time to time) and I can't figure out how to log stuff. The module has a log() subroutine and I tried passing a reference for the bot to watch_svn so I can do $self->log there, but it doesn't work.

Here's a condensed version of the script:

#!/usr/bin/perl use warnings; use strict; package Marvin; use base 'Bot::BasicBot'; my $channel = '#irctoys'; my $server = 'my.internal.server'; my $nick = 'marvin'; #### IRC event handlers overload #### sub connected { my $self = shift; $self->forkit({ channel => $channel, run => \&watch_svn, arguments => [ $self ], }); } #### my stuff #### sub watch_svn { my $self = shift; $self->log("watch_svn: Started main loop\n"); while (1) { $self->log("watch_svn: Inside main loop\n"); print "this should go on $channel\n"; sleep 60; } } #### actual bot #### package main; Marvin->new(nick => $nick, channels => [ $channel ], server => $server + ) ->run; exit;

I only get on stderr the messages from the bot stating that it joined the server and the channel, and nothing else. Help?

Replies are listed 'Best First'.
Re: Bot::BasicBot forkit - help needed
by moritz (Cardinal) on Jul 20, 2009 at 16:22 UTC
    You don't need to spawn a background process for that. In my own IRC bot based on Bot::BasicBot I use the tick method to periodically check the svn repository.

      Thanks, I'll steal the idea, but this still leaves me a couple of questions:

      • I understand I can only have one tick that schedules the next and so on, this makes it pretty complicated if I want to have multiple tasks;
      • I am still at a loss regarding debugging this. I don't think the debugger will be as simple with POE in the mix. I'll try, but logging to stderr would still be nice.
        You could try to dig more into the POE stuff - I'm sure timers aren't that hard.
        but logging to stderr would still be nice

        Nothing prevents you from using warn or print STERR $msg; to achieve that.

        Did you ever come up with a way to schedule multiple tasks? I was thinking of using tick to fork each task each with its own wait time. I think there is some logic problem there, but it's a start.

        # psuedo sub tick { # stuff.... $self->forkit( run => \&task1, channel => $channel, arguments => [ $arg1, 20 ] ); # Where second arg is for a sleep. $self->forkit( run => \&task2, channel => $channel, arguments => [ $arg1, 40 ] ); # Where second arg is for a sleep.

        Neil Watson
        watson-wilson.ca