Subject: comp.lang.perl.tk FAQ part4 of 5
Date: Fri, 15 Mar 1996 09:04:33 GMT

Summary: comp.lang.perl.tk Frequently Asked Questions.
Posting-Frequency: monthly
URL: http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.html
Version: 0.01

URL (Hypertext-split): http://w4.lns.cornell.edu/~pvhp/ptk/ptkTOC.html
URL (Plaintext): http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.txt
Image-supplement: http://w4.lns.cornell.edu/~pvhp/ptk/ptkIMG.html
ftp-Archive: ftp://ftp.ccd.bnl.gov/pub/ptk/ptkFAQ.txt
ftp-Archive: ftp://ftp.wpi.edu/perl5/pTk-FAQ
ftp-Archive: ftp://rtfm.mit.edu/pub/usenet/perl-faq/ptk-faq/
e-mail-Archive: ptkfaq@pubweb.bnl.gov
gopher-Archive: 128.84.219.153

Perl/Tk FAQ part 4 of 5 - More Perl/Tk     
************************************** 

 ______________________________________________________________________
 
 
 
 12. What are some of the primary differences between Tcl/Tk and Perl/Tk? 
 
 Considering that both interpreter/compilers for Tcl and Perl were written in
 C for use on Unix computers it is not surprising that there are some
 similarities between the two languages. 
 
 Nevertheless, there are a large number of differences between the Tcl
 scripting language and the Perl scripting language. Indeed, some of the Tk
 widget names and options have been modified slightly in the perl/Tk
 language (at least as of the Tk-b9.01 version). With Tk-b9.01 (and higher)
 a great many functions start with an upper case letter and continue with all
 lower case letters (e.g. there is a perl/Tk Entry widget but no entry
 widget), and many configuration options are all lower case (e.g. there is a
 perl/Tk highlightthickness option but no highlightThickness
 option). Thus if you are having trouble converting a script check your typing.
 
 While this table does not cover all the differences it is hoped that it will
 prove useful, especially to those people coming from a primarily Tcl/Tk
 background. These are some of the common Tcl->Perl stumbling points: 
 
 
 what              Tcl/Tk                 Perl/Tk
 variable          set a 123              $a = 123; or $a = '123';
  initialization
 re-assignment     set b $a               $b = $a;
 
 lists/arrays      set a {1 2 fred 7.8}   @a = (1,2,'fred',7.8);
 re-assignment     list set b $a          @b = @a;
 
 associative       set a(Jan) 456.02      %a = ('Jan',456.02,'Feb',534.96);
  arrays           set a(Feb) 534.96
 re-assignment     foreach i \            %b = %a;
                    [array names a] {
                    set b($i) = $a($i) }
 
 Note on the above examples:
 In Tcl the scalar, list, and array variable 'a' will overwrite each 
 previous assignment.
 In Perl $a, @a, %a are all distinct (occupy separate namespaces).
 
 expressions       set a [expr $b+$c]     $a = $b+$c;
 
 increment         incr i                 $i++;
 
 declare           proc plus {a b} {      sub plus { my($a,$b) = @_;
  subroutines       expr $a + $b }         $a+$b; }
 
 variable scope    local default          global default
                   override w/ "global"   override w/ "my"    
 
 call              plus 1 2               &plus(1,2); #or
  subroutines                             plus(1,2);  #OK after sub plus
 
 statement sep     newline or at ";"      ";" required
 
 statement         "\" - newline          none required
  continuation
 
 verbatim strings  {}                     ''
  e.g.             {a \ lot@ of $stuff}   'a \ lot@ of $stuff'
 
 escaped strings   ""                     ""
  e.g.             "Who\nWhat\nIdunno"    "Who\nWhat\nIdunno"
 
 STDOUT            puts "Hello World!"    print "Hello World!\n"
                   puts stdout "Hello!"   print STDOUT "Hello!\n"
 
 Note also that Tcl/Tk has a built-in abbreviation completion mechanism
 that lets you specify short hand, e.g. 
 
    canvas .frame.canvas -yscrollcommand ".frame.scroll set" ; #Tcl/Tk OK
    canvas .frame.canvas -yscroll ".frame.scroll set" ;        #Tcl/Tk also OK
    $canvas=$main->Canvas(-yscroll => ['set',$scroll]);  #ERROR perl/Tk
    $canvas=$main->Canvas(-yscrollcommand => ['set',$scroll]); #perl/Tk OK
 
 You may get around this with the perl abbrev.pl package in certain
 circumstances. For example: 
 
    require 'abbrev.pl';
    %foo = ();
    &abbrev(*foo,'-yscrollcommand');
  ...
    $canvas=$main->Canvas($foo{'-yscroll'} => ['set',$scroll]); #perl/Tk OK
 
 There is no Perl equivalent to the Tcl unknown proc. However, you can
 emulate unknown behavior (through the perl AUTOLOAD mechanism) as
 follows: 
 
     use Shell;
     print($p = man(-k => bitmap));
 
 In case you do not recognize the above incantation it is equivalent to what
 you would get if you typed: 
 
     man -k bitmap
 
 From within tclsh or wish. (Thanks to Ilya Zakharevich 
 <ilya@math.ohio-state.edu> for pointing out this "feature" ;-) 
 
 ______________________________________________________________________
 
 
 
 How do I install new scripts | modules | extensions? 
 
 (Thanks to Ilya Zakharevich <ilya@math.ohio-state.edu> for pointing out
 that perl code comes in a variety of flavors and some code requires more
 work than others to install. Hence I have expanded this topic and will refer
 to three distinct categories here: Scripts Modules and Extensions:) 
 
 Scripts
 -------
 
 A "self-contained" script needs little modification (in principle!) to run. It
 is a good idea to check the #! line at the very top of the file to reflect your
 local perl setup (e.g. #!/usr/bin/perl -w (change to) 
 #!/usr/gnu/local/perl -w or what have you). There are allegedly
 "more portable" ways to invoke the perl interpretor as well - they are more
 fully documented in the perl FAQ and the perlrun(1) man page,
 however. 
 
 Other things you do not want to forget when trying to run a perl script
 include giving yourself permission to do so, e.g.: 
 
     chmod u+x newscript
 
 You also want to be sure your DISPLAY environment variable is set up
 properly when attempting to run a perl/Tk script. You may also need to look
 at the xhost(1), the xauth(1) man pages for setting up your X-display
 properly. 
 
 If you are still experiencing difficulty check to be sure that extraneous
 /newsgroup|e-mail|HTML headers|footers|markup//; are not in the file and
 that you have on hand all that is requireed or useed by the script (if not
 you may need to install a module - or even a perl4 style lib.pl file). 
 
 Modules
 -------
 
 Check out the module - make sure it is OK and will run on your system -
 does it require a specific location? For testing purposes (always a good idea)
 or if you do not have root priveleges set the file in a directory that you do
 have write access to and try to include it in a test script. Assuming you have
 a module to test called "Foo.pm" and are simply running the test script in
 the same directory as the module begin by adding to the @INC array like so: 
 
     #!/usr/bin/perl -w
      BEGIN { @INC = ("$ENV{'PWD'}",@INC); }
      use Tk;
      use Foo;
 
 or 
 
     #!/usr/bin/perl -w
      use lib $ENV{PWD};
      use Tk;
      use Foo;
 
 Another approach is to set either the PERLLIB or PERL5LIB environment
 variable from your shell. This method allows invoking the test script from
 within a number of different directories without having to edit a hard coded 
 use lib or push(@INC,".") kind of statement within the script. 
 
 After a successful test; if you are a system administrator, or have root
 priveleges, or are modifying your own copy of perl; then copy it to the 
 perl5/Tk directory. Depending on how the module was written it should
 be possible to use it either with the use Tk; statement itself or with an
 explicit use Tk::Foo; (for module perl5/Tk/Foo.pm). 
 
 Extensions (Overgrown Modules)
 ------------------------------
 
 These may come as a multi-file kit (tape archive usually) and may require a
 C compiler for part of the installation (Tk-b# itself falls into this category).
 You know you have an Overgrown Module (Extension) when there is one
 or more files with an .xs extension (perl->C meta code) and a 
 Makefile.PL (perl->make meta code). One invokes the perl 
 MakeMaker on the file called Makefile.PL in order to create a 
 Makefile via: 
 
     perl Makefile.PL
 
 You may now run make on the resultant Makefile - but the details of this
 process are module dependent and should be documented in a README or
 an INSTALL file. 
 
 ______________________________________________________________________
 
 
 
 14. How do I write new modules? 
 
 You might want to start by poking around your Tk-b# distribution directory.
 Is there something there that already does what you want? Is there
 something that is reasonably close - but only requires minor modification? 
 
 Next go through the various perl documents - including the FAQ as well as
 the various relevant man pages: perlmod(1), perlobj(1), 
 perlbot(1), (and please don't forget: perlpod(1)!) 
 
 Post your idea to comp.lang.perl.tk and discuss it with others - there might
 very well be someone working on an approach already. A clear explanation
 of all the stuff that gets put into a module was posted to the mailing list and
 can be found in the archive at: 
 
     http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.10/0012.html
 
 Also, be sure to check out a recent version of the official Module List that
 Tim Bunce <Tim.Bunce@ig.co.uk> maintains and posts to 
 comp.lang.perl.announce periodically. The list is also available at any CPAN
 ftp site as well as: 
 
     ftp://franz.ww.tu-berlin.de/pub/modules/00modlist.long.html <- html!
     ftp://rtfm.mit.edu/pub/usenet/news.answers/perl-faq/module-list
     ftp://ftp.demon.co.uk/pub/perl/db/mod/module-list.txt
     ftp://ftp.wpi.edu/perl5/Modules/module_list.txt
 
 Finally ready to ship? Small (perl/Tk) modules have been posted directly to 
 comp.lang.perl.tk. Big modules may require ftp distribution (see upload info
 at one of the CPAN sites) then make your announcement to 
 comp.lang.perl.tk and possibly to comp.lang.perl.announce. 
 
 ______________________________________________________________________
 
 
 
 15. Composite Widgets. 
 
 Composite widgets combine the functions of two or more widget primitives
 into something that is not quite a stand alone program but is something that
 may prove very useful for inclusion in your own scripts. A variety of
 composite widgets have been written and many are still being worked on.
 Many come bundled with your Tk-b# distribution, and some are simply
 posted to comp.lang.perl.tk. It is quite common to have composite widgets
 written in perl modules - usually in terms of the Tk widget primitives.
 Graphical examples of some of the composites discussed here can be seen by
 GUI browsers at: 
 
     http://w4.lns.cornell.edu/~pvhp/ptk/ptkIMG.html
 
 ______________________________________________________________________
 
 
 
 15.1. How do I get a Dialog box? 
 
 For things like a simple "are you sure?" dialog box you might want to take a
 look at perl5/Tk/Dialog.pm. This module may be invoked with 
 require Tk::Dialog; etc. - there are much more extensive directions
 inside the comment fields at the top of the Dialog.pm file itself. The
 module has a lot of options and has a tutorial driver script in 
 perl5/Tk/demos/dialog. Dialog.pm is also used by the 
 perl5/Tk/demos/widget demo. In particular look at 
 perl5/Tk/demos/widget_lib/dialog1.pl and dialog2.pl
 for examples of how one makes use of Tk::Dialog. A snippet of a script that
 uses this module could look like: 
 
     require Tk::Dialog;
 
     my $mw = MainWindow->new;
     my $D = $mw->Dialog(
                  -title => 'Are you sure?',
                  -text  => "You have requested rm \*\nAre you sure?",
                  -default_button => 'No',
                  -buttons        => ['No','yes']
                        );
     my $choice = $D->Show;  # use Show for Tk-b9.01
 # if using Tk-b8:    my $choice = $D->show;
 
     print " you chose $choice \n";
 
 A question concerning configuration of the Subwidgets on the Dialogs came
 up recently: 
 
 <Greg_Cockerham@avanticorp.com> wrote:
 ! I want to reconfigure the colors of the Dialog and
 ! ErrorDialog buttons.  How do I do this?
 ! Thanks in advance.
 
    $dialog_widget->configure(-background => 'purple'); 
 
  Since these two widgets are composites you manage them like any 'ol
  widget. If the default delegate subwidget(s) aren't to your liking you can
  always get to individual component widgets of the composite via the 
  ->Subwidget() method. 
 
  I see these subwidgets: 
 
 Dialog
    'message' is the label subwidget with the dialog text, and 'bitmap' is
    the label subwidget showing the dialog bitmap
 ErrorDialog
    'error_dialog' is Dialog subwidget, 'text' is text subwidget
 
  You can even do things like this: 
 
   $error_dialog->Subwidget('error_dialog')->Subwidget('bitmap')->configure(..);
 
  to "get to" the label widget of the dialog component of the error_dialog
  widget..... 
 
  Be sure to also check out the "dialog" demo. 
 
 ______________________________________________________________________
 
 
 
 15.2. Is there a file selector? 
 
 Yes, there may be several eventually... 
 
 One distributed with the Tk-b# code itself is called FileSelect.pm and was
 written by Frederick L. Wagner - (based on an original by Klaus
 Lichtenwalder). 
 
 Another module called SelFile.pm was adapted by Alan Louis Scheinine
 from Wagner's FileSelect.pm. It is available from: 
 
     http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.11/0122.html
 or
     http://w4.lns.cornell.edu/~pvhp/ptk/etc/SelFile.pm
 
 A module called FileSave.pm allows one to type in a new (non-existant)
 filename for "Save as..." type operations. It was posted by Mark Elston on 12
 Oct 1995 to the mailing list and is available from: 
 
     http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.10/0093.html
 or
     http://w4.lns.cornell.edu/~pvhp/ptk/etc/FileSave.pm
 
 A slightly different behaviour is to be had with Brent B. Powers' 
 FileDialog.pm that was posted to the mailing list on 12 Jan 1996 and
 available from: 
 
     http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.12/0201.html
 or
     http://w4.lns.cornell.edu/~pvhp/ptk/etc/FileDialog.pm
 
 Harry Bochner chimed in with SaveAs.pm. It is available from: 
 
     http://w4.lns.cornell.edu/~pvhp/ptk/etc/SaveAs.pm
 
 In general, if there is a feature that you want missing from one of these, or
 some behaviour that you would like to see modified then by all means cp the
 source code to your area and start hacking ;-) 
 
 ______________________________________________________________________
 
 
 
 15.3. Is there a color editor? 
 
 There is. Please see 
 
     perldoc ColorEditor.pm
 
 or run the perl5/Tk/demos/color_editor demo script for more
 information. 
 
 ______________________________________________________________________
 
 
 
 15.4. Is there a round Scale? 
 
 It is not quite a "round Scale" but Roy Johnson has written "Dial.pm" for
 round dial (or speedometer) -like settable widgets. It is available from: 
 
     http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.08/0431.html
 or
     http://w4.lns.cornell.edu/~pvhp/ptk/etc/Dial.pm
 
 As well as from the /Contrib/ sub-directory of recent releases of perl/Tk
 build directories (Tk-b9.01/Contrib/ or higher). 
 
 ______________________________________________________________________
 
 
 
 15.5. Is there something equivalent to tkerror? 
 
 There is. Please see the Tk/ErrorDialog.pm module for further
 information. 
 
 ______________________________________________________________________
 
 
 
 15.6. Are there Tables? 
 
 There are least two: 
 
 Nick's Table
 ------------
 
 Nick Ing-Simmons has distributed his own Table widget package with
 Tk-b9.01 (and higher). It is used through a use TK::Table; and 
 $top->Table(); calls. A rather detailed demo of this widget/geometry
 manager's capabilities can be found in the table_demo script (in your 
 Tk-b9.01/ build directory). There is also pod in the 
 perl5/Tk/Table.pm file. You may also browse the perl Tk::Table man
 page on the web at 
 
     http://w4.lns.cornell.edu/~pvhp/ptk/etc/Table.pm.html
 
 Guy Decoux's BLT_Table
 ----------------------
 
 Guy Decoux <decoux@moulon.inra.fr> has ported the popular BLT_Table
 Tcl/Tk tabular geometry manager to perl/Tk. It was known to work with
 Tk-b8. You may obtain the latest version of it either from 
 
     ftp://moulon.inra.fr/pub/pTk/
 
 or from a CPAN site in the authors/id/GUYDX/ directory. You may
 also browse the perl BLT_Table man page on the web at 
 
     http://w4.lns.cornell.edu/~pvhp/ptk/etc/Table.html
 
 ______________________________________________________________________
 
 
 
 16. Programming/development tools. 
 
 There are a number of tools and methods to help you with your perl/Tk
 scripting and development. It is worthwhile to note here that the -w switch
 is recommended as is the use strict; statement near the top of your
 script/program. If it dies and you still cannot decrypt the error message that
 these generate take a look though man perldiag(1). 
 
 ______________________________________________________________________
 
 
 
 16.1 Is there a Tcl/Tk to perl/Tk translator? 
 
 Nick Ing-Simmons has written a (rather lengthy) tcl2perl script. It is
 being distributed with the perl/Tk code as of Tk-b9.01. Please handle
 carefully! (translation: do not expect it to translate arbitrary tcl code
 accurately nor even into the most efficient perl/Tk equivalent. Do go over
 the converted script with care - and do not forget -w and use strict;.)
 Thanks Nick :-) 
 
 ______________________________________________________________________
 
 
 
 16.2 Is there something equivalent to wish in perl/Tk? 
 
 The answer is yes. 
 
 The idea of wish is that you read from <STDIN> and evaluate each
 statement. The standard way to do this in perl/Tk is to use the tkpsh script
 that comes in your Tk-b#/ distribution. Another elegant way to get wish
 like behavior in perl/Tk is to use rmt which you can find in 
 perl5/Tk/demos in your Tk-b# distribution. When you run rmt you
 already have Tk.pm set up for you so you can start typing things like $mmm
 = new MainWindow; etc. at the rmt: prompt. (This use belies the
 power of rmt which is derived from Ousterhout's Tcl/Tk version of rmt
 [see section 27.2 of his book]. rmt is capable of "inserting Tk code" into
 simultaneously running Tk applications.) 
 
 A cruder way to get wish-like behaviour with perl/Tk is to run a "perl
 shell" and type in your usual commands, including use Tk; etc. There is a
 script distributed with perl called perlsh which is written quite simply as: 
 
     #!/usr/bin/perl
      $/ = '';        # set paragraph mode
      $SHlinesep = "\n";
      while ($SHcmd = <>) {
          $/ = $SHlinesep;
          eval $SHcmd; print $@ || "\n";
          $SHlinesep = $/; $/ = ''; 
      }
 
 You can use this during code development to test out little snippets of code.
 It helps to be an accurate typist and the use strict; is optional here :-) 
 
 Hiroaki Kobayasi has a more sophisticated wish like perl/Tk "shell" that is
 called EVA. It is available from: 
 
     ftp://ftp.sowa.is.uec.ac.jp/pub/Lang/perl5/Tk/eva-*.tar.gz
 
 ______________________________________________________________________
 
 
 
 16.3. Is there a debugger specifically for perl/Tk? 
 
 Not for the latest version - but the -w switch and use strict; are
 always helpful with debugging as they provide informative error messages.
 Gurusamy Sarathy <gsar@engin.umich.edu> has built a PERL5DB file
 called Tkperldb (which despite the name is for pTk not Tk/perl). One must
 install an early de-bugger then apply a patch to bring the debugger up to
 date. The early debugger kit is available from: 
 
     ftp://ftp.perl.com/pub/perl/ext/TK/Tkperldb-a1.tar.gz
 
 And Gurusamy Sarathy notes that the patch to bring the debugger up to date
 is available at: 
 
  You need a post 5.001m perl that has support for debugging closures. 
  Or you can simply apply:
 
    http://www-personal.umich.edu/~gsar/perl5.001m-bugs.patch
 
  to 5.001m. (5.002beta includes all the fixes in the above patch).
 
 Note that a perl debugger may be invoked within your script with a line like: 
 
     $ENV{'PERL5DB'} = 'BEGIN { require Tkperldb }';
 
 See man perldebug(1) for more help. 
 
 Keep in mind that you are programming in perl after all. The perl debug line
 mode is available to you through executing the following from your shell: 
 
     perl -de 0
 
 Whereupon you must enter all the lines of a script including use Tk;.
 (Fancier file reads & evals are possible - but if you are getting that
 sophisticated why not create your own custom PERL5DB file?) When using 
 perl -dwe 0 beware of the emacs like line editing under this debugger,
 and be forewarned that as soon as you type in the MainLoop; statement
 perl will no longer read from <STDIN>. 
 
 Ilya Zakharevich <ilya@math.ohio-state.edu> points out that very recent
 perldb versions will allow for simultaneous X and STDIN reads. He also
 points out: 
 
 Note that you may use 
 
     sub myLoop {
       if (defined &DB::DB) {
         while (1) {             # MainWindow->Count
           Tk::DoOneEvent(0);
         }
       } else {
         MainLoop;
       }
     }
 
 (and I hope the analogous provision will be in MainLoop in 
  tk-b9 - hi, Nick ;-)
 
 ______________________________________________________________________
 
 
 
 16.4. Is there a GUI builder in perl/Tk? 
 
 Work has recently (January 1996) started on porting a Tcl/Tk GUI builder
 known as SpecTcl for use with perl/Tk. 
 
 Somewhat more removed there is also SWIG. 
 
 ______________________________________________________________________
 
 
 
 17. Processes & Inter-Process Communication under Perl/Tk. 
 
 Inter-Process Communication (IPC) is the subject of spawning and
 controlling other programs or "processes" from within perl (sometimes
 using sockets to do so). The subject is briefly discussed in the perlipc(1)
 man page, and was addressed towards the end of Chapter 6 of The Camel.
 The subject is also discussed in the perl FAQ and at Tom Christiansen's ftp
 site (in the various perlipc* files) at: 
 
     ftp://ftp.perl.com/perl/info/everything_to_know/    199.45.129.30
 
 as well as the web site at: 
 
     http://www.perl.com/perl/everything_to_know/ipc/index.html
 
 In addition to the usual perl IPC routines Tk allows (at least) three more
 special functions: fileevent (for handling I/O events), send (for
 inter-widget communication), and after (for time control like a sleep
 expressly for widgets). 
 
 ______________________________________________________________________
 
 
 
 17.1. How does one get Perl/Tk to act on events that are not coming from X?
 
 On 22 Nov 1995 (Yaniv Bargury) bargury@milcse.cig.mot.com wrote: 
 
  I need to write a GUI monitor, that displays the status and controls a
  set of processes running in the background. The idea is to have the
  GUI application start a few child processes, command the children
  through pipes from the GUI to the children, and display the children
  status coming on pipes from the children to the GUI in real time. 
 
  The GUI must not be busy waiting, because the CPU resources are
  limited. This excludes using the Tk_DoWhenIdle as explained in
  the manual. 
 
  The usual way to do this is to for the GUI process to have one 
  select() in its main loop. That select() should wait for X
  events or input from the pipes leading from the children. 
 
  How do you do this? 
 
 To which Nick Ing-Simmons <nik@tiuk.ti.com> replied: 
 
  fileevent - it is the hook into the select() in the mainloop. 
 
 In addition Avi Deitcher <avi@morgan.com> replied with: 
 
  I wrote something similar to effectively do a tail -f on multiple
  hosts, displaying the result on separate text widgets. Do the following: 
 
     parent
      child
      child
      child
      ..
 
  with a one-way pipe from each child to the parent. Set up the
  following: 
 
     $main->fileevent(FILEHANDLE,status,subroutine);
 
  for each pipe that you have. This will cause pTk to monitor the 
  FILEHANDLE and call 'subroutine' when an event happens on
  that handle. In this case: FILEHANDLE = pipename status =
  'readable' or 'writable' or 'exception' and 
  subroutine = any subroutine that you want. 
 
 ______________________________________________________________________
 
 
 
 17.2. Is there a send and do I need xauth? 
 
 There is a Tk::send, but to use it own must write one's own version of 
 Tk::receive. An example of this may be found in the rmt program
 distributed with Tk-b#. 
 
 The Tk::send <-> Tk::receive process will work under xhost +
 authority. The security this affords comes from the fact that anyone who
 would want to exploit it would have to know how to write a Tk::receive
 custom tailored to your application (in addition to all the other protocol
 hacking). 
 
 Please note that while you may not need xauth authorization it is
 nevertheless always a good idea. 
 
 ______________________________________________________________________
 
 
 
 17.3. How can I do animations using after? 
 
 There is a "toggling button" demo script supplied with Tk called 
 after_demo that makes effective use of after(). 
 
 Terry Greenlaw <terry@encompass.is.net> of Encompass Technologies
 posted a character cell animator for the really bored. Here it is in a slightly
 modified form that allows string input from the command line (note too the
 recursive call that doesn't sop up system memory): 
 
 #!/usr/bin/perl
 
 =head1 NAME
 
 From: z50816@mip.lasc.lockheed.com "Terry Greenlaw"  Thu Feb 1 12:02:24 EST 1996
 To: ptk@guest.WPI.EDU
 Subj: A code sample for the REALLY bored
 
 For everyone with a case of Browser envy after using Microsoft's Internet
 Explorer, here's a perl/tk script only slightly more useful than a script
 to do <BLINK>. Don't know why I wrote it. Don't know why you'd run it.
 Maybe if you were writing a ticker tape application. Or had a weird thing
 for Times Square. Anyway....
 
 tog
 Terry Greenlaw (on-site @ Lockheed Martin)      Encompass Technologies
 z50816@mip.lasc.lockheed.com                    terry@encompass.is.net
 
 ##################################################################
 
 =cut
 
     #!/usr/bin/perl
     
     #use strict;
     use Tk;
     
     $message=join(' ',@ARGV,''); 
     if (!$message) {
         $message="THIS IS A VERY LONG SCROLLING MESSAGE...      ";
         $topmssg="This is the top of the screen";
         $botmssg="This is the bottom of the screen";
     }
     else {
         $topmssg=$message;
         $botmssg=$message;
     }
     $top = MainWindow->new;
     $l1 = $top->Label(-fg => 'White', -text => $topmssg);
     $l1->pack(-fill => 'both', -expand => 1 );
     $m1 = $top->Label(-fg=>'Red', -bg=>'black',
                       -textvariable => \$message, 
                       -width => 15 
                       );
     $m1->pack();
     $m2 = $top->Label(-wrap=>1, 
                       -fg=>'Green', -bg=>'black',
                       -textvariable => \$message2, 
                       -width=>1, -height=>8 
                       );
     $m2->pack(-anchor=>'w');
     $l2 = $top->Label(-fg => 'White', -text => $botmssg);
     $l2->pack(-fill => 'both', -expand => 1 );
     
     after(100, \&scroll_it);
     
     $top->MainLoop;
     
     sub scroll_it {
         $message =~ /(.)(.*)/;
         $message="$2$1";
         ($message2 = $message) =~ s/ /  /g;
         after(100, \&scroll_it);
     }
     __END__
 
 ______________________________________________________________________
 
 
 
 17.4. How do you fork on System V (HP)? 
 
 Kraegeloh Martin <mkr@dm-server.cv.com> originally asked: 
 
 
 ! Subj: signal handling difference on HP vs. SUN
 !
 ! the following code will fork an xterm with vi in it, and it
 ! will refuse to do so while the first xterm is still running.
 ! works fine on my sun.
 ! On HP however, the second time an xterm is started, NO handler
 ! is called when the child dies.
 !
 ! the code:
 ! ===================== 8< ===============================
 ! $SIG{CHLD}=\&w;
 !
 ! sub w{
 !    $pid=wait;
 !    print STDERR "died: $pid\n";
 !    if ( $have == $pid ) { $have = 0; }
 ! }
 
 To which a part of Nick Ing-Simmons' response was: 
 
  I suspect HPUX is SysV-ish not BSD or POSIX. So every time a signal
  fires, it removes the handler - you need to reset it in the handler: 
 
     sub w{
         $SIG{CHLD}=\&w;
         $pid=wait;
         print STDERR "died: $pid\n";
         if ( $have == $pid ) { $have = 0; }
      }
  
 
  Whether you reset it before/after the wait may be very important ... 
 
 Then Bjarne Steinsbo <bjarne@hsr.no> followed up with: 
 
  That's not the whole story... Another problem is that SIGCLD
  interrupts the read system call on SysV-ish (I like that word! :-)
  systems. This means that you have to test why "" fails, and act
  accodingly. A program that works on both Sun and HP is: 
 
     $SIG{CHLD}=\&w;
     while(1){
        $_ = ;
        $! = 0, next if $! =~ /Interrupted/;
        last if $! or !defined $_;
        if($have){
             print STDERR "child still alive\n";
        }
        else{
             if(($pid=fork()) != 0){
                $have=$pid;
                print STDERR "forked $pid\n";
             }
             else {
                exec("xterm -e vi") 
             }
        }
     }
 
     sub w{
        $pid=wait;
        print STDERR "died: $pid\n";
        if ( $have == $pid ) { $have = 0; }
        $SIG{CHLD}=\&w;
     }
 
