@auramo, pertanyaan bagus, dan pilihan bagus untuk jawaban terbaik. Suka atau benci, Anda tidak mendapatkan keamanan jenis dan (setidaknya di Ruby) tidak ada keamanan ketik. Saya sangat senang ketika saya menemukan enum di C # dan kemudian di Jawa (pilih nilai, tetapi dari ini!), Ruby tidak memberikan cara nyata untuk melakukan itu dalam hal apa pun.
Dan Rosenstark
2
Masalah dengan pertanyaan ini adalah bahwa Java dan C # enum adalah hal yang sangat berbeda. Anggota Java enum adalah instance objek dan singleton. Java enum dapat memiliki konstruktor. Sebaliknya, C # enum didasarkan pada nilai-nilai Primitive. Perilaku apa yang dicari si penanya? Meskipun kemungkinan kasus yang diinginkan adalah kasus C #, Java disebutkan secara eksplisit, bukan C atau C ++, jadi ada beberapa keraguan. Adapun untuk menyarankan bahwa tidak ada cara untuk menjadi 'aman' di Ruby, itu secara transparan salah, tetapi Anda harus menerapkan sesuatu yang lebih canggih.
user1164178
Jawaban:
319
Dua arah. Simbol ( :foonotasi) atau konstanta ( FOOnotasi).
Simbol sesuai ketika Anda ingin meningkatkan keterbacaan tanpa mengotori kode dengan string literal.
Konstanta sesuai ketika Anda memiliki nilai dasar yang penting. Hanya mendeklarasikan modul untuk memegang konstanta Anda dan kemudian mendeklarasikan konstanta di dalamnya.
moduleFoo
BAR =1
BAZ =2
BIZ =4end
flags =Foo::BAR |Foo::BAZ # flags = 3
Bagaimana jika enum ini terlalu disimpan ke database? Akankah notasi simbol berfungsi? Saya ragu ...
Phuyơng Nguyễn
Saya akan menggunakan pendekatan konstanta jika saya menyimpan ke database. Tentu saja Anda harus melakukan semacam pencarian ketika menarik data kembali dari DB. Anda juga bisa menggunakan sesuatu seperti :minnesota.to_ssaat menyimpan ke database untuk menyimpan versi string simbol. Rails, saya percaya, memiliki beberapa metode penolong untuk menangani beberapa hal ini.
mlibby
7
Bukankah sebuah modul akan lebih baik untuk dikelompokkan konstanta - karena Anda tidak akan membuat contoh itu?
thomthom
3
Hanya komentar. Ruby agak kesal tentang penamaan tetapi tidak terlalu jelas sampai mereka tersandung. Nama-nama enum harus semua huruf besar dan huruf pertama dari nama modul harus dikapitalisasi untuk ruby untuk mengetahui bahwa modul adalah modul konstanta.
Rokujolady
3
Tidak sepenuhnya benar. Huruf pertama dari konstanta harus ditulis dengan huruf besar, tetapi tidak semua huruf harus. Ini adalah masalah preferensi konvensi. Sebagai contoh, semua nama modul dan nama kelas sebenarnya adalah konstanta juga.
Michael Brown
59
Saya terkejut bahwa tidak ada yang menawarkan sesuatu seperti berikut (diambil dari permata 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
Ini berfungsi baik dalam skenario basis data, atau ketika berhadapan dengan konstanta gaya C / enum (seperti halnya ketika menggunakan FFI , yang membuat penggunaan ekstensif oleh RAPI).
Selain itu, Anda tidak perlu khawatir tentang kesalahan ketik yang menyebabkan kegagalan diam, seperti halnya Anda menggunakan solusi tipe-hash.
Itu cara yang bagus untuk menyelesaikan masalah khusus itu, tetapi alasan tidak ada yang menyarankan itu mungkin ada hubungannya dengan fakta bahwa itu tidak banyak seperti C # / Java enum.
mlibby
1
Ini agak tidak lengkap, tetapi berfungsi sebagai petunjuk bagus tentang bagaimana Anda dapat mengimplementasikan solusi dengan pendekatan dinamis. Ini memiliki beberapa kemiripan dengan C # enum dengan set FlagsAttribute, tetapi seperti simbol / solusi berbasis konstan di atas, itu adalah salah satu jawaban dari banyak. Masalahnya adalah pertanyaan asli, yang kacau di maksudnya (C # dan Java tidak dapat dipertukarkan). Ada banyak cara untuk merinci objek di Ruby; memilih yang tepat tergantung pada masalah yang sedang dipecahkan. Fitur-fitur replikasi yang tidak Anda perlukan adalah salah arah. Jawaban yang benar harus bergantung pada konteksnya.
user1164178
52
Cara paling idiomatis untuk melakukan ini adalah dengan menggunakan simbol. Misalnya, alih-alih:
enum {
FOO,
BAR,
BAZ
}
myFunc(FOO);
... Anda bisa menggunakan simbol:
# 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)
Ini sedikit lebih terbuka daripada enum, tetapi cocok dengan semangat Ruby.
Simbol juga berkinerja sangat baik. Membandingkan dua simbol untuk kesetaraan, misalnya, jauh lebih cepat daripada membandingkan dua string.
Kerangka kerja Ruby populer sangat bergantung pada pemrograman runtime, dan melakukan terlalu banyak pengecekan waktu muat akan menghilangkan sebagian besar daya ekspresif Ruby. Untuk menghindari masalah, kebanyakan programmer Ruby mempraktikkan desain yang digerakkan oleh tes, yang tidak hanya akan menemukan kesalahan ketik tetapi juga kesalahan logika.
emk
10
@yar: Nah, desain bahasa adalah serangkaian pertukaran, dan fitur bahasa berinteraksi. Jika Anda ingin bahasa yang baik, sangat dinamis, ikuti Ruby, tulis unit test Anda terlebih dahulu, dan ikuti semangat bahasa tersebut. :-) Jika bukan itu yang Anda cari, ada lusinan bahasa bagus lainnya di luar sana, yang masing-masing menghasilkan pengorbanan yang berbeda.
emk
10
@ em, saya setuju, tapi masalah pribadi saya adalah saya merasa cukup nyaman di Ruby, tapi saya tidak merasa nyaman refactoring di Ruby. Dan sekarang setelah saya mulai menulis unit test (akhirnya), saya menyadari bahwa itu bukan obat mujarab: tebakan saya adalah 1) bahwa kode Ruby tidak mendapatkan refactored secara masif yang sering, dalam praktek dan 2) Ruby bukan akhir -of-the-line dalam hal bahasa dinamis, justru karena sulit untuk refactor secara otomatis. Lihat pertanyaan saya 2317579 yang diambil alih, anehnya, oleh orang-orang Smalltalk.
Dan Rosenstark
4
Ya, tetapi menggunakan string itu tidak akan menjadi semangat bahasa C #, itu hanya praktik yang buruk.
Saya pikir ini adalah jawaban terbaik. Fungsionalitas, sintaksis, dan overhead kode minimal paling mendekati Java / C #. Anda juga dapat menyarangkan definisi lebih dalam dari satu level dan masih memulihkan semua nilai dengan MyClass :: MY_ENUM.flatten. Sebagai catatan saya akan menggunakan nama-nama besar di sini seperti standar untuk konstanta di Ruby. MyClass :: MyEnum mungkin keliru untuk referensi ke subkelas.
Janosch
@Janosch, saya sudah memperbarui nama. terima kasih untuk saran
Alexey
Saya masih sedikit bingung, dan tautannya 410'd (tidak, bukan 404). Bisakah Anda memberi contoh bagaimana enum ini akan digunakan?
Shelvacu
17
Jika Anda menggunakan Rails 4.2 atau lebih tinggi, Anda dapat menggunakan Rails enum.
Rails sekarang memiliki enum secara default tanpa perlu menyertakan permata apa pun.
Ini sangat mirip (dan lebih banyak dengan fitur) dengan Java, C ++ enums.
Seperti yang Anda katakan - tidak berguna jika OP tidak menggunakan Rails (atau lebih tepatnya objek bukan tipe ActiveRecord). Menjelaskan downvote saya saja.
Ger
2
Ini bukan enums di Ruby, ini adalah antarmuka ActiveRecord ke Enums di database Anda. Bukan solusi yang dapat digeneralisasi yang dapat diterapkan dalam setiap use case lainnya.
Adam Lassek
Saya telah aleady menyebutkan bahwa dalam jawaban saya.
vedant
Ini adalah jawaban terbaik IFF menggunakan Rails.
theUtherSide
Saya tidak suka karena itu harus disimpan dalam database Rails (untuk bekerja) dan karena memungkinkan untuk membuat banyak instance dari Conversationkelas - saya percaya itu harus memungkinkan hanya 1 instance.
prograils
8
Ini adalah pendekatan saya untuk enums di Ruby. Saya ingin pendek dan manis, belum tentu yang paling seperti C. Adakah pikiran?
IMHO ini sangat dekat mereplikasi penggunaan dan tujuan (tipe keselamatan) dari Jawa, juga, sebagai pilihan, konstanta dapat didefinisikan seperti ini:class ABC; end
wik
8
Saya tahu sudah lama sejak orang itu memposting pertanyaan ini, tetapi saya memiliki pertanyaan yang sama dan posting ini tidak memberi saya jawabannya. Saya ingin cara mudah untuk melihat apa yang mewakili angka, perbandingan mudah, dan sebagian besar dari semua dukungan ActiveRecord untuk pencarian menggunakan kolom yang mewakili enum.
Saya tidak menemukan apa pun, jadi saya membuat implementasi yang luar biasa yang disebut yinum yang memungkinkan semua yang saya cari. Membuat banyak spesifikasi, jadi saya cukup yakin itu aman.
Jika Anda khawatir tentang kesalahan ketik dengan simbol, pastikan kode Anda menimbulkan pengecualian saat Anda mengakses nilai dengan kunci yang tidak ada. Anda dapat melakukan ini dengan menggunakan fetchdaripada []:
my_value = my_hash.fetch(:key)
atau dengan membuat hash meningkatkan pengecualian secara default jika Anda memberikan kunci yang tidak ada:
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
Jika hash sudah ada, Anda bisa menambahkan perilaku peningkatan pengecualian:
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
Biasanya, Anda tidak perlu khawatir tentang keamanan kesalahan ketik dengan konstanta. Jika Anda salah mengeja nama konstan, biasanya akan muncul pengecualian.
Tampaknya Anda menganjurkan meniru enum dengan hash , tanpa mengatakannya secara eksplisit. Mungkin ada baiknya mengedit jawaban Anda untuk mengatakannya. (Saya juga saat ini memiliki kebutuhan untuk sesuatu seperti enum di Ruby, dan pendekatan pertama saya untuk memecahkan itu adalah dengan menggunakan hash: FOO_VALUES = {missing: 0, something: 1, something_else: 2, ...}ini mendefinisikan simbol kunci. missing, something, Dll, dan juga membuat mereka sebanding melalui nilai-nilai terkait.)
Teemu Leisti
Maksudku, tanpa mengatakannya di awal jawaban.
Teemu Leisti
4
Seseorang pergi ke depan dan menulis permata ruby bernama Renum . Ia mengklaim untuk mendapatkan perilaku Java / C # terdekat. Secara pribadi saya masih belajar Ruby, dan saya sedikit terkejut ketika saya ingin membuat kelas tertentu berisi enum statis, mungkin hash, bahwa itu tidak mudah ditemukan melalui google.
Saya tidak pernah membutuhkan enum di Ruby. Simbol dan konstanta itu idiom dan menyelesaikan masalah yang sama, bukan?
Chuck
Mungkin Chuck; tetapi googling untuk enum di ruby tidak akan membuat Anda sejauh itu. Ini akan menunjukkan hasil untuk upaya terbaik orang di setara langsung. Yang membuat saya bertanya-tanya, mungkin ada sesuatu yang menyenangkan tentang konsep yang disatukan.
dlamblin
@Chuck Simbol dan konstanta tidak memberlakukan, misalnya, bahwa nilai harus menjadi salah satu dari sejumlah kecil nilai.
David Moles
3
Itu semua tergantung bagaimana Anda menggunakan Java atau C # enums. Cara Anda menggunakannya akan menentukan solusi yang akan Anda pilih di Ruby.
Latihan yang jauh lebih baik untuk menggunakan simbol di sini, IMO.
Collin Graves
3
Baru-baru ini kami merilis permata yang mengimplementasikan Enums di Ruby . Dalam posting saya, Anda akan menemukan jawaban atas pertanyaan Anda. Juga saya jelaskan di sana mengapa implementasi kami lebih baik daripada yang sudah ada (sebenarnya ada banyak implementasi fitur ini di Ruby sebagai permata).
# 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'
Simbol adalah cara batu delima. Namun, terkadang seseorang perlu berbicara dengan beberapa kode C atau sesuatu atau Java yang mengekspos beberapa enum untuk berbagai hal.
#server_roles.rbmoduleEnumLikedefEnumLike.server_role
server_Symb=[:SERVER_CLOUD,:SERVER_DESKTOP,:SERVER_WORKSTATION]
server_Enum=Hash.new
i=0
server_Symb.each{|e| server_Enum[e]=i; i +=1}return server_Symb,server_Enum
endend
Apakah Anda menggunakan server_Symbhuruf kedua dalam variabel (mis. ) Karena alasan tertentu? Kecuali jika ada alasan tertentu, itu menjadi idiomatis untuk variabel snake_case_with_all_lower_case, dan simbol :lower_case.
Andrew Grimm
1
@Andrew; contoh ini diambil dari dunia nyata dan dokumentasi protokol jaringan menggunakan xxx_Yyy, jadi kode dalam beberapa bahasa menggunakan konsep yang sama sehingga orang dapat mengikuti perubahan spesifikasi.
Jonke
1
Kode golf: server_Symb.each_with_index { |e,i| server_Enum[e] = i}. Tidak perlu i = 0.
Andrew Grimm
2
Saya telah menerapkan enum seperti itu
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
Ini sepertinya agak berlebihan, tetapi ini adalah metodologi yang telah saya gunakan beberapa kali, terutama di mana saya mengintegrasikan dengan xml atau semacamnya.
Saya tidak akan menyarankan pendekatan ini karena ini bergantung pada Anda secara manual mengatur nilai-nilai dan memastikan Anda mendapatkan pesanan dengan benar :VAL. Akan lebih baik untuk memulai dengan sebuah array dan membangun hash menggunakan.map.with_index
DaveMongoose
1
Poin yang tepat adalah mengikat diri Anda pada nilai yang ditentukan oleh pihak ketiga. Ini bukan tentang ekstensibilitas per se, tetapi tentang harus berurusan dengan kendala asing yang memengaruhi komputabilitas dalam batas proses Anda.
jjk
Titik adil! Dalam hal ini jelas masuk akal untuk menentukan nilai-nilai, tetapi saya akan cenderung untuk melakukan pencarian terbalik dengan .keyatau .invertdaripada :VALkunci ( stackoverflow.com/a/10989394/2208016 )
DaveMongoose
Ya, itu (kembali padamu) poin yang adil. Rubi saya tidak bagus dan berat. Akan menggunakan def keyatauinvert
jjk
1
Kebanyakan orang menggunakan simbol (itulah :foo_barsintaks). Mereka semacam nilai-nilai buram yang unik. Simbol bukan milik tipe enum apa pun sehingga simbol tersebut tidak benar-benar mewakili tipe enum C, tetapi ini cukup bagus.
Terkadang yang saya butuhkan adalah bisa mengambil nilai enum dan mengidentifikasi namanya mirip dengan dunia 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'
Ini bagi saya melayani tujuan enum dan menjaganya agar tetap dapat diperluas. Anda dapat menambahkan lebih banyak metode ke kelas Enum dan mendapatkan biola secara gratis di semua enum yang ditentukan. sebagai contoh. get_all_names dan semacamnya.
Pendekatan lain adalah dengan menggunakan kelas Ruby dengan hash yang berisi nama dan nilai seperti yang dijelaskan dalam posting blog RubyFleebie berikut . Ini memungkinkan Anda untuk mengkonversi dengan mudah antara nilai dan konstanta (terutama jika Anda menambahkan metode kelas untuk mencari nama untuk nilai yang diberikan).
Saya pikir cara terbaik untuk mengimplementasikan enumerasi seperti jenis adalah dengan simbol karena cukup banyak berperilaku sebagai integer (ketika datang ke performace, object_id digunakan untuk membuat perbandingan); Anda tidak perlu khawatir tentang pengindeksan dan mereka terlihat sangat rapi dalam kode xD Anda
Cara lain untuk meniru enum dengan penanganan kesetaraan yang konsisten (tanpa malu-malu diadopsi dari Dave Thomas). Mengizinkan enum terbuka (seperti simbol) dan enum tertutup (sudah ditentukan sebelumnya).
Jawaban:
Dua arah. Simbol (
:foo
notasi) atau konstanta (FOO
notasi).Simbol sesuai ketika Anda ingin meningkatkan keterbacaan tanpa mengotori kode dengan string literal.
Konstanta sesuai ketika Anda memiliki nilai dasar yang penting. Hanya mendeklarasikan modul untuk memegang konstanta Anda dan kemudian mendeklarasikan konstanta di dalamnya.
sumber
:minnesota.to_s
saat menyimpan ke database untuk menyimpan versi string simbol. Rails, saya percaya, memiliki beberapa metode penolong untuk menangani beberapa hal ini.Saya terkejut bahwa tidak ada yang menawarkan sesuatu seperti berikut (diambil dari permata RAPI ):
Yang bisa digunakan seperti ini:
Contoh:
Ini berfungsi baik dalam skenario basis data, atau ketika berhadapan dengan konstanta gaya C / enum (seperti halnya ketika menggunakan FFI , yang membuat penggunaan ekstensif oleh RAPI).
Selain itu, Anda tidak perlu khawatir tentang kesalahan ketik yang menyebabkan kegagalan diam, seperti halnya Anda menggunakan solusi tipe-hash.
sumber
Cara paling idiomatis untuk melakukan ini adalah dengan menggunakan simbol. Misalnya, alih-alih:
... Anda bisa menggunakan simbol:
Ini sedikit lebih terbuka daripada enum, tetapi cocok dengan semangat Ruby.
Simbol juga berkinerja sangat baik. Membandingkan dua simbol untuk kesetaraan, misalnya, jauh lebih cepat daripada membandingkan dua string.
sumber
Saya menggunakan pendekatan berikut:
Saya suka untuk keuntungan berikut:
MY_ENUM
MY_VALUE_1
Simbol mungkin lebih baik karena Anda tidak perlu menulis nama kelas luar, jika Anda menggunakannya di kelas lain (
MyClass::MY_VALUE_1
)sumber
Jika Anda menggunakan Rails 4.2 atau lebih tinggi, Anda dapat menggunakan Rails enum.
Rails sekarang memiliki enum secara default tanpa perlu menyertakan permata apa pun.
Ini sangat mirip (dan lebih banyak dengan fitur) dengan Java, C ++ enums.
Dikutip dari http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html :
sumber
Conversation
kelas - saya percaya itu harus memungkinkan hanya 1 instance.Ini adalah pendekatan saya untuk enums di Ruby. Saya ingin pendek dan manis, belum tentu yang paling seperti C. Adakah pikiran?
sumber
Lihatlah permata ruby-enum, https://github.com/dblock/ruby-enum .
sumber
Mungkin pendekatan ringan terbaik adalah
Nilai cara ini memiliki nama terkait, seperti dalam Java / C #:
Untuk mendapatkan semua nilai, Anda bisa melakukannya
Jika Anda ingin nilai ordinal enum, Anda bisa melakukannya
sumber
class ABC; end
Saya tahu sudah lama sejak orang itu memposting pertanyaan ini, tetapi saya memiliki pertanyaan yang sama dan posting ini tidak memberi saya jawabannya. Saya ingin cara mudah untuk melihat apa yang mewakili angka, perbandingan mudah, dan sebagian besar dari semua dukungan ActiveRecord untuk pencarian menggunakan kolom yang mewakili enum.
Saya tidak menemukan apa pun, jadi saya membuat implementasi yang luar biasa yang disebut yinum yang memungkinkan semua yang saya cari. Membuat banyak spesifikasi, jadi saya cukup yakin itu aman.
Beberapa contoh fitur:
sumber
Jika Anda khawatir tentang kesalahan ketik dengan simbol, pastikan kode Anda menimbulkan pengecualian saat Anda mengakses nilai dengan kunci yang tidak ada. Anda dapat melakukan ini dengan menggunakan
fetch
daripada[]
:atau dengan membuat hash meningkatkan pengecualian secara default jika Anda memberikan kunci yang tidak ada:
Jika hash sudah ada, Anda bisa menambahkan perilaku peningkatan pengecualian:
Biasanya, Anda tidak perlu khawatir tentang keamanan kesalahan ketik dengan konstanta. Jika Anda salah mengeja nama konstan, biasanya akan muncul pengecualian.
sumber
FOO_VALUES = {missing: 0, something: 1, something_else: 2, ...}
ini mendefinisikan simbol kunci.missing
,something
, Dll, dan juga membuat mereka sebanding melalui nilai-nilai terkait.)Seseorang pergi ke depan dan menulis permata ruby bernama Renum . Ia mengklaim untuk mendapatkan perilaku Java / C # terdekat. Secara pribadi saya masih belajar Ruby, dan saya sedikit terkejut ketika saya ingin membuat kelas tertentu berisi enum statis, mungkin hash, bahwa itu tidak mudah ditemukan melalui google.
sumber
Itu semua tergantung bagaimana Anda menggunakan Java atau C # enums. Cara Anda menggunakannya akan menentukan solusi yang akan Anda pilih di Ruby.
Coba
Set
jenis asli , misalnya:sumber
Set[:a, :b, :c]
?Baru-baru ini kami merilis permata yang mengimplementasikan Enums di Ruby . Dalam posting saya, Anda akan menemukan jawaban atas pertanyaan Anda. Juga saya jelaskan di sana mengapa implementasi kami lebih baik daripada yang sudah ada (sebenarnya ada banyak implementasi fitur ini di Ruby sebagai permata).
sumber
Solusi lain adalah menggunakan OpenStruct. Cukup lurus ke depan dan bersih.
https://ruby-doc.org/stdlib-2.3.1/libdoc/ostruct/rdoc/OpenStruct.html
Contoh:
sumber
Simbol adalah cara batu delima. Namun, terkadang seseorang perlu berbicara dengan beberapa kode C atau sesuatu atau Java yang mengekspos beberapa enum untuk berbagai hal.
Ini kemudian dapat digunakan seperti ini
Ini tentu saja dapat dibuat abstrak dan Anda dapat memutar kelas Enum kami sendiri
sumber
server_Symb
huruf kedua dalam variabel (mis. ) Karena alasan tertentu? Kecuali jika ada alasan tertentu, itu menjadi idiomatis untuk variabelsnake_case_with_all_lower_case
, dan simbol:lower_case
.server_Symb.each_with_index { |e,i| server_Enum[e] = i}
. Tidak perlui = 0
.Saya telah menerapkan enum seperti itu
maka mudah untuk melakukan operasi
...
...
sumber
Ini sepertinya agak berlebihan, tetapi ini adalah metodologi yang telah saya gunakan beberapa kali, terutama di mana saya mengintegrasikan dengan xml atau semacamnya.
Ini memberi saya ketelitian ac # enum dan itu terikat dengan model.
sumber
:VAL
. Akan lebih baik untuk memulai dengan sebuah array dan membangun hash menggunakan.map.with_index
.key
atau.invert
daripada:VAL
kunci ( stackoverflow.com/a/10989394/2208016 )key
atauinvert
Kebanyakan orang menggunakan simbol (itulah
:foo_bar
sintaks). Mereka semacam nilai-nilai buram yang unik. Simbol bukan milik tipe enum apa pun sehingga simbol tersebut tidak benar-benar mewakili tipe enum C, tetapi ini cukup bagus.sumber
Keluaran:
1 - a
2 - b
3 - c
4 - d
sumber
to_enum
memberi Anda enumera tor , sedangkanenum
dalam C # / Java sense adalah enumera tionKeluaran:
sumber
Terkadang yang saya butuhkan adalah bisa mengambil nilai enum dan mengidentifikasi namanya mirip dengan dunia java.
Ini bagi saya melayani tujuan enum dan menjaganya agar tetap dapat diperluas. Anda dapat menambahkan lebih banyak metode ke kelas Enum dan mendapatkan biola secara gratis di semua enum yang ditentukan. sebagai contoh. get_all_names dan semacamnya.
sumber
Pendekatan lain adalah dengan menggunakan kelas Ruby dengan hash yang berisi nama dan nilai seperti yang dijelaskan dalam posting blog RubyFleebie berikut . Ini memungkinkan Anda untuk mengkonversi dengan mudah antara nilai dan konstanta (terutama jika Anda menambahkan metode kelas untuk mencari nama untuk nilai yang diberikan).
sumber
Saya pikir cara terbaik untuk mengimplementasikan enumerasi seperti jenis adalah dengan simbol karena cukup banyak berperilaku sebagai integer (ketika datang ke performace, object_id digunakan untuk membuat perbandingan); Anda tidak perlu khawatir tentang pengindeksan dan mereka terlihat sangat rapi dalam kode xD Anda
sumber
Cara lain untuk meniru enum dengan penanganan kesetaraan yang konsisten (tanpa malu-malu diadopsi dari Dave Thomas). Mengizinkan enum terbuka (seperti simbol) dan enum tertutup (sudah ditentukan sebelumnya).
sumber
Coba inum. https://github.com/alfa-jpn/inum
lihat lebih lanjut https://github.com/alfa-jpn/inum#usage
sumber