Was ist der beste Weg, um die enum Idiom in Ruby zu implementieren? Ich bin auf der Suche nach etwas, das ich (fast) wie die Java/C# enums verwenden können.
Antworten
Zu viele Anzeigen?Eine andere Lösung ist die Verwendung von OpenStruct. Es ist ziemlich geradlinig und sauber.
https://ruby-doc.org/stdlib-2.3.1/libdoc/ostruct/rdoc/OpenStruct.html
Beispiel:
# bar.rb
require 'ostruct' # not needed when using Rails
# by patching Array you have a simple way of creating a ENUM-style
class Array
def to_enum(base=0)
OpenStruct.new(map.with_index(base).to_h)
end
end
class Bar
MY_ENUM = OpenStruct.new(ONE: 1, TWO: 2, THREE: 3)
MY_ENUM2 = %w[ONE TWO THREE].to_enum
def use_enum (value)
case value
when MY_ENUM.ONE
puts "Hello, this is ENUM 1"
when MY_ENUM.TWO
puts "Hello, this is ENUM 2"
when MY_ENUM.THREE
puts "Hello, this is ENUM 3"
else
puts "#{value} not found in ENUM"
end
end
end
# usage
foo = Bar.new
foo.use_enum 1
foo.use_enum 2
foo.use_enum 9
# put this code in a file 'bar.rb', start IRB and type: load 'bar.rb'
Es hängt alles davon ab, wie Sie Java- oder C#-Enums verwenden. Wie Sie sie verwenden, bestimmt die Lösung, die Sie in Ruby wählen werden.
Versuchen Sie die einheimische Set
Typ, zum Beispiel:
>> enum = Set['a', 'b', 'c']
=> #<Set: {"a", "b", "c"}>
>> enum.member? "b"
=> true
>> enum.member? "d"
=> false
>> enum.add? "b"
=> nil
>> enum.add? "d"
=> #<Set: {"a", "b", "c", "d"}>
Jemand hat ein Ruby-Edelstein namens Renum . Es behauptet, das Java/C#-ähnliche Verhalten am ehesten zu erreichen. Ich persönlich lerne Ruby immer noch und war ein wenig schockiert, als ich eine bestimmte Klasse mit einer statischen Enum, möglicherweise einem Hash, versehen wollte, dass dies nicht gerade leicht über Google zu finden war.
Vor kurzem haben wir eine gem die Folgendes implementiert Enums in Ruby . In meinem Beitrag werden Sie die Antworten auf Ihre Fragen finden. Außerdem habe ich dort beschrieben, warum unsere Implementierung besser ist als die bestehenden (tatsächlich gibt es viele Implementierungen dieser Funktion in Ruby, auch als Gems).
Ich habe Enums wie folgt implementiert
module EnumType
def self.find_by_id id
if id.instance_of? String
id = id.to_i
end
values.each do |type|
if id == type.id
return type
end
end
nil
end
def self.values
[@ENUM_1, @ENUM_2]
end
class Enum
attr_reader :id, :label
def initialize id, label
@id = id
@label = label
end
end
@ENUM_1 = Enum.new(1, "first")
@ENUM_2 = Enum.new(2, "second")
end
dann ist es einfach, Operationen durchzuführen
EnumType.ENUM_1.label
...
enum = EnumType.find_by_id 1
...
valueArray = EnumType.values