First of all, this is not a duplicate of Enums in Ruby :)
The accepted answer of that question suggests this as a good way to represent enums in Ruby:
class Foo
BAR = 1
BAZ = 2
BIZ = 4
end
In Java it is possible to attach multiple values and methods to an enum value. I want to achive the same or something similar in Ruby.
What would be the most Ruby-like way to represent this Java enum:
public enum Enum
VALUE_1("Value 1"),
VALUE_2("Value 2"),
VALUE_3("Value 3");
Enum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
private String value;
}
EDIT:
I also want to keep the implicit features of Java enums:
Examples:
Enum.VALUE_1.getValue(); // "Value 1"
Enum.VALUE_2.name(); // "VALUE_2"
Enum.VALUE_3.ordinal(); // 2
class MyEnum
attr_accessor :value
def initialize(value)
@value = value
end
VALUE1 = new("Value 1")
VALUE2 = new("Value 2")
class << self
private :new
end
end
MyEnum::VALUE2 # Enum with value "Value 2"
MyEnum.new # Error
A more elaborate solution that allows you to define arbitrary "enum classes" and also gives you ordinal()
:
def enum(*values, &class_body)
Class.new( Class.new(&class_body) ) do
attr_reader :ordinal
def initialize(ordinal, *args, &blk)
super(*args, &blk)
@ordinal = ordinal
end
values.each_with_index do |(name, *parameters), i|
const_set(name, new(i, *parameters))
end
class <<self
private :new
end
end
end
# Usage:
MyEnum = enum([:VALUE1, "Value 1"], [:VALUE2, "Value 2"]) do
attr_reader :str
def initialize(str)
@str = str
end
end
MyEnum::VALUE1.str #=> "Value 1"
MyEnum::VALUE2.ordinal #=> 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With