Ruby で C# スタイルの列挙をエミュレートする最良の方法を知りたいだけです。
5 に答える
具体的には、変数が与えられた値のセットに対して論理テストを実行できるようにしたいと考えています。例は、ウィンドウの状態です:「最小化、最大化、閉じた、開いた」
列挙型を値にマップする必要がある場合 (たとえば、最小化して 0、最大化して 100 にする必要がある場合)、次のようにシンボルのハッシュを値に使用します。
WINDOW_STATES = { :minimized => 0, :maximized => 100 }.freeze
フリーズ(ネイトが言うように)は、将来誤って物事を壊すのを防ぎます。これを行うことで、何かが有効かどうかを確認できます
WINDOW_STATES.keys.include?(window_state)
または、値が必要なく、「メンバーシップ」を確認するだけでよい場合は、配列で問題ありません
WINDOW_STATES = [:minimized, :maximized].freeze
このように使用してください
WINDOW_STATES.include?(window_state)
キーが文字列になる場合 (RoR アプリの「状態」フィールドなど)、文字列の配列を使用できます。多くのRailsアプリでこれを常に行っています。
WINDOW_STATES = %w(minimized maximized open closed).freeze
これはほとんど、Rails validates_inclusion_of
Validator が専用に構築されたものです :-)
個人的なメモ:
インクルードを入力するのが好きではありませんか?常に、私はこれを持っています (複雑なのは .in?(1, 2, 3) ケースのためだけです:
class Object
# Lets us write array.include?(x) the other way round
# Also accepts multiple args, so we can do 2.in?( 1,2,3 ) without bothering with arrays
def in?( *args )
# if we have 1 arg, and it is a collection, act as if it were passed as a single value, UNLESS we are an array ourselves.
# The mismatch between checking for respond_to on the args vs checking for self.kind_of?Array is deliberate, otherwise
# arrays of strings break and ranges don't work right
args.length == 1 && args.first.respond_to?(:include?) && !self.kind_of?(Array) ?
args.first.include?( self ) :
args.include?( self )
end
end
end
これにより、入力できます
window_state.in? WINDOW_STATES
まったく同じではありませんが、私はよくこの種のハッシュを作成します。
STATES = {:open => 1, :closed => 2, :max => 3, :min => 4}.freeze()
ハッシュを凍結すると、その内容を誤って変更することがなくなります。
さらに、存在しないものにアクセスするときにエラーを発生させたい場合は、デフォルトの Proc を使用してこれを行うことができます。
STATES = Hash.new { |hash, key| raise NameError, "#{key} is not allowed" }
STATES.merge!({:open => 1, :closed => 2, :max => 3, :min => 4}).freeze()
STATES[:other] # raises NameError
Ruby が真の列挙型をサポートしているとは思いませんが、まだ解決策はあります。
ruby で Enum を定義して、定数変数を持つクラスを使用する最も簡単な方法。
class WindowState
Open = 1
Closed = 2
Max = 3
Min = 4
end
他の人が言ったようにクラスまたはハッシュを作成するとうまくいきます。ただし、Ruby で行うべきことは、シンボルを使用することです。Ruby のシンボルはコロンで始まり、次のようになります。
greetingtype = :hello
それらは、名前だけで構成されるオブジェクトのようなものです。