By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,374 Members | 2,014 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,374 IT Pros & Developers. It's quick & easy.

Subroutines called from other subroutines

P: 7
In an effort to get back into programming, I've decided to tackle an IRC bot in Perl. As some background info, I am using the POE::Component::IRC module, using strict and warnings, and I'm not intending this to do anything illegal. I can assure you this is simply for my own education. I have already built one that can do some amusing little tricks, but one aspect of my current project is giving me a headache.

I'm having some trouble with subroutines. Specifically, there are methods in the IRC module I am using called "irc_msg" and "irc_public" which are called when you receive a private message and when someone speaks in the channel, respectively. When those are called, I check to see if the message is a bot command, in this case "+lecture"

If the whisper/message matches the command, a subroutine named "begin_lecture" is called. This sub implements a while loop to read a file (called a "lesson plan") line-by-line, posting each line as a new message to the channel.

If the line happens to be ":pause X" where X is a number, the output will be delayed for X seconds. This is so I can give readers some time between messages.

The problem I am having is that, although the function is called properly when I say/whisper "+lecture" it is not being executed how I would expect. Instead of printing a line, pausing, printing, pausing, etc., it waits the total number of seconds, then outputs all messages at once.

I believe this is because the output of the while loop is being returned to the calling function, effectively causing a huge delay followed by a wall of text.

Is there a way I can "fork" the begin_lecture sub (not sure if fork is the right word) to fix this behavior? Ideally, it should appear as if the text is being typed, with appropriate pauses in between each message.

I have supplied the relevant code below:

Expand|Select|Wrap|Line Numbers
  1. sub irc_msg {
  2.     my ($sender, $who, $recip, $what) = @_[SENDER, ARG0 .. ARG2];
  3.     my $nick = ( split /!/, $who )[0];
  5. #Call lecture function
  6.     if (my ($lecture) = $what =~ /^\+lecture/) {
  7.         &begin_lecture();
  8.     }
  10. return;
  11. }

actual "begin_lecture" code:
Expand|Select|Wrap|Line Numbers
  1. sub begin_lecture {
  3.         open(LESSON, $ARGV[0]) or die("Cannot find my lesson plan!\n");
  5.         my $line;
  6.         my $channel ="#chatter";
  8.         while ( $line = <LESSON>) {
  10.                 if (my ($pause) = $line =~ /^\:pause (.+)/) {
  12.                         sleep $pause;
  13.                         next;
  14.                 }
  16.                 $irc->yield( privmsg => "$channel" => "$line" );
  17.         }
  19. }
May 8 '10 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.