in reply to Puzzled about strict

You're using the name of the subroutine as a symbolic reference, and use strict is unhappy about that. Putting a no strict in the eval block will work; a better solution might be a lookup hash:
my %lookup = ( a => \&a, D => \&d, X => \&X, x => \&x, d => \&d, ... );

And the following change to the code that calls the subroutine:
$result .= &{ $lookup{$_} }(@time)

It will take a better monk than me to explain why this fails silently inside the eval block. But the solution above works ( OS 10.2, 5.8.0 ), and keeps you from using symbolic references. You can find a wonderful MJD tirade against those here, and it will make you a believer.

Replies are listed 'Best First'.
Re: Re: Puzzled about strict
by converter (Priest) on Oct 30, 2002 at 06:34 UTC

    ...why this fails silently inside the eval block.

    It "fails silently" because the eval block is working exactly as expected (see perldoc -f eval). eval BLOCK is useful for trapping exceptions at run-time (making fatal exceptions non-fatal and giving you the option to handle the exception with your own code).

Re: Re: Puzzled about strict
by webengr (Pilgrim) on Oct 30, 2002 at 06:17 UTC

    Okay, I'm sold on the lookup hash approach, and it won't take much work to implement with the code I've already got.

    Thanks for the article reference... makes perfect sense to me. And I now see why the program failed... I was throwing the error message from the eval block away (Bad programmer! No donut!)... Another day, another lesson... and that's a good thing!



    PCS
Re: Puzzled about strict
by Dominus (Parson) on Nov 02, 2002 at 20:58 UTC
    Says FamousLongAgo:
    a better solution might be a lookup hash...
    You can find a wonderful MJD tirade against [symbolic references]...it will make you a believer.
    You may, however, want to see this thread, where I labeled the lookup-table approach "monkey code" and had a discussion with several people in which I pointed out that the tirade you cited does not contain any reasons why the original, symbolic reference code would really cause any problems.

    In my opinion, the no strict 'refs' solution is the obvious and easy one, and so far the only arguments I have seen against it have been from superstition.

    --
    Mark Dominus
    Perl Paraphernalia

      Advantages to the table lookup code:
      1. Identifies which functions have a given use with less work than writing a separate package.
      2. Opens you up for refactoring your code later by dynamically creating closures.
      3. If you need to later, you can choose to modify the contents of the table hash dynamically without running the risk of namespace conflicts.
      And yes, I have gained every one of these benefits from table-driven code. I also know how to do much the same things with typeglobs - but find the hash approach cleaner. I admit that is subjective.

      And details like that are nothing compared to the crap variable and function names. I mean, conservation is good and all, but a few more letters wouldn't hurt, would it?

      I'd prefer the table solution. It is monkey code indeed when it contains references to named subroutines. The solution is not to disable the stricture, but rather to build the code right into the hash and get rid of the named functions.
      my %table = ( foo => sub { ... }, bar => sub { ... }, baz => sub { ... }, # ... }
      If this is not some kind of dispatch table for incoming commands, as is usually the case, but merely trying to save some keystrokes for setup code, I submit it is still the better approach. In that case, you'd accompany the construct with something like
      { my ($n, $r); no strict qw(refs); *{$n} = $r while ($n, $r) = each %table; }
      Because this way, changing the name of a function only need be done Once And Only Once. When you change the keyname, most dependent code automatically continues working. The softref approach to saving keystrokes means you have to maintain the function names both at the sub definition as well as at the setup loop (and possibly several other locations). (You can solve this by adding a layer of indirection. Think about that approach for 10 seconds though and you'll find you're exactly back to square one. Because you'd need to store the coderefs in a hash..)

      Makeshifts last the longest.

      In my opinion, the no strict 'refs' solution is the obvious and easy one, and so far the only arguments I have seen against it have been from superstition.

      Just for arguments sake :-)

      In this module we do not want any arbritary subroutine executed. We just want the "format token" subroutines executable.

      At the moment this is not made explicit - it's implicit in the fact that FETCH can only execute single letter functions, and all the format token functions are single letter functions.

      We could document this in POD or a comment, but my personal coding philosophy is to, as much as possible, have the code document itself.

      As soon as we do:

      my %lookup = ( a => \&a, D => \&d, X => \&X, x => \&x, d => \&d, ... );

      we make the subroutines we want to execute explicit in the code. This is a good thing - and hopefully not just superstition :-)

      While I would immediately refactor the subs into the hash as anonymous subroutines I think that that first step is a useful one - and not just monkey code.