web-dev-qa-db-ja.com

Rubyで特定の変数がハッシュか配列かを判断するためのシンプルでエレガントな方法は何ですか?

@some_varとは何かを確認するために、

if @some_var.class.to_s == 'Hash' 

@some_varHashまたはArrayであるかどうかを確認するよりエレガントな方法があると確信しています。

121
drhyde

あなたはただすることができます:

@some_var.class == Hash

または次のようなもの:

@some_var.is_a?(Hash)

「is_a?」クラスがオブジェクトの祖先ツリーのどこかにある場合、methodはtrueです。例えば:

@some_var.is_a?(Object)  # => true

@some_varがハッシュまたはObjectから派生する他のクラスのインスタンスである場合、上記は真です。したがって、クラスのタイプを厳密に一致させたい場合は、==またはinstance_ofを使用しますか?メソッドはおそらくあなたが探しているものです。

236
Pete

まず、文字通りの質問に対する最良の答えは

Hash === @some_var

しかし、ここでアヒルのタイピングを行う方法を示すことで、質問は本当に答えられるはずでした。それはあなたが必要とするアヒルの種類に少し依存します。

@some_var.respond_to?(:each_pair)

または

@some_var.respond_to?(:has_key?)

あるいは

@some_var.respond_to?(:to_hash)

アプリケーションによっては正しい場合があります。

36
cabo

通常、Rubyでは、「タイプ」を探しているときに、実際に「アヒルのタイプ」または「アヒルのような鳴き声をしたいですか?」が必要です。特定のメソッドに応答するかどうかがわかります。

@some_var.respond_to?(:each)

:eachに応答するため、@ some_varを反復処理できます。

型を本当に知りたい場合、およびそれがハッシュまたは配列である場合は、次のことができます:

["Hash", "Array"].include?(@some_var.class)  #=> check both through instance class
@some_var.kind_of?(Hash)    #=> to check each at once
@some_var.is_a?(Array)   #=> same as kind_of
25
Brandon
Hash === @some_var #=> return Boolean

これは、caseステートメントでも使用できます。

case @some_var
when Hash
   ...
when Array
   ...
end
11
GutenYe

実際には、単なるテルではなく、変数が配列であるかハッシュであるかによって異なる動作をすることがよくあります。この状況では、エレガントイディオムは次のとおりです。

case item
  when Array
   #do something
  when Hash
   #do something else
end

item.classメソッドを呼び出さないことに注意してください。

4

私はこれを使用します:

@var.respond_to?(:keys)

HashおよびActiveSupport :: HashWithIndifferentAccessで機能します。

4
drinor

instance_of?を使用できます

例えば

@some_var.instance_of?(Hash)
2
Shiv

オブジェクトがHashを厳密に拡張するか拡張するかをテストする場合は、次を使用します。

value = {}
value.is_a?(Hash) || value.is_a?(Array) #=> true

しかし、Rubyのカモタイピングの価値を高めるには、次のようなことができます。

value = {}
value.respond_to?(:[]) #=> true

value[:key]構文を使用して特定の値にのみアクセスする場合に便利です。

Array.new["key"]TypeErrorを発生させることに注意してください。

0
Vini Brasil