Forum: Ruby enumeration with symbol name information

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
F689a7a8d2a3daf96619feac7b880726?d=identicon&s=25 Sasa (Guest)
on 2007-07-20 12:04
(Received via mailing list)
Hello everybody...
I have a beginne's question:

I've created class for my numeric constants, it looks like:

class MyClass

  NAME1 = 0
  NAME2 = 1
  NAME3 = 2
  #etc...

  def self.to_s(something)
    case something
      when 0
        "NAME1"
      when 1
        "NAME2"
      when 2
        "NAME3"
      #etc...
    end
  end

end


What is more elegant way to do this? Basically, I want to convert the
numerical value to string representation (ideally via identifier name).

Thanks in advance,
Sasa
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2007-07-20 12:36
(Received via mailing list)
On 7/20/07, Sasa <sasa555@gmail.com> wrote:
>   NAME3 = 2
>       #etc...
>     end
>   end
>
> end
>
>
> What is more elegant way to do this? Basically, I want to convert the
> numerical value to string representation (ideally via identifier name).


In ruby we often use symbols in place of of enumerations. Any place
you'd
use  NAME0, use :name0.  For NAME1 use :name1, etc.

For example:
class MyClass
  def something
     case @enum_value
     when :name0
         puts "In name zero mode"
     when :name1
         puts "In name one mode"
     end
  end
end

:name0.to_s #=> "name0"

If, for whatever reason you don't want to use symbols, a way I
occasionally
use to emulate enums is the following:

NAME0 = Object.new

def NAME0.to_s
   "NAME0"
end

NAME1 = Object.new

def NAME1.to_s
   "NAME1"
end

...


Another method that could be used to simplify your existing code is to
use a
hash:

NAME0 = 0
NAME1 = 1
NAME2 = 2

Names = { NAME0 => "NAME0", NAME1 => "NAME1", NAME2 => "NAME2" }

def self.to_s(something)
   Names[something]
end

You can even wrap this one up (or the previous method with some
metaprogramming:)

def self.enum(*args)
   const_set("Names", {})
   args.each_with_index do |v, i|
      Names[i] = v
      const_set(v, i)
   end
end

enum "NAME0", "NAME1", "NAME2"


Thanks in advance,
Bd4166a8d561763cd47294e6265d8bca?d=identicon&s=25 Mariusz Pękala (Guest)
on 2007-07-20 13:19
(Received via mailing list)
On 2007-07-20 19:00:04 +0900 (Fri, Jul), Sasa wrote:
>   #etc...
>     end
>   end
>
> end
>
>
> What is more elegant way to do this? Basically, I want to convert the
> numerical value to string representation (ideally via identifier name).
>
> Thanks in advance,
> Sasa

If your numeric values always start from 0, then you may use an array:

class MyClass
  NAMES = [ 'NAME1','NAME2','NAME3' ]

  def self.to_s(something) # personally I would rather avoid redefining
class.to_s
    NAMES[something.to_i] || default_value
  end
end

If this is unacceptable, you may use a hash:

  NAMES = { 1 => 'NAME1', 2 => 'NAME2', 5 => 'NAME3' }
  NUMBERS = Hash[ *NAMES.map {|k,v| [v,k]}.flatten ]    # may be useful
:-)

  def self.to_s(something)
    NAMES[ something ] || defaul_value
  end

  def self.to_i(something)  # may be useful :-)
    NUMBERS[ something ] || default_number
  end
This topic is locked and can not be replied to.