class Module
def enumerate(*list)
[ list ].flatten.each_with_index{|c,i| const_set "#{ c }".upcase, i + 1}
end
end
class MyClass2
enumerate :CONST_A1, :CONST_A2, :CONST_A3
enumerate %w( CONST_B1 CONST_B2 CONST_B3 )
end
p MyClass2::CONST_A1
p MyClass2::CONST_B2
harp:~ > ruby a.rb
1
2
1
2
HTH.
-a
···
On Mon, 2 May 2005, Andreas Habel wrote:
Hi,
I`ve a simple question about constants in ruby. Is there a possibility to define constants in a module or a class like a enum in c?
Maybe something short like the 'attr_accessor' syntax would be great!
class MyClass
const_def :CONST_A1, :CONST_A2, :CONST_A3
const_def :CONST_B1, :CONST_B2, :CONST_B3
end
eq.
class MyClass
CONST_A1 = 1
CONST_A2 = 2
CONST_A3 = 3
CONST_B1 = 1
CONST_B2 = 2
CONST_B3 = 3
end
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
renunciation is not getting rid of the things of this world, but accepting
that they pass away. --aitken roshi
Others have given good direct solutions... But I wonder why you would
want this? For most situations, symbols would be a cleaner solution:
MyClass.new(data, MyClass::CONST_A1, MyClass::CONST_B3)
vs.
MyClass.new(data, :a1, :b2)
They can also be used as flags:
MyClass.new(data, MyClass::CONST_A1 | MyClass::CONST_A2)
vs.
MyClass.new(data, :a1, :a2)
Constants are used in core classes like File and IO, but i think it's
mainly due to them being based on the underlying system calls, which
use C. ISTM that most rubysts prefer to use symbols for flags and
enumerated values.
HTH,
Mark
···
On 5/2/05, Andreas Habel <mail@exceptionfault.de> wrote:
Hi,
I`ve a simple question about constants in ruby. Is there a possibility
to define constants in a module or a class like a enum in c?
I`ve a simple question about constants in ruby. Is there a possibility to define constants in a module or a class like a enum in c?
Maybe something short like the 'attr_accessor' syntax would be great!
class MyClass
const_def :CONST_A1, :CONST_A2, :CONST_A3
const_def :CONST_B1, :CONST_B2, :CONST_B3
end
What do you need constants for; why not directly use symbols?
I have to synchronize a lot of constants in my code with "constants" in a database which were generated using a sequence. With the enum function I don`t have to matter which value the constant has in my database nor in ruby. Only the order is important.
Hm. If these constants have no values that you care of in the
first place, then you could definitely use Symbols, which have
the exact behaviour you seem to be looking for (distinct but
meaningless values). The only situation where Symbols would not
work is if you had actual constant values (e.g. PI has to be 3.14~)
that needed to be stored.
Sure, this way works too (and produced some nice code;), but
it might not be necessary and perhaps counterintuitive to others?
E
···
Le 2/5/2005, "Andreas Habel" <mail@exceptionfault.de> a écrit:
Andreas Schwarz wrote:
Andreas Habel wrote:
Hi,
I`ve a simple question about constants in ruby. Is there a possibility
to define constants in a module or a class like a enum in c?
Maybe something short like the 'attr_accessor' syntax would be great!
class MyClass
const_def :CONST_A1, :CONST_A2, :CONST_A3
const_def :CONST_B1, :CONST_B2, :CONST_B3
end
What do you need constants for; why not directly use symbols?
I have to synchronize a lot of constants in my code with "constants" in
a database which were generated using a sequence. With the enum function
I don`t have to matter which value the constant has in my database nor
in ruby. Only the order is important.
If you want to expose the enumerated values for use in the library,
then symbols are much more intuitive. It's worth a little effort
behind the scenes to make them available. Here's a quick
implementation for it:
class Class
def enumerate(*args) @enumerations = {}
symbols.each_with_index do |sym, idx| @enumerations[sym] = idx + 1
end
end
def enum_value(sym) @enumerations[sym]
end
end
class MyClass
enumerate :a, :b, :c
enumerate :x, :y, :z
def foo( name, enum1, enum2 ) @database.fetch( name, enum_value(enum1), enum_value(enum2) )
end
end
MyClass.new.foo("test", :a, :y)
HTH,
Mark
···
On 5/2/05, Andreas Habel <mail@exceptionfault.de> wrote:
Andreas Schwarz wrote:
> Andreas Habel wrote:
>
>> Hi,
>>
>> I`ve a simple question about constants in ruby. Is there a possibility
>> to define constants in a module or a class like a enum in c?
>>
>> Maybe something short like the 'attr_accessor' syntax would be great!
>>
>> class MyClass
>> const_def :CONST_A1, :CONST_A2, :CONST_A3
>> const_def :CONST_B1, :CONST_B2, :CONST_B3
>> end
>
>
> What do you need constants for; why not directly use symbols?
I have to synchronize a lot of constants in my code with "constants" in
a database which were generated using a sequence. With the enum function
I don`t have to matter which value the constant has in my database nor
in ruby. Only the order is important.
that's embarrassing. Obviously I didn't test the code before I sent
it, and there was a major logic error, regarding scope.
----8<----
class Class
def enumerate(*syms) @enumerations ||= {}
enums = @enumerations
syms.each_with_index do |sym, idx|
enums[sym] = idx + 1
end
define_method(:enum_val) do |sym|
enums[sym]
end
end
end
class MyClass
enumerate :a, :b, :c
enumerate :x, :y, :z
def foo(enum1, enum2)
[enum_val(enum1), enum_val(enum2)]
end
end
p MyClass.new.foo(:a, :y)
----8<----
... prints "[1, 2]"
Sorry 'bout that. I should have caught the glaring error.
cheers,
Mark
···
On 5/2/05, Andreas Habel <mail@exceptionfault.de> wrote:
Hi Mark,
I tried to implement your code and got very confused receiving the
following error.. What`s wrong ???
----
class Class
def enumerate(*symb) @enumerations = {}
symb.each_with_index do |sym, idx| @enumerations[sym] = idx + 1
end
end
def enum_val(sym) @enumerations[sym]
end
end
class MyClass
enumerate :a, :b, :c
enumerate :x, :y, :z
def foo( enum1, enum2 )
p enum_val(enum1)
p enum_val(enum2)
end
end
p Class.public_method_defined?( 'enum_val' )
p MyClass.public_method_defined?( 'enum_val' )
p MyClass.new.foo( :a, :y)
===>
true
false
test.rb:21:in `foo': undefined method `enum_val' for
#<MyClass:0x2874d40> (NoMethodError)
from test.rb:29