Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re^3: Setting signal handlers considered unsafe?

by ikegami (Patriarch)
on Nov 09, 2008 at 18:07 UTC ( [id://722507]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Setting signal handlers considered unsafe?
in thread Setting signal handlers considered unsafe?

It's not a side-effect. It's not a bug. local undefines its argument. Details

Replies are listed 'Best First'.
Re^4: Setting signal handlers considered unsafe?
by gone2015 (Deacon) on Nov 09, 2008 at 19:34 UTC
    It's not a side-effect. It's not a bug. local undefines its argument.

    The documentation Temporary Values via local() says:

    .... The argument list may be assigned to if desired, which allows you to initialize your local variables. (If no initializer is given for a particular variable, it is created with an undefined value.)
    This does not say that the lvalues in the local argument list will be set undef and later the result of any initialiser will be assigned to it.

    Taking the empirical approach:

    use strict ; use warnings ; our $fred = 78 ; { local $fred = $fred ? 'Was Defined' : '*undef*' ; print "\$fred = $fred\n" ; } ; print "\$fred = $fred\n" ;
    gives:
      $fred = Was Defined
      $fred = 78
    
    which reenforces the feeling that the variable being localised retains its old value up to the moment the new value is set.

    Were it not for the side effect of setting $SIG{ALRM} to undef, nobody would ever be able to tell that being set undef is apparently a step in the initialisation of the local. The implementation may assume it doesn't matter -- we live and learn !

    IMO, this quacks like a bug.

      The documentation Temporary Values via local() says

      I agree. The docs are misleading. local actually does the same thing whether an assignment ("initializer") is present or not. local doesn't even know of the presence of an assignment. Similarly The assignment doesn't know local is present.

      Were it not for the side effect of setting $SIG{ALRM} to undef, nobody would ever be able to tell that being set undef is apparently a step in the initialisation of the local.

      Not so. I rely on that feature all the time.

      sub d :lvalue { print("$_[0]: ", defined($_[1]) ? "[$_[1]]" : "undef", "\n"); $_[1] } our $fred = 78; d("pre local", $fred); d("post local", local $fred);

      gives

      pre local: [78] post local: undef

      It can also be seen with an "initializer" present.

      sub d :lvalue { print("$_[0]: ", defined($_[1]) ? "[$_[1]]" : "undef", "\n"); $_[1] } our $fred = 78; d("pre local", $fred); d("post assign", d("post local", local $fred) = 90);
      pre local: [78] post local: undef post assign: [90]
        I agree. The docs are misleading.

        OK, so we're agreed: either the code doesn't do what the documentation says, or vice versa -- a bug in one or the other, by any reasonable standard, IMO :-)

        Not so. I rely on that feature all the time.

        Now I'm fascinated. I confess, I've tried, but I cannot imagine a useful purpose for the fact that  local $foo = 76 ; fleetingly sets $foo to undef, before setting it to the required 76.

        I understand that  local $fred ; sets $fred to undef. As far as I can see your code fragment:

        sub d :lvalue { print("$_[0]: ", defined($_[1]) ? "[$_[1]]" : "undef", "\n"); $_[1] } our $fred = 78; d("post assign", d("post local", local $fred) = 90);
        performs a local $fred (setting it undef) and passes that to sub d where it, eventually gets treated/returned as an lvalue. So far, so interesting. I only wish I could see how that informs the simpler case of:
        our $fred = 78 ; local $fred = 'ho hum' ;
        where there is a straightforward initialiser and, AFAICS, no urgent need to set $fred to undef immediately before setting it to 'ho hum'.

        Remembering, that the point here is that the current behaviour means that the recommended use of local for $SIG creates a very nasty hiatus in which the SIG_DFL state is set.

        One can, of course, ignore the standard advice and save and restore the $SIG state by hand. Or get out POSIX and block the signal during the local. This second turns out to be essential in order to use local to automatically restore the $SIG state on forced exit (die) from an eval.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://722507]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-19 23:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found