Dr. Mu has asked for the wisdom of the Perl Monks concerning the following question:

The following gives me the result I want, but the syntax is ... well ... ugly.
use constant FIRST => 1; use constant SECOND => 2; use constant FIFTH => 5; %nums = ( @{[FIRST]} => 'Ein', @{[SECOND]} => 'Zwei', @{[FIFTH]} => 'Funf' ); print keys %nums
(The obvious -- but wrong -- "clean" way gives %nums the keys 'FIRST', 'SECOND', 'FIFTH' instead of 1, 2, 5.) I know it's not World Peace, but is there a neater way to accomplish the hash assignment?

Thanks.

Replies are listed 'Best First'.
Re: Ugly syntax
by chipmunk (Parson) on Dec 04, 2001 at 10:27 UTC
    The results you get are caused by the special bareword-quoting feature of =>. You can either avoid giving the constant to => as a bareword, or switch to a regular comma:
    %nums = ( @{[FIRST]} => 'Ein', SECOND() => 'Zwei', &THIRD => 'Drei', (FOURTH) => 'Vier', FIFTH, 'Funf', );
      Yup, SECOND through FIFTH are much cleaner; thanks! Quick response, too!

      I'm wondering about the long-term portability of SECOND and THIRD, though, as they seem to rely on the particular way that constant is implemented.

        In a nutshell, this is what sucks about constant. It's not really a built-in, but rather more of a hack based on an implementation detail.

        I used it on a big project, and I don't think I would do it again. The syntax for using constants in interpolated strings and HERE docs is horrible, and you have to be constantly alert for subtle bugs caused by the problem you desribe here. I think you're better off with globals.

      The use of &THIRD can lead to problems so it isn't a habit I encourage people to get into. The most common way that I see problems with this are typical constants exported from modules where &THIRD can cause a warning if $_[0] contains a non-numeric string. Yes, part of the reason that such a warning is possible is because the default way of making constants in the XS code of modules doesn't actually make constants like use constant does (and I think that is changing).

      Anyway, using & without () is usually a bad idea, so I don't encourage its casual use. See (tye)Re: A question of style for more on why.

              - tye (but my friends call me "Tye")
Re: Ugly syntax
by dws (Chancellor) on Dec 04, 2001 at 10:26 UTC
    Perhaps your example is contrived, but defining a manifest constant named FIRST for 1 seems like magic number avoidance run amok. Regardless,
    use constant FIRST => 1; use constant SECOND => 2; use constant FIFTH => 5; %nums = ( &FIRST => 'Ein', &SECOND => 'Zwei', &FIFTH => 'Funf' );
    works, though to use the same constants as keys, you need to say $nums{&FIRST} or $nums{+FIRST}