3

As I understand from Enums in Ruby question, you use Symbols to stand for something in ruby instead of enums in other languages as java or C#.

When you have enums, you can gather related identifiers in one place as below. You can see from the code that there are three colors available, and that paint method accepts one of those three values.

enum Color {
  Red,
  Yellow,
  Purple
}
public void paint(Color color) {}

how do you document the available values for related symbols in ruby?(:red, :yellow, :purple) Do you have to put it in a comment in the method that uses them, as below?

# allowed colors: :red, :yellow, :purple
def paint(color)
end
Community
  • 1
  • 1
Yeonho
  • 3,629
  • 4
  • 39
  • 61
  • My personal preference is to make a module that just contains constant values. See http://stackoverflow.com/a/76046/3124288 – JKillian Aug 07 '15 at 02:49
  • possible duplicate of [Enums in Ruby](http://stackoverflow.com/questions/75759/enums-in-ruby) – JKillian Aug 07 '15 at 02:49
  • @JKillian so you use `constants` instead of `symbols`? – Yeonho Aug 07 '15 at 02:57
  • Well, the constants can be a symbol, string, integer, Class, etc, not particularly important. The Enums in Ruby question has lots of good answers though that give you different ways of doing things. – JKillian Aug 07 '15 at 14:40

2 Answers2

2

Usually I create a constant array containing the allowed symbols. You can freeze it if you want to be sure that it won't change.

COLORS = [:red, :green, :blue].freeze

If you have a lot of different elements, you can use the %i() syntax:

COLORS = %i(red green blue yellow purple).freeze

And if you're using Rails, since the 4.1 version there's a enum macro available for ActiveRecord::Base.

class Car < ActiveRecord::Base
  enum color: %i(red green blue yellow purple)
end

Car.new(color: :red)
mrodrigues
  • 1,052
  • 10
  • 14
  • in the `initialize` method of `Car`, do you validate that `color` is indeed in the `COLORS`, or is it just for documentation purposes? – Yeonho Aug 07 '15 at 03:14
  • 1
    If you try to pass an invalid element, Rails will raise an error: `Car.new(color: :small)` throws an `ArgumentError: 'small' is not a valid color` error. By the way, Rails allows you to pass a string as well, and it'll convert it to the correct value. Internally, an enum is represented as an integer column in the database. – mrodrigues Aug 07 '15 at 03:23
  • Oh sorry, now I've seen that I forgot to write the inheritance, gonna fix that. – mrodrigues Aug 07 '15 at 05:30
  • 1
    how do I actually use the constant array, for example if I want to check if a variable is `:red` or if I want to pass in a value of `:red`? – makstaks Sep 07 '20 at 18:56
2
module TOKEN_TYPES 

  def self.const_missing(name)
    type = TYPES.find { |e| e == name.to_s.upcase.to_sym }
                    raise "constant not found error" if type.nil?
  return type

  end

# punctuation
TYPES = [:LEFT_PAREN, :RIGHT_PAREN, :LEFT_BRACE, :RIGHT_BRACE,
       :COMMA, :DOT, :SEMICOLON, :SLASH, :BACK_SLASH, :STAR,

# mathematical operators
:OP_PLUS, :OP_MINUS, :OP_MUL, :OP_DIV, :LT, :LE, :EQ, :NE, :GT, :GE, :OP_POW, # ne = <>

# logical operators
:TRUE, :FALSE, :NIL,

# program flow

# errors

# other
:AMPERSAND,

# literals
:NUM, :STRING, :SYM, :IDENTIFIER, :CONSTANT,

# keywords
:CLASS, :MODULE, :BEGIN, :END, :IF, :ELSE, :IF, :UNLESS, :DO, :WHILE, :FOR, :UNTIL,
:NEXT, :SKIP, :BREAK, :RETURN, :DEF, :ENFORCE, :INCLUDE, :EXTEND,

:EOF]
end

This may not suit everybody's needs. I just wanted symbols without value. You can use it like this

type = TOKEN_TYPES::CLASS
# => type = :CLASS
von spotz
  • 875
  • 7
  • 17