[23750] in Perl-Users-Digest
Perl-Users Digest, Issue: 5954 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Dec 18 14:15:44 2003
Date: Thu, 18 Dec 2003 11:15:16 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Thu, 18 Dec 2003 Volume: 10 Number: 5954
Today's topics:
Re: strange results using m//g in while loop... <not_a_real@adress.getting.too.much.spam.org>
Re: strange results using m//g in while loop... <not_a_real@adress.getting.too.much.spam.org>
Re: strange results using m//g in while loop... <uri@stemsystems.com>
Re: strange results using m//g in while loop... <nobull@mail.com>
Re: strange results using m//g in while loop... <uri@stemsystems.com>
Re: strange results using m//g in while loop... <nobull@mail.com>
Re: strange results using m//g in while loop... (Anno Siegel)
Re: strange results using m//g in while loop... (Anno Siegel)
Re: strange results using m//g in while loop... <not_a_real@adress.getting.too.much.spam.org>
Re: strange results using m//g in while loop... <uri@stemsystems.com>
Re: strange results using m//g in while loop... <nobull@mail.com>
Re: strange results using m//g in while loop... <nobull@mail.com>
Re: strange results using m//g in while loop... <tcurrey@no.no.i.said.no>
Re: strange results using m//g in while loop... <uri@stemsystems.com>
Re: When closing DOS window... <jwillmore@remove.adelphia.net>
Re: When closing DOS window... <ThomasKrarz@REMOVEwebCAPS.de>
Re: When closing DOS window... (Malcolm Dew-Jones)
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Thu, 18 Dec 2003 08:45:37 -0800
From: "Damian" <not_a_real@adress.getting.too.much.spam.org>
Subject: Re: strange results using m//g in while loop...
Message-Id: <brslh6$749vv$1@ID-196529.news.uni-berlin.de>
Anno Siegel wrote:
> Damian <not_a_real@adress.getting.too.much.spam.org> wrote in
> comp.lang.perl.misc:
>> The following works as expected (examples):
>>
>>
>> my $re_d = qr|(\d),(\d),(\d)|;
>> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
>>
>> while ($s =~ m|$re_d|g) {
>> print "[$1 $2 $3]\n";
>> }
>>
>> And prints:
>>
>> [1 2 3]
>> [4 5 6]
>> [7 8 9]
>>
>>
>>
>> However, if I try to capture the $1, $2, ... matches ot an array, it
>> turns into na infinate loop:
>
> Yup, that's expected.
>
> There's a whole lot of magic going on with //g in scalar context that
> doesn't happen in list context. In particular, in scalar context,
> each //g matches only once (despite the /g), but sets the position
> (pos())
> of the string to the place past the last match. The next match
> implicitly
> starts matching at pos(), not at the start of the string. That
> mechanism
> steers you safely through the loop when you match in scalar context.
>
> In list context, a global match is just a global match: It starts at
> the beginning and matches everything it can to the end of the string.
> The next match does exactly the same thing, hence the endless loop.
>
>> my $re_d = qr|(\d),(\d),(\d)|;
>> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
>>
>> my @r;
>> while (@r = $s =~ m|$re_d|g) {
>> print "[@r]\n";
>> }
>>
>> And keeps printing:
>>
>> [1 2 3 4 5 6 7 8 9]
>> [1 2 3 4 5 6 7 8 9]
>
> Anno
Thank you.
So is there anyway around this? To be able to capture a variable
(unknown) about of $1, $2, ... matches to an array (without using an
eval) ?
------------------------------
Date: Thu, 18 Dec 2003 08:52:21 -0800
From: "Damian" <not_a_real@adress.getting.too.much.spam.org>
Subject: Re: strange results using m//g in while loop...
Message-Id: <brslto$77puv$1@ID-196529.news.uni-berlin.de>
Anno Siegel wrote:
> Damian <not_a_real@adress.getting.too.much.spam.org> wrote in
> comp.lang.perl.misc:
>> The following works as expected (examples):
>>
>>
>> my $re_d = qr|(\d),(\d),(\d)|;
>> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
>>
>> while ($s =~ m|$re_d|g) {
>> print "[$1 $2 $3]\n";
>> }
And one more question if I may, why does this not work?
while ($s =~ m|$re_d|g) {
my @r = @_; # $_ is emtpy too...
print "[@r]\n";
}
[]
[]
[]
I thought the default loop variable was $_ ? Which why you do something
like
while (<FILE>) { print; }
------------------------------
Date: Thu, 18 Dec 2003 17:20:28 GMT
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: strange results using m//g in while loop...
Message-Id: <x7wu8ucaar.fsf@mail.sysarch.com>
>>>>> "D" == Damian <not_a_real@adress.getting.too.much.spam.org> writes:
> Anno Siegel wrote:
>> Damian <not_a_real@adress.getting.too.much.spam.org> wrote in
>> comp.lang.perl.misc:
>>> The following works as expected (examples):
>>>
>>>
>>> my $re_d = qr|(\d),(\d),(\d)|;
>>> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
>>>
>>> while ($s =~ m|$re_d|g) {
>>> print "[$1 $2 $3]\n";
>>> }
> And one more question if I may, why does this not work?
> while ($s =~ m|$re_d|g) {
> my @r = @_; # $_ is emtpy too...
why are you using @_? it has nothing to do with regexes. where did you
get this false concept?
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
------------------------------
Date: 18 Dec 2003 17:16:12 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: strange results using m//g in while loop...
Message-Id: <u9hdzy11yb.fsf@wcl-l.bham.ac.uk>
"Damian" <not_a_real@adress.getting.too.much.spam.org> writes but
doesn't trim:
[ Please quote only what is relevant ]
> Anno Siegel wrote:
> >
> > There's a whole lot of magic going on with //g in scalar context that
> > doesn't happen in list context.
> >
> > In list context, a global match is just a global match: It starts at
> > the beginning and matches everything it can to the end of the string.
>
> So is there anyway around this? To be able to capture a variable
> (unknown) about of $1, $2, ... matches to an array (without using an
> eval) ?
After a match against some variable $var $1 is the same as
substr($var, $-[1], $+[1] - $-[1])
The number of the last successful capture in the regex is $#- and the
total number of captures in the regex is in $#+.
This is all explained in a rather obscure place in the manuals.
Namely, perlvar for "@-" and "@+".
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: Thu, 18 Dec 2003 17:30:40 GMT
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: strange results using m//g in while loop...
Message-Id: <x7smjic9ts.fsf@mail.sysarch.com>
>>>>> "D" == Damian <not_a_real@adress.getting.too.much.spam.org> writes:
> my $re_d = qr|(\d),(\d),(\d)|;
> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
> my @r;
> while (@r = $s =~ m|$re_d|g) {
> print "[@r]\n";
> }
> And keeps printing:
> [1 2 3 4 5 6 7 8 9]
> Why is ading the array to suck up the results causing the behavior to
> change?
as others have pointed out, a regex in an list context with /g will keep
running it until it fails. sort of like while/g in scalar context but
all at one time.
> And for that matter, how can I capture the $1, $2... in an array like
> this?
you have captured them in the array. you just did it 3 times in each
call to the regex so you got all 9 digits.
so work with this and change your loop to grab 3 values at a time:
my $re_d = qr|(\d),(\d),(\d)|;
my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
# get all the digits at once
my @r = $s =~ m|$re_d|g ;
# loop over them 3 at a time
while (@s = splice( @r, 0, 3 )) {
print "[@s]\n";
}
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
------------------------------
Date: 18 Dec 2003 17:25:39 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: strange results using m//g in while loop...
Message-Id: <u9d6am11ik.fsf@wcl-l.bham.ac.uk>
"Damian" <not_a_real@adress.getting.too.much.spam.org> writes:
> And one more question if I may, why does this not work?
>
> while ($s =~ m|$re_d|g) {
> my @r = @_; # $_ is emtpy too...
> print "[@r]\n";
> }
Because, as MJD would say, "you can't just make shit up and expect the
computer to know what you mean, retardo!"
$_ and @_ and $1,$2,$3 etc are all different variables.
> I thought the default loop variable was $_ ?
It is in "for". ( In "map", it's the only loop variable!).
> Which why you do something like
> while (<FILE>) { print; }
No, this is a different bit of DWIM.
The <handle> operator acts in a special way it notices that it
appears inside the condition of a while.
while (<FILE>) { print; }
Is actually interpreted as if it said:
while ( defined ( $_ = <FILE>) ) { print; }
Note: $_ is not local()ized here - this can lead to some odd effects.
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: 18 Dec 2003 17:51:20 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: strange results using m//g in while loop...
Message-Id: <brspeo$p50$1@mamenchi.zrz.TU-Berlin.DE>
Damian <not_a_real@adress.getting.too.much.spam.org> wrote in comp.lang.perl.misc:
> Anno Siegel wrote:
> > Damian <not_a_real@adress.getting.too.much.spam.org> wrote in
> > comp.lang.perl.misc:
> >> The following works as expected (examples):
> >>
> >>
> >> my $re_d = qr|(\d),(\d),(\d)|;
> >> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
> >>
> >> while ($s =~ m|$re_d|g) {
> >> print "[$1 $2 $3]\n";
> >> }
> >>
> >> And prints:
> >>
> >> [1 2 3]
> >> [4 5 6]
> >> [7 8 9]
> >>
> >>
> >>
> >> However, if I try to capture the $1, $2, ... matches ot an array, it
> >> turns into na infinate loop:
> >
> > Yup, that's expected.
> >
> > There's a whole lot of magic going on with //g in scalar context that
> > doesn't happen in list context. In particular, in scalar context,
> > each //g matches only once (despite the /g), but sets the position
> > (pos())
> > of the string to the place past the last match. The next match
> > implicitly
> > starts matching at pos(), not at the start of the string. That
> > mechanism
> > steers you safely through the loop when you match in scalar context.
> >
> > In list context, a global match is just a global match: It starts at
> > the beginning and matches everything it can to the end of the string.
> > The next match does exactly the same thing, hence the endless loop.
> >
> >> my $re_d = qr|(\d),(\d),(\d)|;
> >> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
> >>
> >> my @r;
> >> while (@r = $s =~ m|$re_d|g) {
> >> print "[@r]\n";
> >> }
> >>
> >> And keeps printing:
> >>
> >> [1 2 3 4 5 6 7 8 9]
> >> [1 2 3 4 5 6 7 8 9]
> >
> > Anno
>
> Thank you.
>
> So is there anyway around this? To be able to capture a variable
> (unknown) about of $1, $2, ... matches to an array (without using an
> eval) ?
You can analyze the @- and @+ arrays after the match. Something like
(untested, may be off by one (or more))
map substr( $str, $-[ $_], $+[ $_] - $-[ $_]), 0 .. $#-;
should list the whole match first, then $1, $2, etc. I'm not sure how
well that works with /g.
Another way is to provide the behavior of /g in scalar context explicitly
while calling it in list context:
while ( my @matches = /\G<something>/ ) {
pos = $+[ 0];
# ...
}
Anno
------------------------------
Date: 18 Dec 2003 18:06:09 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: strange results using m//g in while loop...
Message-Id: <brsqah$p50$2@mamenchi.zrz.TU-Berlin.DE>
Damian <not_a_real@adress.getting.too.much.spam.org> wrote in comp.lang.perl.misc:
> Anno Siegel wrote:
> > Damian <not_a_real@adress.getting.too.much.spam.org> wrote in
> > comp.lang.perl.misc:
> >> The following works as expected (examples):
> >>
> >>
> >> my $re_d = qr|(\d),(\d),(\d)|;
> >> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
> >>
> >> while ($s =~ m|$re_d|g) {
> >> print "[$1 $2 $3]\n";
> >> }
>
> And one more question if I may, why does this not work?
>
> while ($s =~ m|$re_d|g) {
> my @r = @_; # $_ is emtpy too...
> print "[@r]\n";
> }
Well, it doesn't work because it's neither implemented nor documented
that way. It could be so, granted, but it isn't.
>
> I thought the default loop variable was $_ ? Which why you do something
> like
> while (<FILE>) { print; }
Even if this were entirely true (scalar $_ is *the* default variable in
Perl, not only loop variable), it would do nothing to explain the behavior
of the array @_. Though they share the name "_", they are entirely
different variables. That goes for all names and is a fundamental fact
in Perl. The array @_ is important as the variable space in subroutine
calls, but functions and operators don't deposit their results there
(except in one case, which happened by accident).
Anno
------------------------------
Date: Thu, 18 Dec 2003 10:18:30 -0800
From: "Damian" <not_a_real@adress.getting.too.much.spam.org>
Subject: Re: strange results using m//g in while loop...
Message-Id: <brsqut$75s6d$1@ID-196529.news.uni-berlin.de>
Anno Siegel wrote:
> Another way is to provide the behavior of /g in scalar context
> explicitly
> while calling it in list context:
>
> while ( my @matches = /\G<something>/ ) {
> pos = $+[ 0];
> # ...
> }
Thank you Anno, I tried using the above, as it seems to be the solution
I'm looking for, though it never seems to enter the loop:
my $re_d = qr|(\d),(\d),(\d)|;
my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
while (my @r = $s =~ m/\G$re_d/) {
pos($s) = $+[0];
print "[@r]\n";
}
(I tried it with the /g modifier too, though I didn't think it should be
there in this case.)
Is there something missing?
Thanks again.
------------------------------
Date: Thu, 18 Dec 2003 18:28:17 GMT
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: strange results using m//g in while loop...
Message-Id: <x7ekv2c75q.fsf@mail.sysarch.com>
>>>>> "D" == Damian <not_a_real@adress.getting.too.much.spam.org> writes:
> Thank you Anno, I tried using the above, as it seems to be the solution
> I'm looking for, though it never seems to enter the loop:
> while (my @r = $s =~ m/\G$re_d/) {
from perlre:
In scalar context, each execution of "m//g" finds the next
match, returning true if it matches, and false if there is no
further match. The position after the last match can be read or
set using the pos() function; see the pos entry in the perlfunc
manpage. A failed match normally resets the search position to
the beginning of the string, but you can avoid that by adding
the "/c" modifier (e.g. "m//gc"). Modifying the target string
also resets the search position.
You can intermix "m//g" matches with "m/\G.../g", where "\G" is
a zero-width assertion that matches the exact position where the
previous "m//g", if any, left off. Without the "/g" modifier,
the "\G" assertion still anchors at pos(), but the match is of
course only attempted once. Using "\G" without "/g" on a target
string that has not previously had a "/g" match applied to it is
the same as using the "\A" assertion to match the beginning of
the string.
so \G is meaningless in list context and you regex fails and the loop
isn't entered. |G is only useful with /g in a scalar context.
see my other post for a working solution with splice.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
------------------------------
Date: 18 Dec 2003 18:27:51 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: strange results using m//g in while loop...
Message-Id: <u9zndqyo9k.fsf@wcl-l.bham.ac.uk>
"Damian" <not_a_real@adress.getting.too.much.spam.org> writes:
> Anno Siegel wrote:
>
> > Another way is to provide the behavior of /g in scalar context
> > explicitly
> > while calling it in list context:
> >
> > while ( my @matches = /\G<something>/ ) {
> > pos = $+[ 0];
> > # ...
> > }
>
> Thank you Anno, I tried using the above, as it seems to be the solution
> I'm looking for, though it never seems to enter the loop:
>
> my $re_d = qr|(\d),(\d),(\d)|;
>
> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
>
> while (my @r = $s =~ m/\G$re_d/) {
> pos($s) = $+[0];
> print "[@r]\n";
> }
>
> (I tried it with the /g modifier too, though I didn't think it should be
> there in this case.)
>
> Is there something missing?
Yes, Anno missed out .*? which is needed if the matches are
non-contiguous.
my $re_d = qr|(\d),(\d),(\d)|;
my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
while (my @r = $s =~ m/\G.*?$re_d/) {
pos($s) = $+[0];
print "[@r]\n";
}
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: 18 Dec 2003 18:35:23 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: strange results using m//g in while loop...
Message-Id: <u9vfoeynx0.fsf@wcl-l.bham.ac.uk>
Uri Guttman <uri@stemsystems.com> writes:
> >>>>> "D" == Damian <not_a_real@adress.getting.too.much.spam.org> writes:
>
> > Thank you Anno, I tried using the above, as it seems to be the solution
> > I'm looking for, though it never seems to enter the loop:
>
> > while (my @r = $s =~ m/\G$re_d/) {
>
> from perlre:
>
> In scalar context, each execution of "m//g" finds the next
> match, returning true if it matches, and false if there is no
> further match. The position after the last match can be read or
> set using the pos() function; see the pos entry in the perlfunc
> manpage. A failed match normally resets the search position to
> the beginning of the string, but you can avoid that by adding
> the "/c" modifier (e.g. "m//gc"). Modifying the target string
> also resets the search position.
>
> You can intermix "m//g" matches with "m/\G.../g", where "\G" is
> a zero-width assertion that matches the exact position where the
> previous "m//g", if any, left off. Without the "/g" modifier,
> the "\G" assertion still anchors at pos(), but the match is of
> course only attempted once. Using "\G" without "/g" on a target
> string that has not previously had a "/g" match applied to it is
> the same as using the "\A" assertion to match the beginning of
> the string.
>
> so \G is meaningless in list context
No it isn't.
> and you regex fails and the loop isn't entered.
The regex fails because pos($s)=0 initially and hense the first \G
behaves like \A. The OP's pattern $re_d didn't match at the start
of $s so the loop isn't entered.
> |G is only useful with /g in a scalar context.
No it isn't.
> see my other post for a working solution with splice.
See my other post for a working solution with \G with out /g and with
m// in a list context.
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: Thu, 18 Dec 2003 10:41:50 -0800
From: "Trent Curry" <tcurrey@no.no.i.said.no>
Subject: Re: strange results using m//g in while loop...
Message-Id: <brssfn$8m2$1@news.astound.net>
Uri Guttman wrote:
>>>>>> "D" == Damian <not_a_real@adress.getting.too.much.spam.org>
>>>>>> writes:
>
> so \G is meaningless in list context and you regex fails and the loop
> isn't entered. |G is only useful with /g in a scalar context.
Apparenly it isn't:
<code>
my $re_d = qr|(\d),(\d),(\d)|;
my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
while (my @r = $s =~ m/\G.*?$re_d/) {
pos($s) = $+[0];
print "[@r]\n";
}
</code>
<output>
[1 2 3]
[4 5 6]
[7 8 9]
</output>
Remove the \G and it keeps iterating ad infinitum
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
...
Conclusion: it indeed makes a difference, forcing scalar context, giving
@r that matches for that iteration only, and the pos assignment manually
moving the matching along.
--
Trent Curry
perl -e
'($s=qq/e29716770256864702379602c6275605/)=~s!([0-9a-f]{2})!pack("h2",$1
)!eg;print(reverse("$s")."\n");'
------------------------------
Date: Thu, 18 Dec 2003 18:55:25 GMT
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: strange results using m//g in while loop...
Message-Id: <x71xr2c5wj.fsf@mail.sysarch.com>
>>>>> "BM" == Brian McCauley <nobull@mail.com> writes:
> Yes, Anno missed out .*? which is needed if the matches are
> non-contiguous.
> my $re_d = qr|(\d),(\d),(\d)|;
> my $s = "abcde1,2,3hk4,5,6hkgk7,8,9dfdfdfd";
> while (my @r = $s =~ m/\G.*?$re_d/) {
ok, it is the .*? that makes it work. i tried it without that and i see
why it failed (as you pointed out). the pos (\G) starts at 0 or the end
of the last match and you need the .*? to eat chars before the match. i
don't use \G much and i never used it in a list context before. the docs
i quoted seem to imply that it was only for list context but it just
uses the pos() value either way.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
------------------------------
Date: Thu, 18 Dec 2003 16:46:10 GMT
From: James Willmore <jwillmore@remove.adelphia.net>
Subject: Re: When closing DOS window...
Message-Id: <20031218114610.5f145c4e.jwillmore@remove.adelphia.net>
On Thu, 18 Dec 2003 13:24:30 -0000
"Richard S Beckett" <spikeywan@bigfoot.com.delete.this.bit> wrote:
<snip>
> Should I start Excel differently so that it terminates when the
> script does?
>
> Alternatively, can anyone give me any pointers on how to trap the
> user clicking on the X so that I can ensure that my END block is
> run, like I now do for control C?
The example given in the Win32::OLE documentation uses Excel - but has
the user open and close Excel, not the script. That's the route I
went with one of the few Win32 scripts I've written. Will that help?
Another may be to use one of the Spreadsheet modules to do what you
need to do - removing the actual Excel application from the mix.
http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel.pm
I realize this isn't much to go on, but that's what experience I've
had and just figured I'd throw it out there. Others may have better
options.
--
Jim
Copyright notice: all code written by the author in this post is
released under the GPL. http://www.gnu.org/licenses/gpl.txt
for more information.
a fortune quote ...
You will be a winner today. Pick a fight with a four-year-old.
------------------------------
Date: Thu, 18 Dec 2003 18:05:15 +0100
From: Thomas Kratz <ThomasKrarz@REMOVEwebCAPS.de>
Subject: Re: When closing DOS window...
Message-Id: <3fe1df05.0@juno.wiesbaden.netsurf.de>
Richard S Beckett wrote:
> Guys,
>
> I ahve written a script that runs in a DOS window, and parses a log file
> into Excel.
>
> If a user decides to terminate the script whilst running, the Excel process
> gets left running, and messes up the operation of the script, and Excel
> afterwards.
>
> I invoke Excel like this:
> my $excel;
> eval {$excel = Win32::OLE->GetActiveObject('Excel.Application')};
> die "WARNING! Excel not installed" if $@;
> unless (defined $excel) {
> $excel = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;}) or die
> "ERROR, cannot start Excel";
> }
This way you are first trying to use an already opened Excel. If this
fails you will start a new instance.
>
> I have an END block that closes Excel down, and I have successfully trapped
> Control C so that the END block gets executed and Excel is closed properly.
>
> However, I have found that if the user presses the X button on the window,
> then I am again left with an orphan Excel process.
The X button closes down the command shell running your script. The script
is killed immediately.
>
> Should I start Excel differently so that it terminates when the script does?
You have to create a watchdog for your script that kills Excel, when your
script should be killed.
One solution could be:
- create a master Perl script, that runs in the background without a
window (use wperl.exe instead of perl.exe)
- let it start Excel (with Win32::Process, keep the object to kill
it later) or get the PID of a already running Excel (not sure how
to do that), You can create an Win32::Process Object with a PID.
- let it start a new cmd interpreter with your script (wait for
this process to end)
- your script should just connect to Excel with
Win32::OLE->GetActiveObject not create a new one with
Win32::OLE->new
- when the master script regains control, all you have to do is kill
Excel, if it is still running.
But what if the user kills the master process with TaskManager?
I personally would probably do the user interaction with Tk (with
wperl.exe no cmd window involved). You can trap the closing of Tk windows.
Thomas
--
open STDIN,"<&DATA";$=+=14;$%=50;while($_=(seek( #J~.> a>n~>>e~.......>r.
STDIN,$:*$=+$,+$%,0),getc)){/\./&&last;/\w| /&&( #.u.t.^..oP..r.>h>a~.e..
print,$_=$~);/~/&&++$:;/\^/&&--$:;/>/&&++$,;/</ #.>s^~h<t< ..~. ...c.^..
&&--$,;$:%=4;$,%=23;$~=$_;++$i==1?++$,:_;}__END__#....>>e>r^..>l^...>k^..
------------------------------
Date: 18 Dec 2003 10:57:08 -0800
From: yf110@vtn1.victoria.tc.ca (Malcolm Dew-Jones)
Subject: Re: When closing DOS window...
Message-Id: <3fe1f884@news.victoria.tc.ca>
Richard S Beckett (spikeywan@bigfoot.com.delete.this.bit) wrote:
: Guys,
: I ahve written a script that runs in a DOS window, and parses a log file
: into Excel.
: If a user decides to terminate the script whilst running, the Excel process
: gets left running, and messes up the operation of the script, and Excel
: afterwards.
: I invoke Excel like this:
: my $excel;
: eval {$excel = Win32::OLE->GetActiveObject('Excel.Application')};
: die "WARNING! Excel not installed" if $@;
: unless (defined $excel) {
: $excel = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;}) or die
: "ERROR, cannot start Excel";
: }
: I have an END block that closes Excel down, and I have successfully trapped
: Control C so that the END block gets executed and Excel is closed properly.
: However, I have found that if the user presses the X button on the window,
: then I am again left with an orphan Excel process.
The command line program does not (normally, ever?) see the controlling
events sent to the dos-box window. (After all, the dos box is emulating a
window-less environment.)
: Should I start Excel differently so that it terminates when the script does?
Perhaps an Excel macro could monitor the dos-box and shut down excel
if the dos-box app goes away. Total guess, but I wonder if there's a
"OnOLETimeout" or similar event defined for excel.
: Alternatively, can anyone give me any pointers on how to trap the user
: clicking on the X so that I can ensure that my END block is run, like I now
: do for control C?
Spawn a second process and start excel from within that process instead.
Have that process provide its own window. If the user closes the dos-box
then your app still runs. If they close the (second) window then you
receive the window close and shut down excel.
You don't need a ful fledged window, a modeless dialog box would be
enough. (I'm not sure if/how a console program shows a modeless dialog
though - a regular dialog is very easy to display, at least in the active
state distro.)
Alternately, the second program could run in the background and monitor
the first (dos-box) process, and shut both itself and excel down if the
dos-box goes away.
$0.02
------------------------------
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.
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 5954
***************************************