Kjetil has asked for the wisdom of the Perl Monks concerning the following question:

O Monks,

I'm wondering, can I have the name of a constant, rather than the value, when the constant is a return value from a sub?

To quote specifically what I'm trying to do: I'm checking out some mail addresses with Mail::CheckUser, and I'd like to save the return code to my DB. I can get that by calling last_check()->{code}.

However, the names of the constants are much more instructive than the values (which are just numbers), so it is the name of the constants (e.g. CU_BAD_SYNTAX) that I want to save.

Is there an easy way to do this?

Replies are listed 'Best First'.
Re: The name of a constant
by broquaint (Abbot) on Apr 30, 2003 at 17:10 UTC
    Ahem
    use constant FOO => "a string"; sub constant_name { return (grep { $_[0] eq (\&{$_})->() } keys %constant::declared)[0] =~ /::(.*?)\z/; } print constant_name(FOO);
    So it can be done, but don't do it like that, best listen to BrowserUk and use a hash map instead.
    HTH

    _________
    broquaint

Re: The name of a constant
by BrowserUk (Patriarch) on Apr 30, 2003 at 16:56 UTC

    There's no way to do it directly, but it would be easy enough to set up an array (or hash if the range of the constants is sparse) that maps the numeric value to the textual equivalent.

    You could use the constant names as the text, but you might be better to expand the abbreviated information into a clearer error text.


    Examine what is said, not who speaks.
    1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
    2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
    3) Any sufficiently advanced technology is indistinguishable from magic.
    Arthur C. Clarke.
Re: The name of a constant
by benn (Vicar) on Apr 30, 2003 at 16:58 UTC
    Surely the point of the constant name is simply to alias the number? So whatever last_check()->{code} returns, you'll eventually compare it to CU_BAD_SYNTAX anyway?

    If you want to store a meaningful name in the DB for other reasons, you could use a hash maybe, with nicer aliases than easy-to-spot-in-code ones - "Bad Syntax" etc.

    Cheers,
    Ben.

Re: The name of a constant
by Mr. Muskrat (Canon) on Apr 30, 2003 at 17:03 UTC

    I'm not going to say that this is the best way to do it, just the first way that occurred to me. ;-)

    #!/usr/bin/perl -w use strict; use Mail::CheckUser qw(:constants); my @constants = @{ $Mail::CheckUser::EXPORT_TAGS{constants} }; foreach my $constant (@constants) { print $constant, " = ", eval($constant), $/; }

    Updated: Now prints the names of all the constants and their values.

    Added: outputs:

    CU_OK = 0 CU_BAD_SYNTAX = 1 CU_UNKNOWN_DOMAIN = 2 CU_DNS_TIMEOUT = 3 CU_UNKNOWN_USER = 4 CU_SMTP_TIMEOUT = 5 CU_SMTP_UNREACHABLE = 6

Re: The name of a constant
by bobdeath (Scribe) on Apr 30, 2003 at 17:05 UTC