tags:

views:

445

answers:

2

I need to pass back a enum value in perl, how can I do this?

pulling from this thread: http://stackoverflow.com/questions/473666/does-perl-have-an-enumeration-type

use strict;

use constant {
    HOME   => 'home',
    WORK   => 'work',
    MOBILE => 'mobile',
};

my $phone_number->{type} = HOME;
print "Enum: ".$phone_number->{type}."\n";

but shouldn't this return index 0? or am I understanding this wrong?

EDIT:

So would something like this be more expectable for a enum type?

use strict;

use constant {
    HOME   => 0,
    WORK   => 1,
    MOBILE => 2,
};

my $phone_number->{type} = HOME;
print "Enum: ".$phone_number->{type}."\n";

EDIT #2

Also I would like to validate on the option selected but pass back the Word rather then the Value. How can I have the best of both examples?

@VALUES = (undef, "home", "work", "mobile");

sub setValue {

if (@_ == 1) {
   # we're being set
   my $var = shift;
   # validate the argument
   my $success = _validate_constant($var, \@VALUES);

   if ($success == 1) {
       print "Yeah\n";
   } else {
       die "You must set a value to one of the following: " . join(", ", @VALUES) . "\n";
   }
}
}

sub _validate_constant {
# first argument is constant
my $var = shift();
# second argument is reference to array
my @opts = @{ shift() };

my $success = 0;
foreach my $opt (@opts) {
    # return true
    return 1 if (defined($var) && defined($opt) && $var eq $opt);
}

# return false
return 0;
}
+2  A: 

A constant is not an enum (in perl, or any language I know of)

No, because here what you're doing is inserting in the symbol table a link between the key HOME and the literal Home, this is also called a bareword in perl parlance. The symbol table is implemented with a hash, and there is no number equivalence of its keys and the order they were added.

In your example what you're doing is setting $perl_number->{type} = 'Home', and then printing out $phone_number->{type}.

Evan Carroll
Thanks for the help, Cheers!!!
Phill Pafford
sry one more EDIT :)
Phill Pafford
Invoking the symbol table doesn't really matter. It's much less confusing to people to say that you create a subroutine that takes no arguments and returns a constant value. Leave the innards out of it.
brian d foy
@brian This is my answer, you're free to leave your own using the "Add another answer" option on the bottom of your screen.
Evan Carroll
OF course, I did add my answer. However, I also help people refine and correct their own answers. Symbol tables are an unnecessary confusion here, and you appear a bit confused about what is actually going on. You can provide better answers if you brought more focus to them by leaving out unnecessary details.
brian d foy
I want to explain why I feel it is appropriate, I think in order to understand why there isn't an `enum type`, you have to understand what a *constant* really *is*. I think I did a decent job at explaining it. `BEGIN {*{FOO} = sub {5}}; print FOO` is your constant. I didn't have to introduce other concepts like you want too either, like prototyping. Now he understands that all he is doing is **putting a key/value pair in a special hash**. My response to you, brian, who **never likes *my* answer** will always be to go get your own.
Evan Carroll
There's no need for a typeglob there. That's my point. I don't think you understand that a constant is just a value that doesn't change. You don't even need to use a subroutine for it (i.e. the Readonly module). I think you're conflating two different ideas in your answer, leaving people more confused than when they started. As noted, I already have my own answer. If you don't like discussion or think that a technical discussion is personally offensive, Stackoverflow is not the place for you.
brian d foy
I understand this, in fact, I explicitly said it **"The point is, there is no enum types they're implemented with symbol table hacks, the typical hack is just key->value, he is just implementing it as a sub on the namespace, rather than a bareword (sub prototyped to take no arguments). – Evan Carroll yesterday"**I don't think the discussion is offensive, I think *you* are out to make a statement rather than help anyone.
Evan Carroll
oh, if that sounds like a personal attack, it is. You've responded to probably 10 of my answers now with nothing, while your answers consist of one line that you know the questioner has already read, with no explanation or reasoning whatsoever. Good you have 28.7k exp; if you're here for the game: you win. I'm here to help.
Evan Carroll
A: 

If you want enums, use the enum module.

brian d foy
Read the thread this one references, as per the question.
Evan Carroll
Yep, already read that. It doesn't change my answer.
brian d foy