> 1) A faulty assumption that the process exit code covers the 'death by signal' case.
SIGSTOP e.g. is indeed something to skip later-on in detecting when to terminate.
But there's still an issue: ignored child state changes must be either ignored in the reaper or in the loop exit condition, otherwise we exit the loop on e.g. SIGSTOP as well.
> 2) Missing parentheses on the exists statements, giving the wrong precedence.
Here I got curious, as the test script behaved as expected when I killed my sleep child processes with zap sleep.3.
perl -MO=Deparse -e '%a=("a",1,"b",2); print "ok" if exists $a{a} && 1
++exists $a{b}'
# (%a) = ('a', 1, 'b', 2);
# print 'ok' if exists $a{'a'} and 1 + exists($a{'b'});
# NOTE above interesting and _misleading_ choice of parens, _plus_ tra
+nslation to 'and'
perl -MO=Deparse -e '%a=("a",1,"b",2); print "ok" if exists($a{a} && 1
++exists $a{b})'
# exists argument is not a HASH or ARRAY element at -e line 1.
# NOTE same error of course w/o Deparse, also when I move ')' behind '
+1'.
While 'and' surely makes the condition more readable, it doesn't look like '&&' leads to an unintended precedence. Which you'd normally expect with '&&' (when using it yourself intentionally). Why this? ->
perl -MO=Deparse -e 'sub f {warn join "\n",@_,"",""};%a=("a",1,"b",2);
+ print "ok" if f $a{a} && 5+f $a{b}'
# print 'ok' if f $a{'a'} && 5 + f($a{'b'});
# output 2 6 (* with sub f ($), it's 1 2)
perl -MO=Deparse -e 'sub f {warn join "\n",@_,"",""};%a=("a",1,"b",2);
+ print "ok" if f($a{a} && 5+f $a{b})'
# print 'ok' if f $a{'a'} && 5 + f($a{'b'});
# output 5 2
perl -MO=Deparse -e 'sub f {warn join "\n",@_,"",""};%a=("a",1,"b",2);
+ print "ok" if f($a{a} && 5)+f $a{b}'
# print 'ok' if f($a{'a'} && 5) + f($a{'b'});
perl -e 'sub f {warn join "\n",@_,"",""};%a=("a",1,"b",2); print "ok"
+if f($a{a}) && 5+f($a{b})'
# output 1 2
perl -e 'sub f {warn join "\n",@_,"",""};%a=("a",1,"b",2); print "ok"
+if f $a{a} and 5+f $a{b}'
# output 1 2
(I'd naively expected Deparse to be a bit more explicit in its rephrasing. Anyway:)
After reading man perlop, exists() is a named unary operator,
and thus has precedence over both '&&' and 'and'. The function f in contrast is
a 'list operator (rightward)', with a precedence lower than '&&'.
So the precedence in the statement was correct. And considering the three of us, this loop exit statement is well on it's way to become a future maintenance trap :).
Suggestion: Consider replacing '&&' with the more normal/readable 'and'.
Note that using parens is still required to protect against e.g. prototypes overturning naive precedence expectations wrt e.g. comparison operators:
f 3 >= 5
What is the argument here to a previous sub f?
And in case of sub f($)?
And what about &f 3 >= 5 for both cases?
Perlish prototypes != C prototypes in use and semantics: (tye)Re: A question of style, &f vs f(), Gratuitous use of Perl Prototypes and finally USAGE OF Prototype.
/me leaves to fetch an Arkansas stone and some honing oil in order to remove the embarassing nicks out of /my paranoia. |