in reply to Re: Database design and Class::DBI
in thread Database design and Class::DBI

First, these are method calls and prototypes on method calls are ignored. I realize this is a special case that allows for constant folding -- I don't want to use prototypes for the only and only case where they actually work with methods :) I might encourage others to do Bad Things.

Second, the discussion of void prototype issues and the resultant "mysterious" behavior is enough for me to avoid using them unless I really, really want them. Also, subclassing them doesn't always work if they've been optimized away. Later versions of Perl (IIRC >= 5.8?) will optimize away the subroutine itself, thus ensuring that calls to SUPER from a subclass will have disappointing results.

Cheers,
Ovid

New address of my CGI Course.
Silence is Evil (feel free to copy and distribute widely - note copyright text)

Replies are listed 'Best First'.
Re: Re: Re: Database design and Class::DBI
by perrin (Chancellor) on Mar 06, 2003 at 04:12 UTC
    Is there a reason you didn't use the "constant" pragma? Personally I find it annoying and use package variables instead, but I believe it does exactly what you just did.

      I just ran a quick test on 5.8 to ensure that there were no problems with inheriting constants and, as far as I can tell, there aren't any, but I do worry about it because of issues like this:

      $ perl -MO=Deparse -e 'sub foo(){3};print foo()' print 3;

      Note that the sub declaration is gone and, due to the constant folding optimization, the value of the constant is hardcoded into the program at compile time. As a result, I tend to avoid constants if they're to be used outside of a given package. For example, I used to do this:

      use constant DEBUGGING => 0; # later if (DEBUGGING) {...}

      I would try to override DEBUGGING in a test suite ...

      local *Some::Package::DEBUGGING = sub {0};

      ... only to discover that because use of the constant had been optimized away, there was nothing left to override. I've personally found that bugs like this can be very difficult for me to debug as these are "behind the scenes" compile-time actions. I wound up sticking explicit sub declarations (with no prototype) in my code and my problems went away.

      In other words, I use the constant pragma quite a bit, but again, only if said constant isn't to be used outside of a given package (or is to be explicitly exported to another package).

      My coworker and I had quite a bit of debate about these issues and whether or not to use constants, but what finally settled it was simple: these are properties of a class, so we should provide accessors to them and ensure that the interface to class data is consistent. The only consideration we gave to the special case is that the accessors are ALL CAPS, which should be a clue to any programmer that there's something odd going on.

      Cheers,
      Ovid

      New address of my CGI Course.
      Silence is Evil (feel free to copy and distribute widely - note copyright text)

        Hmmm, I don't see how what you're doing is really any different from using constant. Isn't constant doing exactly the same thing behind the scenes? I also don't think it's fair to complain that you couldn't override a sub made by the constant pragma, since you're not supposed to know that it's a sub anyway!

        However, I am very down on the use of the constant pragma and using subs as constants in general, because of all the messy situations you get into when trying to use your constants in a string or a hash key. I think it's much more clear to just use globals, which everyone can understand immediately.