http://qs321.pair.com?node_id=297890


in reply to POE, was Re: Tk tail -f - How?
in thread Tk tail -f - How?

Thanks all,
I put the following together using the tips from perldoc -q "tail -f". As a POE user I was under the impression that the Tk tail would fail on Win32 due to the lack of fileevent - I haven't used it recently so it may be fixed.

This first version hangs onto the filehandle as you say so it needs some thought to emulate --follow=name.

#! perl use strict; use warnings; use Tk; # my $file = "C:\\openejb-0.8.3\\openejb.log"; # my $title = "Tk Tail"; my $version = "1.0"; my $mw = new MainWindow( -title => $title ); # Nicer fixed-width font... $mw->fontCreate( 'listboxfont', -family => 'courier', -size => '8' ); my $fr = $mw->Frame()->pack( -expand => 1, -fill => 'both' ); # $fr->Label( -text => "File to tail" )->pack; $fr->Entry( -textvariable => \$file, -width => '50', -font => 'listboxfont', )->pack; $fr->Button( -text => 'GO', -command => \&gopush )->pack; my $listbox = $mw->Scrolled( 'Listbox', -setgrid => '1', -height => '10', -width => '50', -font => 'listboxfont', -selectmode => 'extended', -scrollbars => 'se', -bg => 'black', -fg => 'green', ); $listbox->pack( -expand => 'yes', -fill => 'both', -pady => '3' ); my $fr_statusbar = $mw->Frame( -relief => 'sunken', -borderwidth => '1', )->pack( -fill => 'x' ); #~ $fr_statusbar->Label( -image => $smallicon )->pack(-side => 'left') +; $fr_statusbar->Label( -text => "Version: $version" )->pack( -side => ' +left' ); # sub gopush { close F; open F, '<', $file or die $!; timerstart(); } # repeating actions... my $timerid; sub timerstart { &timerstop(); $timerid = $mw->repeat( 1000, \&timerproc ); } sub timerstop { if ($timerid) { $timerid->cancel; } } sub timerproc { while (<F>) { chomp; my $text = $_; $listbox->insert( 'end', $text ); $listbox->see('end'); $mw->update(); } seek( F, 0, 1 ); } MainLoop();

Replies are listed 'Best First'.
Re: Re: POE, was Re: Tk tail -f - How?
by BrowserUk (Patriarch) on Oct 09, 2003 at 12:43 UTC

    You might want to add a check for the number of lines you have in the listbox and limit it to some reasonable size.

    If your file grows quickly, you could rapidly find yourself running out of memory, and (if my limited experience of Tk is still valid) things start to slow down when widgets grow beyond a certain size.

    It would be more efficient to load the listbox using

    $listbox->insert( 'end', <F> ); $listbox->see( 'end' ); $mw->update();

    Also, you probably shouldn't be seeking to the end after you have read. If nothing has been added, it will make no difference as you will already be there. However, if something was added between the last read and the seek, you will never read it and lines (or partial lines) will be lost..


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail

      Of course :) after insert task I have added...
      my $trim = $listbox->size - $maxlines; $listbox->delete(0, $trim-1) if trim > 0;
      I accept the point re last-read-to-seek-delay-data-loss: any ideas anyone?

      Otherwise I don't see any harm with the seek(F,0,1) - isn't it required in order to clear the EOF condition as per docs?

        any ideas anyone?

        What my one-liner above demonstrated was that if you read the file with the diamond operator, the way you detect eof, is when it returns undef. If you simply ignore the undefs and continue reading, the eof condition clears itself without any further action required..

        Given the docs you cite, I'm not sure if this is "working as designed" or an an undocumented and therefore unreliable feature, but it has worked this way in every version of perl I've used. About the oldest script I have that I still use makes use of this feature.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail

Re: Re: POE, was Re: Tk tail -f - How?
by rcaputo (Chaplain) on Oct 09, 2003 at 14:37 UTC
    As a POE user I was under the impression that the Tk tail would fail on Win32 due to the lack of fileevent - I haven't used it recently so it may be fixed.

    It is fixed in the latest release, version 0.27. POE works around ActivePerl's Tk fileevent problems by polling internally. All the usual I/O methods (select_{read,write}, the Wheel classes, and Components) should magically start working after an upgrade.

    -- Rocco Caputo - rcaputo@pobox.com - poe.perl.org