@auramo, dobre pytanie i świetny wybór dla najlepszej odpowiedzi. Uwielbiam to lub nienawidzę, nie dostajesz bezpieczeństwa typu i (przynajmniej w Ruby) bezpieczeństwa literówek. Byłem podekscytowany, kiedy odkryłem wyliczenia w C #, a później w Javie (wybierz wartość, ale z nich!), Ruby w żadnym wypadku nie zapewnia prawdziwego sposobu na zrobienie tego.
Dan Rosenstark,
2
Problem z tym pytaniem polega na tym, że wyliczenia Java i C # są diametralnie różne. Członek enum Java jest instancją obiektu i singletonem. Wyliczenie Java może mieć konstruktor. Natomiast wartości wyliczone w języku C # oparte są na wartościach pierwotnych. Jakiego zachowania szuka pytający? Chociaż jest prawdopodobne, że pożądany jest przypadek C #, Java jest wyraźnie wymieniona, a nie C lub C ++, więc są pewne wątpliwości. Co do sugerowania, że nie ma sposobu, aby być „bezpiecznym” w Rubim, jest to oczywiście fałszywe, ale musisz wdrożyć coś bardziej wyrafinowanego.
user1164178
Odpowiedzi:
317
Dwie drogi. Symbole ( :foonotacja) lub stałe ( FOOnotacja).
Symbole są odpowiednie, gdy chcesz zwiększyć czytelność bez zaśmiecania kodu literałami.
Stałe są odpowiednie, gdy masz podstawową wartość, która jest ważna. Po prostu zadeklaruj moduł do przechowywania stałych, a następnie zadeklaruj stałe w tym zakresie.
moduleFoo
BAR =1
BAZ =2
BIZ =4end
flags =Foo::BAR |Foo::BAZ # flags = 3
Co jeśli te wyliczenia też są przechowywane w bazie danych? Czy notacja symboli działa? Wątpię ...
Phương Nguyễn
Użyłbym podejścia do stałych, gdybym zapisywał dane w bazie danych. Oczywiście wtedy trzeba wykonać jakiś przegląd podczas wyciągania danych z bazy danych. Możesz również użyć czegoś takiego jak :minnesota.to_spodczas zapisywania w bazie danych, aby zapisać ciąg znaków w wersji symbolu. Wierzę, że Rails ma pewne metody pomocnicze, aby sobie z tym poradzić.
mlibby
7
Czy moduł nie byłby lepszy do grupowania stałych - skoro nie będziesz go tworzył?
thomthom
3
Tylko komentarz. Ruby ma trochę kłopotów z konwencjami nazewnictwa, ale nie jest do końca oczywista, dopóki się nad nimi nie potkniesz. Nazwy wyliczeń muszą zawierać wszystkie wielkie litery, a pierwsza litera nazwy modułu musi być pisana wielkimi literami, aby ruby wiedział, że moduł jest modułem stałych.
Rokujolady
3
Nie do końca prawda. Pierwsza litera stałej musi być wielka, ale nie wszystkie litery muszą być. Jest to kwestia preferencji konwencji. Na przykład wszystkie nazwy modułów i nazwy klas są w rzeczywistości również stałymi.
Michael Brown
59
Dziwi mnie, że nikt nie zaoferował czegoś takiego (zebranego z klejnotu RAPI ):
classEnum
private
defself.enum_attr(name, num)
name = name.to_s
define_method(name +'?')do@attrs& num !=0end
define_method(name +'=')do|set|if set
@attrs|= num
else@attrs&=~num
endendend
public
def initialize(attrs =0)@attrs= attrs
enddef to_i
@attrsendend
Działa to dobrze w scenariuszach baz danych lub w przypadku stałych / wyliczeń w stylu C (jak w przypadku korzystania z FFI , z którego RAPI korzysta w szerokim zakresie).
Ponadto nie musisz się martwić, że literówki powodują cichą awarię, tak jak w przypadku rozwiązania typu skrótu.
To świetny sposób na rozwiązanie tego konkretnego problemu, ale powód, dla którego nikt nie sugerował, prawdopodobnie ma związek z faktem, że nie przypomina on wyliczeń C # / Java.
mlibby
1
Jest to nieco niekompletne, ale stanowi dobrą wskazówkę, jak można wdrożyć rozwiązania z dynamicznym podejściem. Jest podobny do wyliczenia C # z zestawem FlagsAttribute, ale podobnie jak powyższe rozwiązania oparte na symbolach / stałych, jest to jedna z wielu odpowiedzi. Problemem jest oryginalne pytanie, które jest niejasne (C # i Java nie są wymienne). Istnieje wiele sposobów wyszczególnienia obiektów w Ruby; wybór właściwego zależy od rozwiązanego problemu. Niewłaściwe kopiowanie niewolniczych funkcji jest mylące. Prawidłowa odpowiedź musi zależeć od kontekstu.
user1164178
52
Najbardziej idiomatycznym sposobem na to jest użycie symboli. Na przykład zamiast:
enum {
FOO,
BAR,
BAZ
}
myFunc(FOO);
... możesz po prostu użyć symboli:
# You don't actually need to declare these, of course--this is# just to show you what symbols look like.:foo
:bar
:baz
my_func(:foo)
Jest to nieco bardziej otwarte niż wyliczenia, ale dobrze pasuje do ducha Ruby.
Symbole również działają bardzo dobrze. Na przykład porównywanie dwóch symboli dla równości jest znacznie szybsze niż porównywanie dwóch ciągów.
Tak więc duch Ruby brzmi: „Literówki się skompilują”
mxcl
82
Popularne frameworki Ruby w dużej mierze polegają na metaprogramowaniu środowiska wykonawczego, a wykonanie zbyt dużej kontroli czasu ładowania zabrałoby większość ekspresyjnej mocy Ruby. Aby uniknąć problemów, większość programistów Rubiego ćwiczy projektowanie oparte na testach, które znajdzie nie tylko literówki, ale także błędy logiczne.
emk
10
@yar: Cóż, projektowanie języków to szereg kompromisów, a funkcje językowe współdziałają. Jeśli chcesz dobrego, wysoce dynamicznego języka, idź z Ruby, najpierw napisz testy jednostkowe i idź z duchem języka. :-) Jeśli nie tego szukasz, istnieje wiele innych doskonałych języków, z których każdy ma inne kompromisy.
emk
10
@emk, zgadzam się, ale moim osobistym problemem jest to, że czuję się dobrze w Ruby, ale nie czuję się komfortowo refaktoryzując się w Ruby. A teraz, kiedy zacząłem pisać testy jednostkowe (wreszcie), zdaję sobie sprawę, że to nie jest panaceum: zgaduję, że 1) że kod Ruby nie jest masowo refaktoryzowany tak często, w praktyce i 2) Ruby to nie koniec -of-the-line pod względem dynamicznych języków, właśnie dlatego, że trudno jest automatycznie refaktoryzować. Zobacz moje pytanie 2317579, które dziwnie przejęli ludzie z Smalltalk.
Dan Rosenstark,
4
Tak, ale używanie tych ciągów nie byłoby zgodne z duchem języka C #, jest to po prostu zła praktyka.
Myślę, że to najlepsza odpowiedź. Funkcjonalność, składnia i minimalny narzut kodu są najbliższe Java / C #. Możesz także zagnieździć definicje nawet głębiej niż jeden poziom i nadal odzyskiwać wszystkie wartości za pomocą MyClass :: MY_ENUM.flatten. Na marginesie użyłbym tutaj wielkich liter, tak jak jest to standard dla stałych w Rubim. MyClass :: MyEnum może być mylone z odniesieniem do podklasy.
Janosch
@Janosch, zaktualizowałem nazwiska. dzięki za sugestię
Alexey
Nadal jestem trochę zdezorientowany, a link 410'd (nie, nie 404). Czy możesz podać przykłady wykorzystania tego wyliczenia?
Shelvacu
17
Jeśli używasz Railsów 4.2 lub nowszych, możesz użyć wyliczeń Railsów.
Railsy mają teraz domyślnie wyliczenia bez potrzeby dołączania jakichkolwiek klejnotów.
Jest to bardzo podobne (i więcej z funkcjami) do wyliczeń Java, C ++.
Jak powiedziałeś - nieprzydatne, jeśli OP nie używa Railsów (a ściślej obiekt nie jest typu ActiveRecord). Samo wyjaśnienie mojej opinii jest wszystkim.
Ger
2
To nie są wyliczenia w Rubim, to interfejs ActiveRecord do wyliczeń w bazie danych. Nie jest to uogólnione rozwiązanie, które można zastosować w każdym innym przypadku użycia.
Adam Lassek
Aleady wspomniałem o tym w mojej odpowiedzi.
wedant
To jest najlepsza odpowiedź IFF przy użyciu Railsów.
theUtherSide
Nie podoba mi się to, ponieważ musi być przechowywane w bazie danych Railsów (do pracy) i ponieważ pozwala na tworzenie wielu instancji Conversationklasy - uważam, że musi ona dopuszczać tylko 1 instancję.
prograils
8
To jest moje podejście do wyliczeń w Ruby. Chciałem być krótki i słodki, niekoniecznie najbardziej podobny do C. jakieś pomysły?
IMHO bardzo dokładnie odwzorowuje użycie i cel (bezpieczeństwo typu) z Javy, a także, w ramach preferencji, stałe można zdefiniować w następujący sposób:class ABC; end
wik
8
Wiem, że minęło dużo czasu, odkąd facet opublikował to pytanie, ale miałem to samo pytanie i ten post nie dał mi odpowiedzi. Chciałem w łatwy sposób zobaczyć, co reprezentuje liczba, łatwe porównanie, a przede wszystkim obsługę ActiveRecord dla wyszukiwania za pomocą kolumny reprezentującej wyliczenie.
Nic nie znalazłem, więc zrobiłem niesamowitą implementację o nazwie yinum która pozwoliła na wszystko, czego szukałem. Stworzyłem mnóstwo specyfikacji, więc jestem pewien, że to bezpieczne.
Jeśli martwisz się literówkami z symbolami, upewnij się, że Twój kod zgłasza wyjątek podczas uzyskiwania dostępu do wartości za pomocą nieistniejącego klucza. Możesz to zrobić, używając fetchzamiast []:
my_value = my_hash.fetch(:key)
lub wprowadzając skrót domyślnie wyjątek, jeśli podasz nieistniejący klucz:
my_hash =Hash.new do|hash, key|
raise "You tried to access using #{key.inspect} when the only keys we have are #{hash.keys.inspect}"end
Jeśli skrót już istnieje, możesz dodać zachowanie powodujące wyjątki:
my_hash =Hash[[[1,2]]]
my_hash.default_proc = proc do|hash, key|
raise "You tried to access using #{key.inspect} when the only keys we have are #{hash.keys.inspect}"end
Zwykle nie musisz się martwić o bezpieczeństwo literówek ze stałymi. Jeśli źle przeliterujesz stałą nazwę, zwykle spowoduje to wyjątek.
Wygląda na to, że popierasz emulację wyliczeń za pomocą skrótów , nie mówiąc wprost. Dobrym pomysłem może być edytowanie odpowiedzi. (I również mają obecnie zapotrzebowanie na coś takiego jak teksty stałe w Ruby, a moje pierwsze podejście do rozwiązywania go jest za pomocą skrótów: FOO_VALUES = {missing: 0, something: 1, something_else: 2, ...}Definiuje główne symbole. missing, somethingItp, a także sprawia, że są porównywalne poprzez odpowiednie wartości.)
Teemu Leisti,
Nie mówię tego na samym początku odpowiedzi.
Teemu Leisti,
4
Ktoś poszedł naprzód i napisał rubinowy klejnot o nazwie Renum . Twierdzi, że ma najbliższe zachowanie podobne do Java / C #. Osobiście wciąż uczę się Ruby i byłem trochę zszokowany, gdy chciałem, aby konkretna klasa zawierała statyczny wyliczenie, być może skrót, że nie było łatwo znaleźć google.
Nigdy nie potrzebowałem wyliczenia w Ruby. Symbole i stałe są idiomatyczne i rozwiązują te same problemy, prawda?
Chuck
Prawdopodobnie Chuck; ale szukanie wyliczenia w rubinie nie zaprowadzi cię tak daleko. To pokaże ci wyniki najlepszej ludzkiej próby bezpośredniego odpowiednika. Zastanawiam się, może jest coś fajnego w tym, że ta koncepcja jest razem.
dlamblin
@Chuck Symbole i stałe nie wymuszają, np. Że wartość musi być jednym z małego zestawu wartości.
David Moles,
3
Wszystko zależy od tego, w jaki sposób używasz wyliczeń Java lub C #. Sposób korzystania z niego podyktuje rozwiązanie, które wybierzesz w Ruby.
Znacznie lepsza praktyka używania symboli tutaj, IMO.
Collin Graves,
3
Niedawno wydaliśmy klejnot, który implementuje Enums w Ruby . W moim poście znajdziesz odpowiedzi na swoje pytania. Opisałem również, dlaczego nasza implementacja jest lepsza niż istniejące (w rzeczywistości istnieje wiele implementacji tej funkcji w Ruby jako klejnoty).
# bar.rb
require 'ostruct'# not needed when using Rails# by patching Array you have a simple way of creating a ENUM-styleclassArraydef to_enum(base=0)OpenStruct.new(map.with_index(base).to_h)endendclassBar
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"endendend# 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'
Czy server_Symbz jakiegoś powodu używasz drugiego słowa w zmiennych (np. )? O ile nie ma konkretnego powodu, idiomatyczne jest, aby zmienne były snake_case_with_all_lower_casei symbole :lower_case.
Andrew Grimm,
1
@Andrzej; ten przykład został zaczerpnięty ze świata rzeczywistego, a dokumentacja protokołu sieciowego używała xxx_Rrr, więc kod w kilku językach wykorzystywał tę samą koncepcję, aby można było śledzić zmiany specyfikacji.
Jonke,
1
Kod golfa: server_Symb.each_with_index { |e,i| server_Enum[e] = i}. Nie ma potrzeby i = 0.
Andrew Grimm,
2
Zaimplementowałem takie wyliczenia
moduleEnumTypedefself.find_by_id id
if id.instance_of?String
id = id.to_i
end
values.each do|type|if id == type.id
return type
endendnilenddefself.values
[@ENUM_1,@ENUM_2]endclassEnum
attr_reader :id,:label
def initialize id, label
@id= id
@label= label
endend@ENUM_1=Enum.new(1,"first")@ENUM_2=Enum.new(2,"second")end
Nie radziłbym tego podejścia, ponieważ polega ono na ręcznym ustawianiu wartości i zapewnianiu prawidłowego zamówienia :VAL. Lepiej byłoby zacząć od tablicy i zbudować skrót za pomocą.map.with_index
DaveMongoose,
1
Dokładnym celem jest przywiązanie się do wartości podyktowanej przez osoby trzecie. Nie chodzi o samo rozszerzanie, ale o radzenie sobie z zewnętrznymi ograniczeniami, które wpływają na obliczalność w granicach procesu.
jjk
Uczciwy punkt! W takim przypadku zdecydowanie warto podać wartości, ale byłbym skłonny do wyszukiwania wstecznego z kluczem .keylub .invertzamiast niego :VAL( stackoverflow.com/a/10989394/2208016 )
DaveMongoose 23.0919
Tak, to (z powrotem na ciebie) słuszna kwestia. Mój rubin był nieelegancki i nieporęczny. Zdecydowanie skorzystałby keylubinvert
jjk
1
Większość ludzi używa symboli (taka jest :foo_barskładnia). To rodzaj unikalnych nieprzejrzystych wartości. Symbole nie należą do żadnego typu typu wyliczeniowego, więc nie są tak naprawdę wierną reprezentacją typu wyliczeniowego C, ale jest to tak dobre, jak to możliwe.
Czasami wszystko, czego potrzebuję, to móc pobrać wartość wyliczenia i zidentyfikować jego nazwę podobną do świata Java.
moduleEnumdef get_value(str)
const_get(str)enddef get_name(sym)
sym.to_s.upcase
endendclassFruits
include Enum
APPLE ="Delicious"
MANGO ="Sweet"endFruits.get_value('APPLE')#'Delicious'Fruits.get_value('MANGO')# 'Sweet'Fruits.get_name(:apple)# 'APPLE'Fruits.get_name(:mango)# 'MANGO'
To dla mnie służy celowi wyliczania i sprawia, że jest on również bardzo rozszerzalny. Możesz dodać więcej metod do klasy Enum i viola uzyskać je za darmo we wszystkich zdefiniowanych wyliczeniach. na przykład. get_all_names i takie tam.
Innym podejściem jest użycie klasy Ruby z hashem zawierającym nazwy i wartości, jak opisano w poniższym poście na blogu RubyFleebie . Pozwala to na łatwą konwersję między wartościami a stałymi (szczególnie jeśli dodasz metodę klasy, aby wyszukać nazwę dla danej wartości).
Myślę, że najlepszym sposobem na zaimplementowanie wyliczenia podobnego do typów jest użycie symboli, ponieważ właściwie zachowują się jak liczby całkowite (jeśli chodzi o performace, object_id służy do dokonywania porównań); nie musisz się martwić indeksowaniem, a one wyglądają naprawdę porządnie w kodzie xD
Kolejny sposób naśladowania wyliczenia z konsekwentnym traktowaniem równości (bezwstydnie przyjęty przez Dave'a Thomasa). Pozwala na otwarte wyliczenia (podobnie jak symbole) i zamknięte (predefiniowane) wyliczenia.
Odpowiedzi:
Dwie drogi. Symbole (
:foo
notacja) lub stałe (FOO
notacja).Symbole są odpowiednie, gdy chcesz zwiększyć czytelność bez zaśmiecania kodu literałami.
Stałe są odpowiednie, gdy masz podstawową wartość, która jest ważna. Po prostu zadeklaruj moduł do przechowywania stałych, a następnie zadeklaruj stałe w tym zakresie.
źródło
:minnesota.to_s
podczas zapisywania w bazie danych, aby zapisać ciąg znaków w wersji symbolu. Wierzę, że Rails ma pewne metody pomocnicze, aby sobie z tym poradzić.Dziwi mnie, że nikt nie zaoferował czegoś takiego (zebranego z klejnotu RAPI ):
Które można wykorzystać tak:
Przykład:
Działa to dobrze w scenariuszach baz danych lub w przypadku stałych / wyliczeń w stylu C (jak w przypadku korzystania z FFI , z którego RAPI korzysta w szerokim zakresie).
Ponadto nie musisz się martwić, że literówki powodują cichą awarię, tak jak w przypadku rozwiązania typu skrótu.
źródło
Najbardziej idiomatycznym sposobem na to jest użycie symboli. Na przykład zamiast:
... możesz po prostu użyć symboli:
Jest to nieco bardziej otwarte niż wyliczenia, ale dobrze pasuje do ducha Ruby.
Symbole również działają bardzo dobrze. Na przykład porównywanie dwóch symboli dla równości jest znacznie szybsze niż porównywanie dwóch ciągów.
źródło
Stosuję następujące podejście:
Podoba mi się z następujących zalet:
MY_ENUM
MY_VALUE_1
Symbole mogą być lepsze, ponieważ nie musisz wpisywać nazwy klasy zewnętrznej, jeśli używasz jej w innej klasie (
MyClass::MY_VALUE_1
)źródło
Jeśli używasz Railsów 4.2 lub nowszych, możesz użyć wyliczeń Railsów.
Railsy mają teraz domyślnie wyliczenia bez potrzeby dołączania jakichkolwiek klejnotów.
Jest to bardzo podobne (i więcej z funkcjami) do wyliczeń Java, C ++.
Cytat z http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html :
źródło
Conversation
klasy - uważam, że musi ona dopuszczać tylko 1 instancję.To jest moje podejście do wyliczeń w Ruby. Chciałem być krótki i słodki, niekoniecznie najbardziej podobny do C. jakieś pomysły?
źródło
Sprawdź klejnot rubinowy: https://github.com/dblock/ruby-enum .
źródło
Być może najlepsze byłoby podejście lekkie
W ten sposób wartości mają powiązane nazwy, jak w Javie / C #:
Aby uzyskać wszystkie wartości, możesz to zrobić
Jeśli chcesz wartości porządkowej wyliczenia, możesz to zrobić
źródło
class ABC; end
Wiem, że minęło dużo czasu, odkąd facet opublikował to pytanie, ale miałem to samo pytanie i ten post nie dał mi odpowiedzi. Chciałem w łatwy sposób zobaczyć, co reprezentuje liczba, łatwe porównanie, a przede wszystkim obsługę ActiveRecord dla wyszukiwania za pomocą kolumny reprezentującej wyliczenie.
Nic nie znalazłem, więc zrobiłem niesamowitą implementację o nazwie yinum która pozwoliła na wszystko, czego szukałem. Stworzyłem mnóstwo specyfikacji, więc jestem pewien, że to bezpieczne.
Niektóre przykładowe funkcje:
źródło
Jeśli martwisz się literówkami z symbolami, upewnij się, że Twój kod zgłasza wyjątek podczas uzyskiwania dostępu do wartości za pomocą nieistniejącego klucza. Możesz to zrobić, używając
fetch
zamiast[]
:lub wprowadzając skrót domyślnie wyjątek, jeśli podasz nieistniejący klucz:
Jeśli skrót już istnieje, możesz dodać zachowanie powodujące wyjątki:
Zwykle nie musisz się martwić o bezpieczeństwo literówek ze stałymi. Jeśli źle przeliterujesz stałą nazwę, zwykle spowoduje to wyjątek.
źródło
FOO_VALUES = {missing: 0, something: 1, something_else: 2, ...}
Definiuje główne symbole.missing
,something
Itp, a także sprawia, że są porównywalne poprzez odpowiednie wartości.)Ktoś poszedł naprzód i napisał rubinowy klejnot o nazwie Renum . Twierdzi, że ma najbliższe zachowanie podobne do Java / C #. Osobiście wciąż uczę się Ruby i byłem trochę zszokowany, gdy chciałem, aby konkretna klasa zawierała statyczny wyliczenie, być może skrót, że nie było łatwo znaleźć google.
źródło
Wszystko zależy od tego, w jaki sposób używasz wyliczeń Java lub C #. Sposób korzystania z niego podyktuje rozwiązanie, które wybierzesz w Ruby.
Wypróbuj
Set
typ macierzysty , na przykład:źródło
Set[:a, :b, :c]
?Niedawno wydaliśmy klejnot, który implementuje Enums w Ruby . W moim poście znajdziesz odpowiedzi na swoje pytania. Opisałem również, dlaczego nasza implementacja jest lepsza niż istniejące (w rzeczywistości istnieje wiele implementacji tej funkcji w Ruby jako klejnoty).
źródło
Innym rozwiązaniem jest użycie OpenStruct. Jest całkiem prosty i czysty.
https://ruby-doc.org/stdlib-2.3.1/libdoc/ostruct/rdoc/OpenStruct.html
Przykład:
źródło
Symbole to rubinowa droga. Czasami jednak trzeba porozmawiać z jakimś kodem C lub czymś lub Javą, która ujawnia pewną enum dla różnych rzeczy.
Można to następnie wykorzystać w ten sposób
Można to oczywiście uczynić abstrakcyjnym i możesz rzucić naszą własną klasą Enum
źródło
server_Symb
z jakiegoś powodu używasz drugiego słowa w zmiennych (np. )? O ile nie ma konkretnego powodu, idiomatyczne jest, aby zmienne byłysnake_case_with_all_lower_case
i symbole:lower_case
.server_Symb.each_with_index { |e,i| server_Enum[e] = i}
. Nie ma potrzebyi = 0
.Zaimplementowałem takie wyliczenia
to jest łatwe do zrobienia
...
...
źródło
To wydaje się trochę zbyteczne, ale jest to metodologia, której użyłem kilka razy, szczególnie tam, gdzie integruję się z XML-em lub podobnymi.
Daje mi to rygor ac acumum i jest on związany z modelem.
źródło
:VAL
. Lepiej byłoby zacząć od tablicy i zbudować skrót za pomocą.map.with_index
.key
lub.invert
zamiast niego:VAL
( stackoverflow.com/a/10989394/2208016 )key
lubinvert
Większość ludzi używa symboli (taka jest
:foo_bar
składnia). To rodzaj unikalnych nieprzejrzystych wartości. Symbole nie należą do żadnego typu typu wyliczeniowego, więc nie są tak naprawdę wierną reprezentacją typu wyliczeniowego C, ale jest to tak dobre, jak to możliwe.źródło
Wynik:
1 - a
2 - b
3 - c
4 - d
źródło
to_enum
daje enumera Tora , natomiastenum
w C # / Java jest sens enumera cjaWynik:
źródło
Czasami wszystko, czego potrzebuję, to móc pobrać wartość wyliczenia i zidentyfikować jego nazwę podobną do świata Java.
To dla mnie służy celowi wyliczania i sprawia, że jest on również bardzo rozszerzalny. Możesz dodać więcej metod do klasy Enum i viola uzyskać je za darmo we wszystkich zdefiniowanych wyliczeniach. na przykład. get_all_names i takie tam.
źródło
Innym podejściem jest użycie klasy Ruby z hashem zawierającym nazwy i wartości, jak opisano w poniższym poście na blogu RubyFleebie . Pozwala to na łatwą konwersję między wartościami a stałymi (szczególnie jeśli dodasz metodę klasy, aby wyszukać nazwę dla danej wartości).
źródło
Myślę, że najlepszym sposobem na zaimplementowanie wyliczenia podobnego do typów jest użycie symboli, ponieważ właściwie zachowują się jak liczby całkowite (jeśli chodzi o performace, object_id służy do dokonywania porównań); nie musisz się martwić indeksowaniem, a one wyglądają naprawdę porządnie w kodzie xD
źródło
Kolejny sposób naśladowania wyliczenia z konsekwentnym traktowaniem równości (bezwstydnie przyjęty przez Dave'a Thomasa). Pozwala na otwarte wyliczenia (podobnie jak symbole) i zamknięte (predefiniowane) wyliczenia.
źródło
Wypróbuj inum. https://github.com/alfa-jpn/inum
zobacz więcej https://github.com/alfa-jpn/inum#usage
źródło