Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Re: use slack;

by autark (Friar)
on Dec 20, 2000 at 19:18 UTC ( #47587=note: print w/replies, xml ) Need Help??

in reply to use slack;

I hate to turn off strict. Why use strict if you are only going to turn it off ?

I usually do this:

use strict; sub foo { print "bar\n" } my $func = "foo"; my $func_ref = \&{$func}; $func_ref->();
The reason this works is because the construct \&{$func} is exempt from the rule of strict references. It is as far as I know not documented in earlier perls, but code support for this construct has been in for a long time. It is documented in bleadperl IIRC

The construct is often used in AUTLOAD like this:

sub AUTOLOAD { # get params and function # ... my $func_ref = \&{$func}; goto &{$func_ref}; }

Replies are listed 'Best First'.
Re: use slack;
by Dominus (Parson) on Dec 21, 2000 at 20:44 UTC
    Says autark:
    > I hate to turn off strict. Why use strict if you are only going to turn it off ?
    Strict is a safety feature. It is there to prevent you from accidentally doing something dangerous. Like all safety features, it also prevents some things that are not really dangerous. For example, sometimes my kitchen smoke alarm goes off when I am cooking onions.

    If what you want is to do something that is not dangerous, but which the alarm is too stupid to distinguish from dangerous behavior, it is entirely appropriate to turn off the alarm. Should I stop cooking onions, out of some superstitious fear that maybe the alarm knows better than I do? No, that would be ridiculous.

    You asked why have the alarm, if I am just going to shut it off? That is the wrong question. I am not going to shut it off all the time; just when it interferes with my cooking of onions. The rest of the time, it will be available to perform its function, which is to warn me about accidental fires.

    The alarm is a means to an end. The goal is to prevent fires. Keeping the alarm quiet is not a goal in itself; it is only a way to help prevent fires. Keeping strict quiet is not a goal in itself, either. The goal is to avoid the dangerous and difficult bugs that can result from careless use of symbolic references. No dangerous problems can occur in this case.

    But apparently a lot of people in this thread feel the way you do, because we've seen a whole bunch of clumsy, overcoded solutions, all just to get around turning off the smoke alarm, when what's really wanted is just to turn off strict for one line and cook the damn onions already.

      I agree that in the AUTOLOAD example it is probably best to just turn off strict rather than to use a weird workaround.

      In the example that he started with, I prefer looking up the correct function in a hash to scanning a list for it. YMMV. But the two wins I see are that you don't have to synchronize the name of the function with the name of the element in the list, and you don't get cow-orkers tempted to drop the scan and just jump to the function if it exists. (Which takes you from a safe use of symbolic references to a potentially very dangerous one.)

      Also the conceptual step of knowing that you can keep functions in a hash is (in my eyes) a worthwhile step forward in sophistication.

Re: Re: use slack;
by epoptai (Curate) on Dec 21, 2000 at 07:23 UTC
    Thanks for the occult info autark! Please correct me if i'm wrong but as far as i can tell saying no strict "refs" inside a tight loop only turns strict refs off for the duration of the loop.

    Aside from this one exception employed for a well-tested condition (for a huge optimization):

    if($in){ foreach(@actions){ unless($_ eq /one|/){ if($in eq $_){ no strict "refs"; &$_()}}}}
    the (now 400 line) script uses strict. Since i know how to play by the rules why not also start to break them, since it seems to pay off so well when done carefully?

    UPDATE: I responded too quickly, as autark explained in the chatterbox, this is the perfect solution. I get to do what I want without breaking strict with:

    if($in){ foreach(@actions){ unless($_ eq /one|/){ if($in eq $_){ do{\&{$_}}->()}}}}
      The strict pragma is lexically scoped, so it will only affect the innermost block of your program.

      Now, there is no rule saying that you have to use strict;, it's only good advice :-). Though, I'm a bit curious how breaking these "rules" have paid off ?


Log In?

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2020-11-24 22:00 GMT
Find Nodes?
    Voting Booth?

    No recent polls found