AlterEGO Labs official blog

About ruby, rails and another amazing stuffs…

Перечисления в Ruby

Во многих языках программирования можно встретить, так называемые, перечисления или enum, которые представляют из себя набор именованых констант. Например, в языке C# их можно объявить следующим образом:

land:csharp Листинг 1 - Enum в C#
1
2
3
enum Days {Mon, Tue, Wed, Thu, Fri, Sat, Sun};

day = Days.Mon;

В ruby нет встроенного типа enum, но есть несколько приемов как такое можно реализовать из того, что есть под рукой :-)

Вариант 1 - Быстрый и понятный

Все что нам нужно - модуль и константы. Код будет следующим:

Листинг 2 - Ruby Enum 1
1
2
3
4
5
6
7
module Days
  MON = 1
  TUE = 2
  # и так далее
end

puts Days::MON # => 1

Я думаю, что здесь особо ничего не нужно комментировать.

Вариант 2

Вот такой интересный вариант я нагуглил:

Листинг 3 - Ruby Enum 2
1
2
3
Days = [Mon = 1, Tue = 2, ...]

puts Mon # => 1

Но данный подход, как по мне, имеет несколько недостатков:

  • Теряется namespace, для этого нужно код выше поместить еще в модуль
  • Необходимо вручную прописывать значения для каждого элемента перечисления
  • Не очень удобно (но иногда все таки необходимо) использовать числа в качестве значений

Вариант 3

Необходимо будет написать дополнительно пару строк кода и… вуаля!

Листинг 4 - Ruby Enum 3
1
2
3
4
5
6
7
8
9
10
11
12
13
module Enumable
  def enum(*args)
    args.flatten.each { |const| const_set(const, const) }
  end
end

module Days
  include Enumable

  enum "MON", "TUE", "WED", ...
end

puts Days::MON # => 'MON'

Такой вариант очень удобен и читабелен, особенно если вы хотите устанавливать определенные значения для какой-либо записи в БД. Ведь сразу понятнее такая информация event.day_of_week # => 'MON', чем event.day_of_week # => 1.

Заключение

На самом деле можно нагуглить очень много вариантов реализации и вы можете выбрать именно тот, который вам по душе и лучше всего подходит к решению конкретной задачи.

P.S. Вот, на мой взгляд, одна из самых лучших реализаций ruby enum

Comments