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

Hi I am trying to do a basic IRC chat client in Perl using TK and IO::Stream and a few other modules that are not important to the problem. So basically whats going on here is the response from the server is suppose to be inserted into the listbox or chat window if you will but its not working for some weird reason heres parts of the code.
# Fork it into two process's my $kidpid; die "Cant Fork: $!" unless defined($kidpid = fork()); if ($kidpid) { while (defined ( my $line = <$sock> ) ){ chomp($line); $line =~ s/(\x0a|\x0d)//g; # Display response from server &show($line); print "<< $line\n";
The &show($line); Is what runs the sub routine to enter the response from the server into the list box heres that routine.
sub show { my $line = $_; print "Testing if this is even working!!!\n\n"; print "<< $line\n"; $scrolledText -> insert('end',"<< $line"); # Insert the text in +to the Listbox $scrolledText }
Now the print statement that says "Testing if this is even working!!!" Is printing so the routine is being called. But the Text is not inserting into the ListBox.Also the Print "<< $line\n"; is only printing out the << part and not the response from the server. If anyone knows why this is happening it would be appreciated a lot thank you.

Replies are listed 'Best First'.
Re: Perl - TK - Listbox insertion problem
by GrandFather (Saint) on Apr 23, 2010 at 03:17 UTC

    You can't share variables across forked processes so $line in the socket polling process is not the same $line used by Tk.

    True laziness is hard work
Re: Perl - TK - Listbox insertion problem
by almut (Canon) on Apr 23, 2010 at 08:44 UTC
    sub show { my $line = $_; ... }

    Arguments to routines are passed in the array @_, not $_. So either write

    sub show { my $line = shift;

    or

    sub show { my ($line) = @_;

    or

    sub show { my $line = $_[0];

    With that change, things should work just fine, provided the loop that reads from the socket is in the main/parent process — which it seems to be.

Re: Perl - TK - Listbox insertion problem
by choroba (Cardinal) on Apr 24, 2010 at 21:33 UTC
    Have you tried using fileevent? Something along these lines works for me (though with Attempt to free unreferenced scalar at the end):
    open $STDIN,'-'; $top->fileevent($STDIN,readable => sub { my $line = <$STDIN>; $listboxb->insert('end',$line); });
      I tried this but im not sure that i am implementing it properly heres the code.
      # Fork it into two process's my $kidpid; die "Cant Fork: $!" unless defined($kidpid = fork()); if ($kidpid) { while (defined ( my $line = <$sock> ) ){ chomp($line);# = $_); $line =~ s/(\x0a|\x0d)//g; # Display response from server open $STDIN,'-'; $mainWindow->fileevent($STDIN,readable => sub { my $line = <$STDIN>; $scrolledText->insert('end',$line); });
      And heres the Error i get
      drew@Phantom:~$ perl irc.pl >> NICK k0rn >> USER k0rnh0le localhost localhost Andrew Tk::Error: Can't locate object method "OPEN" via package "Tk::Event::I +O" at irc.pl line 444, <GEN1> line 2. <Key-Return> (command bound to event) perl: ../../src/xcb_io.c:242: process_responses: Assertion `(((long) ( +dpy->last_request_read) - (long) (dpy->request)) <= 0)' failed. perl: ../../src/xcb_io.c:242: process_responses: Assertion `(((long) ( +dpy->last_request_read) - (long) (dpy->request)) <= 0)' failed. Aborted
      Thank you very much for your help.
        In your case, you should not use STDIN, but the socket as the source of the events (I am not sure whether it is possible, but if not, you can try sending the lines from the socket to a file and use its filehandle...).