[26021] in Perl-Users-Digest
Perl-Users Digest, Issue: 8236 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Jul 8 18:05:23 2005
Date: Fri, 8 Jul 2005 15:05:06 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Fri, 8 Jul 2005 Volume: 10 Number: 8236
Today's topics:
Accessing lexical vars in other packages <ra.jones@dpw.clara.co.invalid>
Re: Accessing lexical vars in other packages (Anno Siegel)
Problems understanding and implementing process managem <amheiserbush@yahoo.com.au>
Re: Problems understanding and implementing process man <notvalid@email.com>
Re: Problems understanding and implementing process man <amheiserbush@yahoo.com.au>
Re: Problems understanding and implementing process man <1usa@llenroc.ude.invalid>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Fri, 8 Jul 2005 14:31:54 +0100
From: RA Jones <ra.jones@dpw.clara.co.invalid>
Subject: Accessing lexical vars in other packages
Message-Id: <iOhNJgAKBozCFwP+@na326073.eclipse.co.uk>
This is a question about packages and lexical variables.
I am using a very useful $SIG{__DIE__} handler module (CGI::HTMLError),
and want to extend it's functionality by adding an e-mail alert
function. Clearly I don't want to have to re-write the module to do
this, so in my apps I 'use' my extended mod Local::HTMLError, which
itself uses CGI::HTMLError as base. All works fine, except for the fact
that the CGI errors are captured within lexical variables inside a C::H
sub. I assume I cannot access these as they are not present in the
symtable (they are declared with 'my'), and indeed
$CGI::HTMLError::sub_routine::variable does not work.
Except that I read that Perl does not necessarily recycle variables if
it detects they are referenced elsewhere. So is there any way I can
achieve what I want here - to retrieve lexical variables from another
package's sub-routines?
--
ra(dot)jones(at)dpw(dot)clara(dot)co(dot)uk
------------------------------
Date: 8 Jul 2005 13:55:01 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Accessing lexical vars in other packages
Message-Id: <dam0jl$p30$1@mamenchi.zrz.TU-Berlin.DE>
RA Jones <ra.jones@dpw.clara.co.invalid> wrote in comp.lang.perl.misc:
> This is a question about packages and lexical variables.
Packages have nothing to do with lexical variables.
> I am using a very useful $SIG{__DIE__} handler module (CGI::HTMLError),
> and want to extend it's functionality by adding an e-mail alert
> function. Clearly I don't want to have to re-write the module to do
> this, so in my apps I 'use' my extended mod Local::HTMLError, which
> itself uses CGI::HTMLError as base. All works fine, except for the fact
> that the CGI errors are captured within lexical variables inside a C::H
> sub. I assume I cannot access these as they are not present in the
> symtable (they are declared with 'my'), and indeed
> $CGI::HTMLError::sub_routine::variable does not work.
>
> Except that I read that Perl does not necessarily recycle variables if
> it detects they are referenced elsewhere. So is there any way I can
> achieve what I want here - to retrieve lexical variables from another
> package's sub-routines?
Again, any talk of packages in this context is a red herring. You'd
have the same problem if the sub that accesses the lexicals were in
"your" package, never mind what that is.
You cannot access lexical variables from outside their scope, unless
code inside the scope allows it. So, unless the code in CGI::HTMLError
provides an accessor routine (in the generic sense, not necessarily a
method) to the variable, you're out of luck.
Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
------------------------------
Date: Fri, 8 Jul 2005 11:24:04 -0400
From: "James Calivar" <amheiserbush@yahoo.com.au>
Subject: Problems understanding and implementing process management
Message-Id: <dam5qk$avs$1@home.itg.ti.com>
Hello,
I'm a pretty new Perl programmer, and am having some difficulty in finding
the correct way to approach process management in an application that I'm
writing. Basically, I've written a Perl/Tk script that pops up a nice GUI
that a user can use to configure some parameters, and then press a Start
button to kick off a separate (already written and tested) Perl script.
This secondary Perl script is something that I want to have run as a
separate process from the GUI script, and it does its own thing in the
background. I want to be able to terminate the secondary script at any time
by pressing a Stop button, with the result that the secondary process is
terminated but the GUI remains up so that the process can be kicked off
again is desired.
I'm running ActiveState Perl 5.8.4 on a Windows XP machine (SP2).
Now, I've been somewhat successful in invoking the secondary script by using
one of a couple of different methods. But I'm not sure which one is really
appropriate for my application. The first thing I did was to just try to
use the system() command - but this waits for the secondary process to
terminate before the GUI proceeds, the net effect being that when I press
the Start button, the GUI essentially hangs up (with the button depressed)
and only recovers after I kill the secondary script with Ctrl-C. (I do not
want to use the exec() function, because that terminates the GUI.) I also
tried using fork(), but every time I invoke it, the script crashes and gives
me the "Windows has encoutered a problem - would you like to file a report?"
error message. So it seems that fork() is out. Finally, I tried using
piped processes (as suggested in Learning Perl, Chapter 14 "Processes as
Filehandles"). That also kicks off my secondary script, and returns control
over the GUI to me, but now I cannot terminate the secondary process. And I
believe it's because, as with the system() call, the close command issued to
the filehandle that I have assigned to the secondary process also has to
wait for that process to terminate, which it won't - so again, I'm stuck.
Can anyone here kindly nudge me in the right direction? Am I on the right
track, or do I need to switch methods altogether? I can provide code
examples if need be.
Thanks
James
------------------------------
Date: Fri, 08 Jul 2005 17:42:37 GMT
From: Ala Qumsieh <notvalid@email.com>
Subject: Re: Problems understanding and implementing process management
Message-Id: <hWyze.3188$6%2.94@newssvr21.news.prodigy.com>
James Calivar wrote:
> Hello,
>
> I'm a pretty new Perl programmer, and am having some difficulty in finding
> the correct way to approach process management in an application that I'm
> writing. Basically, I've written a Perl/Tk script that pops up a nice GUI
What GUI library are you using? If Tk, then perhaps you can use the
Tk::fileevent method, as described in its pods.
> that a user can use to configure some parameters, and then press a Start
> button to kick off a separate (already written and tested) Perl script.
What does the second script do? Is there any data that needs to be
passed back to the GUI?
> I'm running ActiveState Perl 5.8.4 on a Windows XP machine (SP2).
>
> Now, I've been somewhat successful in invoking the secondary script by using
> one of a couple of different methods. But I'm not sure which one is really
> appropriate for my application. The first thing I did was to just try to
> use the system() command - but this waits for the secondary process to
> terminate before the GUI proceeds, the net effect being that when I press
> the Start button, the GUI essentially hangs up (with the button depressed)
> and only recovers after I kill the secondary script with Ctrl-C. (I do not
I believe on Windows, you can use the command "start prog.pl" to run
your second Perl script in the background.
> want to use the exec() function, because that terminates the GUI.) I also
> tried using fork(), but every time I invoke it, the script crashes and gives
> me the "Windows has encoutered a problem - would you like to file a report?"
> error message. So it seems that fork() is out. Finally, I tried using
The perlfork pods claim:
On some platforms such as Windows where the fork() system call is not
available, Perl can be built to emulate fork() at the interpreter
level.
Which Win32 Perl distribution are you using?
> piped processes (as suggested in Learning Perl, Chapter 14 "Processes as
> Filehandles"). That also kicks off my secondary script, and returns control
> over the GUI to me, but now I cannot terminate the secondary process. And I
Can you show this code?
If you use open() to create your pipe, then the return value of your
open is the pid of your child process. You can use that to kill() it.
--Ala
------------------------------
Date: Fri, 8 Jul 2005 15:36:31 -0400
From: "James Calivar" <amheiserbush@yahoo.com.au>
Subject: Re: Problems understanding and implementing process management
Message-Id: <damkjv$k5k$1@home.itg.ti.com>
"Ala Qumsieh" <notvalid@email.com> wrote in message
news:hWyze.3188$6%2.94@newssvr21.news.prodigy.com...
> James Calivar wrote:
>
> > Hello,
> >
> > I'm a pretty new Perl programmer, and am having some difficulty in
finding
> > the correct way to approach process management in an application that
I'm
> > writing. Basically, I've written a Perl/Tk script that pops up a nice
GUI
>
> What GUI library are you using? If Tk, then perhaps you can use the
> Tk::fileevent method, as described in its pods.
>
Tk is what I'm using. The GUI part is all done; it's just this last one
command that kicks off another process that is driving me nuts.
> > that a user can use to configure some parameters, and then press a Start
> > button to kick off a separate (already written and tested) Perl script.
>
> What does the second script do? Is there any data that needs to be
> passed back to the GUI?
>
Well, in the *real* application, the secondary script does a lot of stuff.
But as far as the calling GUI code is concerned, it does nothing - it just
goes out and stays out and needs to be killed off at some point via some
method yet to be determined. So, for the purposes of testing, I've just
replaced it with a script that prints out the "spinning text wheel" either
for 30 seconds or so, or (optionally if I uncomment out the commented
lines), forever. This kind of emulates a long-lived process. And since it
won't ever return/terminate (at least not immediately), I can't use
system(), exec() or the "piped process" method since all of those methods
must wait for the secondary application's termination before they can
proceed.
> > I'm running ActiveState Perl 5.8.4 on a Windows XP machine (SP2).
> >
> > Now, I've been somewhat successful in invoking the secondary script by
using
> > one of a couple of different methods. But I'm not sure which one is
really
> > appropriate for my application. The first thing I did was to just try
to
> > use the system() command - but this waits for the secondary process to
> > terminate before the GUI proceeds, the net effect being that when I
press
> > the Start button, the GUI essentially hangs up (with the button
depressed)
> > and only recovers after I kill the secondary script with Ctrl-C. (I do
not
>
> I believe on Windows, you can use the command "start prog.pl" to run
> your second Perl script in the background.
>
Do you mean system()?
> > want to use the exec() function, because that terminates the GUI.) I
also
> > tried using fork(), but every time I invoke it, the script crashes and
gives
> > me the "Windows has encoutered a problem - would you like to file a
report?"
> > error message. So it seems that fork() is out. Finally, I tried using
>
> The perlfork pods claim:
>
> On some platforms such as Windows where the fork() system call is not
> available, Perl can be built to emulate fork() at the interpreter
> level.
>
> Which Win32 Perl distribution are you using?
Win XP Pro, running Perl ActiveState Perl 5.8.7 (Build 813) - I just
upgraded.
>
> > piped processes (as suggested in Learning Perl, Chapter 14 "Processes as
> > Filehandles"). That also kicks off my secondary script, and returns
control
> > over the GUI to me, but now I cannot terminate the secondary process.
And I
>
> Can you show this code?
>
> If you use open() to create your pipe, then the return value of your
> open is the pid of your child process. You can use that to kill() it.
>
> --Ala
>
Here is the code, stripped down somewhat so that noone has to look at all
the meaningless parts. There are two files: daemon_gui.pl, and test2.pl.
daemon_gui.pl is the Tk-enabled "master" code that sets up the GUI
environment, and kicks off the secondary file (test2.pl) when the "Start
Daemon" button is pressed. As you can see, test2.pl is simply a stub that
"spins its wheels" in the command-line window that daemon_gui.pl is invoked
from (I always like to start the script from a CLI when developing, because
then I can see messages that I would lose if I just double-clicked the file
in Windows Explorer).
So basically, if you invoke daemon_gui.pl (from CLI), the click the Start
button, you'll see the "spinning text" in the CLI. Now what I *want* to
happen is when I press Stop, the secondary script is terminated immediately.
But what is *actually* happening is that the Stop button's actions do not go
into effect until the secondary script has stopped processing.
Some rudimentary debug code in daemon_gui.pl (lines 118 and 129) show me
that the process ID that I am attempting to kill is the same one created
when I invoke the secondary script. Do I need to embed a signal handler
routine in the secondary script or something?
Any ideas, comments, questions, etc?
Thanks for your help
James Calivar
daemon_gui.txt:
==========
#---------------------------#
# initial environment setup
#---------------------------#
use Tk;
use Tk::widgets qw/Dialog/;
use Tk::Balloon;
use subs qw/buildMenuBar finishUp startDaemon stopDaemon/;
use vars qw/$MW $VERSION $pid/;
use strict;
############################################################################
##############
# BEGIN Variable Declarations
#---------------------------------------------------------------------------
-------------#
# version number for internal tracking
$VERSION = '0.97';
#-----------------------------------------------#
# hash used to hold values for all config params
#-----------------------------------------------#
my %config = (
"dbpwd" => undef
);
my @hash_keys = keys %config;
my @hash_vals = values %config;
#-----------------------------------------------#
# hash used to hold popup balloon text msgs
#-----------------------------------------------#
my %configMessages = (
"dbpwd" => "Password for database user account (hidden when typed on
screen)"
);
#-----------------------------------------------#
# hash used to hold handles to Entry widgets
#-----------------------------------------------#
my %configEntry;
#---------------------------------------------------------------------------
-------------#
# END Declarations
############################################################################
##############
############################################################################
##############
# BEGIN Main window geometry setup
#---------------------------------------------------------------------------
-------------#
#-------------------------------------#
# define the main window's attributes
#-------------------------------------#
$MW = MainWindow->new;
$MW->geometry("520x540+0+0");
$MW->title("Daemon GUI $VERSION");
my $menubar = buildMenuBar;
#-------------------------------------------------#
# set up conf.ini variable labels and entry boxes
#-------------------------------------------------#
my $startButton = $MW->Button (-text => "Start Daemon\n", -anchor => 'n',
-foreground => 'black',
-background => 'SeaGreen3',
-activeforeground => 'black',
-activebackground => 'green',
-command => sub {startDaemon})
->place(-anchor=>'nw', -x=>325, -y=>467);
my $stopButton = $MW->Button (-text => "Stop Daemon\n", -anchor => 'n',
-foreground => 'black',
-background => 'salmon1',
-activeforeground => 'white',
-activebackground => 'red',
-command => sub {stopDaemon})
->place(-anchor=>'nw', -x=>425, -y=>467);
my $idx = 0;
foreach my $key (@hash_keys)
{
# draw a label widget that annotates the variable being entered
my $label = $MW->Label(-text => "$key:\n")->place(-anchor =>
'nw', -x=>0, -y=>(10 + $idx*25));
# draw a popover balloon that describes the label widget
my $balloon = $MW->Balloon(-state => 'balloon');
$balloon->attach($label, -balloonmsg => $configMessages{$key}, -initwait
=> 10,
-balloonposition => 'mouse', -state => 'balloon');
# draw an entry widget that accepts input for the variable being entered
# special case for password, which should show up as asteriks
if ($key eq 'dbpwd')
{
$configEntry{$key} = $MW->Entry(-textvariable => \$config{$key}, -show
=> '*')
->place(-anchor=>'nw', -x=>150, -y=>(1
0 + $idx*25));
}
else
{
$configEntry{$key} = $MW->Entry(-textvariable => \$config{$key})
->place(-anchor=>'nw', -x=>150, -y=>(1
0 + $idx*25));
}
$idx++;
}
#---------------------------------------------------------------------------
-------------#
# END Main window geometry setup
############################################################################
##############
############################################################################
##############
# BEGIN Subroutine Definitions
#---------------------------------------------------------------------------
-------------#
#--------------------------------------#
# Start the daemon if all config values
# have been filled out; look for config
# file first, then check entries in GUI
#--------------------------------------#
sub startDaemon {
# kick off daemon
$pid = open DAEMON, "|perl test2.pl";
print ("Process ID created is $pid\n");
} # end startDaemon()
#--------------------------------------#
# commit the changes to the conf file
# (this will be a lot cleaner with the
# config hash)
#--------------------------------------#
sub stopDaemon {
print ("Process ID to kill is $pid\n");
kill 2, $pid or die "Cannot signal $pid with SIGINT: $!";
close DAEMON;
} # end stopDaemon()
#---------------------------------#
# build up the GUI's menu structure
#---------------------------------#
sub buildMenuBar {
# Create the menubar, and File and Quit menubuttons. Note
# that the cascade's menu widget is automatically created.
my $menubar = $MW->Menu;
$MW->configure(-menu => $menubar);
my $file = $menubar->cascade(-label => '~File', -tearoff => 0);
my $help = $menubar->cascade(-label => '~Help', -tearoff => 0);
# Create the menuitems for each menu. First, the File menu item.
$file->command(-label => "Open...", -command => \&open);
$file->separator;
$file->command(-label => "Save...", -command => \&save);
$file->separator;
$file->command(-label => "Quit", -command => \&finishUp);
# Help menuitems (Version and About)
$help->command(-label => 'Version');
$help->separator;
$help->command(-label => 'About');
my $ver_dialog = $MW->Dialog(-title => 'Daemon GUI Utility',
-font=> "Arial 10 normal",
-text=> "Daemon GUI Utility Version
$VERSION",
-buttons => ['OK'],
-bitmap => 'info');
my $about_dialog = $MW->Dialog(-title => 'About Daemon GUI Utility',
-font=> "Arial 10 normal",
-text=> "Daemon GUI Utility Version
$VERSION\n\n\Copywright 2005\n\nDaemon GUI Enterprises, Inc. (LLC)\n\nUse
without explicit permission is strictly prohibited. Violators will be
prosecuted to the fullest extent of the law.",
-buttons => ['OK']);
my $menu = $help->cget('-menu');
$menu->entryconfigure('Version', -command => [$ver_dialog => 'Show']);
$menu->entryconfigure('About', -command => [$about_dialog => 'Show']);
# return the menubar
$menubar;
} # end buildMenuBar()
#--------------------------------------------------#
# retrieve GUI configuration from earlier sessions
#--------------------------------------------------#
sub open {
} # end open()
#--------------------------------------#
# save GUI configuration for later use
#--------------------------------------#
sub save {
} # end save()
#-------------------------------#
# Clean up and exit the program
#-------------------------------#
sub finishUp {
exit;
} # end finishUp()
#---------------------------------------------------------------------------
-------------#
# END Subroutine Definitions
############################################################################
##############
############################################################################
##############
# BEGIN Main Event Processor Loop
#---------------------------------------------------------------------------
-------------#
MainLoop;
#---------------------------------------------------------------------------
-------------#
# END Main Event Processor Loop
############################################################################
##############
test2.pl:
=====
use strict;
my $i = 0;
# while (1) {
for ($i = 0; $i <= 2000000; $i++) {
if (($i % 4) == 0) {
print "|\r";
} elsif (($i % 4) == 1) {
print "/\r";
} elsif (($i % 4) == 2) {
print "-\r";
} else {
# $i = 0;
print "\\\r";
}
# $i++;
}
------------------------------
Date: Fri, 08 Jul 2005 21:23:36 GMT
From: "A. Sinan Unur" <1usa@llenroc.ude.invalid>
Subject: Re: Problems understanding and implementing process management
Message-Id: <Xns968DB0EFC11asu1cornelledu@127.0.0.1>
"James Calivar" <amheiserbush@yahoo.com.au> wrote in
news:damkjv$k5k$1@home.itg.ti.com:
> Here is the code,
Please make an effort not to use extra comment lines that wrap when
pasted, and format you source code nicely. Consider running it through a
code beautifier even if you are not willing to follow the recommendations
given in perldoc perlstyle.
I have been trying to run your code for the last 15 minutes, but it won't
due to various problems.
Sinan
--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)
comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc. For subscription or unsubscription requests, send
#the single line:
#
# subscribe perl-users
#or:
# unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V10 Issue 8236
***************************************