Какой простой / элегантный способ сказать в Ruby, является ли конкретная переменная Hash или Array? - PullRequest
121 голосов
/ 20 марта 2011

Чтобы проверить, что такое @some_var, я делаю

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

Я уверен, что есть более элегантный способ проверить, является ли @some_var значением Hash или Array.

Ответы [ 9 ]

233 голосов
/ 20 марта 2011

Вы можете просто сделать:

@some_var.class == Hash

или что-то вроде:

@some_var.is_a?(Hash)

Стоит отметить, что "is_a?"Метод true, если класс находится где-нибудь в дереве предков объектов.например:

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

вышеизложенное верно, если @some_var является экземпляром хэша или другого класса, который происходит от Object.Итак, если вы хотите строгое соответствие для типа класса, используя == или instance_of?Метод, вероятно, то, что вы ищете.

36 голосов
/ 29 мая 2013

Прежде всего, лучший ответ на буквальный вопрос -

Hash === @some_var

Но на вопрос, действительно, следовало бы ответить, показывая, как здесь можно печатать на уток.Это зависит от того, какая утка вам нужна.

@some_var.respond_to?(:each_pair)

или

@some_var.respond_to?(:has_key?)

или даже

@some_var.respond_to?(:to_hash)

могут быть правильными в зависимости от приложения.

25 голосов
/ 20 марта 2011

Обычно в ruby, когда вы ищете «тип», вы на самом деле хотите «тип утки» или «это как кряк, как утка?». Вы увидите, отвечает ли он определенному методу:

@some_var.respond_to?(:each)

Вы можете перебрать @some_var, потому что он отвечает: каждый

Если вы действительно хотите знать тип и если это Hash или Array, тогда вы можете сделать:

["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
11 голосов
/ 20 марта 2011
Hash === @some_var #=> return Boolean

это также можно использовать с оператором case

case @some_var
when Hash
   ...
when Array
   ...
end
4 голосов
/ 01 мая 2015

На практике вам часто хочется действовать по-разному в зависимости от того, является ли переменная массивом или хешем, а не просто сказать. В этой ситуации идиома элегантный выглядит следующим образом:

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

Обратите внимание, что вы не вызываете метод .class для item.

4 голосов
/ 09 июля 2014

Я использую это:

@var.respond_to?(:keys)

Работает для Hash и ActiveSupport :: HashWithIndifferentAccess.

2 голосов
/ 20 марта 2011

Вы можете использовать instance_of?

* 1004 например *

@some_var.instance_of?(Hash)
0 голосов
/ 16 августа 2018

Если вы хотите проверить, является ли объект строго или расширяет Hash, используйте:

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

Но чтобы оценить утку Руби, вы можете сделать что-то вроде:

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

Это полезно, когда вы хотите получить доступ только к некоторому значению с использованием синтаксиса value[:key].

Обратите внимание, что Array.new["key"] повысит TypeError.

0 голосов
/ 20 марта 2011
irb(main):005:0> {}.class
=> Hash
irb(main):006:0> [].class
=> Array
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...