[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

enum in ruby ?

Andreas Habel

5/2/2005 5:29:00 PM

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

Thanks,
Andreas
14 Answers

Bill Atkins

5/2/2005 5:46:00 PM

0

Don't know if there's anything built-in, but you can try (untested):

[:CONST_1, :CONST_2].each_with_index { |name, i| eval name.to_s + " = " + (i
+ 1).to_s }

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?
>
> 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
>
> Thanks,
> Andreas
>
>


--
Bill Atkins

Ara.T.Howard

5/2/2005 5:49:00 PM

0

mark sparshatt

5/2/2005 5:50:00 PM

0

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
>

The following is a simple implementation of what you want


class Class
def const_def(*symbols)
symbols.each_with_index do |symbol, index|
const_set(symbol, index + 1)
end
end
end

class MyClass
const_def :CONST_A1, :CONST_A2, :CONST_A3

p CONST_A1, CONST_A2, CONST_A3
end

#=>
1
2
3


HTH

--
Mark Sparshatt



Andreas Schwarz

5/2/2005 5:51:00 PM

0

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?

Andreas Habel

5/2/2005 5:57:00 PM

0

mark sparshatt wrote:
> The following is a simple implementation of what you want
>
>
> class Class
> def const_def(*symbols)
> symbols.each_with_index do |symbol, index|
> const_set(symbol, index + 1)
> end
> end
> end
>
> class MyClass
> const_def :CONST_A1, :CONST_A2, :CONST_A3
>
> p CONST_A1, CONST_A2, CONST_A3
> end
>
> #=>
> 1
> 2
> 3
>
>
> HTH
>
> --
> Mark Sparshatt
>

Thanks to all for your fast answers! That`s perfect, const_set is the
miracle I searched for ;)

Andreas

Andreas Habel

5/2/2005 6:04:00 PM

0

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.

Or has someone a better suggestion for that ?

Jannis Harder

5/2/2005 7:03:00 PM

0

I've extended mark sparshatt's code and wrote an UnitTest.

const_def.rb is the code and const_def_test.rb the test

Examples:

class MyClass
const_def 4, :CONST_A1, :CONST_A2, :CONST_A3

p CONST_A1, CONST_A2, CONST_A3
end

#=>
4
5
6

class MyClassTwo
const_def "a",:CONST_A1, :CONST_A2, 7, :CONST_A3

p CONST_A1, CONST_A2, CONST_A3
end

#=>
"a"
"b"
7


--
Jannis Harder
require 'const_def'
require 'test/unit'

class ConstDefTest < Test::Unit::TestCase
def test_integers
c = Class.new
c.instance_eval do
const_def :CONST_A1, :CONST_A2, :CONST_A3
const_def 10, :CONST_B1, :CONST_B2, :CONST_B3
const_def 10, :CONST_C1, 2, :CONST_C2, 1, :CONST_C3
end
assert_equal([c::CONST_A1,c::CONST_A2,c::CONST_A3],[1, 2 ,3 ])
assert_equal([c::CONST_B1,c::CONST_B2,c::CONST_B3],[10,11,12])
assert_equal([c::CONST_C1,c::CONST_C2,c::CONST_C3],[10,2 ,1 ])
end
def test_floats
c = Class.new
c.instance_eval do
const_def 1.5, :CONST_A1, :CONST_A2, :CONST_A3
const_def 2.5, :CONST_B1, 7.0, :CONST_B2, :CONST_B3
const_def 3.5, :CONST_C1, 2.5, :CONST_C2, 0.5, :CONST_C3
end
assert_equal([c::CONST_A1,c::CONST_A2,c::CONST_A3],[1.5, 2.5 ,3.5 ])
assert_equal([c::CONST_B1,c::CONST_B2,c::CONST_B3],[2.5, 7.0 ,8.0 ])
assert_equal([c::CONST_C1,c::CONST_C2,c::CONST_C3],[3.5, 2.5 ,0.5 ])
end
def test_strings
c = Class.new
c.instance_eval do
const_def "jix", :CONST_A1, :CONST_A2, :CONST_A3
const_def "ruby", :CONST_B1, "zzz", :CONST_B2, :CONST_B3
const_def "hello", :CONST_C1, "world", :CONST_C2, "!", :CONST_C3
end
assert_equal([c::CONST_A1,c::CONST_A2,c::CONST_A3],%w{jix jiy jiz})
assert_equal([c::CONST_B1,c::CONST_B2,c::CONST_B3],%w{ruby zzz aaaa})
assert_equal([c::CONST_C1,c::CONST_C2,c::CONST_C3],%w{hello world !})
end
def test_custom
c = Class.new
c.instance_eval do
const_def CustomClass.new(1,1), :CONST_A1,
:CONST_A2,
:CONST_A3

const_def CustomClass.new(3,1), :CONST_B1,
CustomClass.new("a","a"), :CONST_B2,
:CONST_B3

const_def CustomClass.new(1,2), :CONST_C1,
CustomClass.new(3,4), :CONST_C2,
CustomClass.new(5,6), :CONST_C3
end
assert_equal([c::CONST_A1,c::CONST_A2,c::CONST_A3],[
CustomClass.new(1,1),
CustomClass.new(1,3),
CustomClass.new(2,3)
])
assert_equal([c::CONST_B1,c::CONST_B2,c::CONST_B3],[
CustomClass.new(3,1),
CustomClass.new("a","a"),
CustomClass.new("a","c")
])
assert_equal([c::CONST_C1,c::CONST_C2,c::CONST_C3],[
CustomClass.new(1,2),
CustomClass.new(3,4),
CustomClass.new(5,6)
])
end
def test_mixed
c = Class.new
current_time = Time.new
c.instance_eval do
const_def 1, :CONST_A1, :CONST_A2, "hi",:CONST_A3
const_def current_time, :CONST_B1, 50, :CONST_B2, :CONST_B3
const_def 3.141, :CONST_C1, [1,2], :CONST_C2, "!", :CONST_C3
end
assert_equal([c::CONST_A1,c::CONST_A2,c::CONST_A3],[1, 2, "hi"])
assert_equal([c::CONST_B1,c::CONST_B2,c::CONST_B3],[current_time, 50, 51 ])
assert_equal([c::CONST_C1,c::CONST_C2,c::CONST_C3],[3.141, [1,2], "!" ])
end
class CustomClass
include Comparable
attr_accessor :a,:b
def initialize(a,b)
@a = a
@b = b
end
def succ
if @a < @b
CustomClass.new(@a.succ,@b)
else
CustomClass.new(@a,@b.succ.succ)
end
end
def <=> other
if (res = (@a <=> other.a)) == 0
@b <=> other.b
else
res
end
end
def inspect
"<#CC #{@a.inspect} #{@b.inspect}>"
end
end

end
class Class
def const_def(*symbols)
val = 1
symbols.each_with_index do |symbol, index|
unless symbol.is_a? Symbol
val = symbol
else
const_set(symbol, val)
begin
if val.respond_to? :succ
val = val.succ
else
val+=1
end
rescue
val = nil
end
end
end
end
end

Mark Hubbart

5/2/2005 7:04:00 PM

0

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?

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



ES

5/2/2005 8:34:00 PM

0


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.
>
>Or has someone a better suggestion for that ?

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

--
template<typename duck>
void quack(duck& d) { d.quack(); }



Mark Hubbart

5/2/2005 8:44:00 PM

0

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.
>
> Or has someone a better suggestion for that ?

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