me.at.coding
me.at.coding

Reputation: 17796

Access name of a constant, not only its value?

In Perl, is it possible to pass a constant to a function and then display the name of the constant literally as well as use its value? Maybe by passing some kind of escaped constant name to the function?

Here is an example of what I would like to do, of course the code in exitError() yet doesn't do what I want to do.

use constant MAIL_SEND_FAILED => 1;

# exitError($exitcode)
sub exitError
{
    my $exitCode = $_[0];
    say "error, exitcode: $exitCode"; # output constant name as human readable exitcode, e.g. MAIL_SEND_FAILED
    exit $exitCode; # use value of exitcode, e.g. 1
}

exitError(MAIL_SEND_FAILED);
# function call should effectively execute this code
# say "error, exitcode: MAIL_SEND_FAILED";
# exit 1;

Upvotes: 1

Views: 912

Answers (3)

snoofkin
snoofkin

Reputation: 8895

use constant MAIL_SEND_FAILED => 1;

sub exitError
{
   my %data = @_;
   # Keys are names and values are values....
}

exitError(MAIL_SEND_FAILED => MAIL_SEND_FAILED);

Upvotes: 0

brian d foy
brian d foy

Reputation: 132920

If you want to use something's name and its value, a hash is what you are looking for. You might even have a constant hash with Readonly.

Upvotes: 2

Oleg V. Volkov
Oleg V. Volkov

Reputation: 22471

Not exactly the way you want, but to the same effect, you can use Perl's ability to store different string and number representation in single scalar with dualvar from Scalar::Util:

use strict;
use warnings;
use feature 'say';
use Scalar::Util qw(dualvar);

use constant MAIL_SEND_FAILED => dualvar 1, 'MAIL_SEND_FAILED';

sub exitError
{
    my $exitCode = $_[0];
    say "error, exitcode: $exitCode"; # output constant name as human readable exitcode, e.g. MAIL_SEND_FAILED
    exit $exitCode; # use value of exitcode, e.g. 1
}

exitError(MAIL_SEND_FAILED);

Closer to your original idea, you can exploit fact that constants are actually inlined subs and find original sub by name with can from UNIVERSAL:

use strict;
use warnings;
use feature 'say';
use Scalar::Util qw(dualvar);

use constant MAIL_SEND_FAILED => 2;

sub exitError
{
    my $exitCode = $_[0];
    say "error, exitcode: $exitCode"; # output constant name as human readable exitcode, e.g. MAIL_SEND_FAILED
    exit __PACKAGE__->can($exitCode)->(); # use value of exitcode, e.g. 1
}

exitError('MAIL_SEND_FAILED');

However, IIRC Perl doesn't guarantee that constants will always be generated that way, so this may break at later date.

Upvotes: 3

Related Questions