Что представляет собой простой/элегантный способ в Ruby, чтобы определить, является ли конкретная переменная хешем или массивом?

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

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

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

Ответ 1

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

@some_var.class == Hash

а также что-то вроде:

@some_var.is_a?(Hash)

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

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

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

Ответ 2

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

Hash === @some_var

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

@some_var.respond_to?(:each_pair)

или

@some_var.respond_to?(:has_key?)

или даже

@some_var.respond_to?(:to_hash)

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

Ответ 3

Обычно в рубине, когда вы ищете "тип", вы на самом деле хотите "утиного типа" или "действительно ли это трюк, как утка?". Вы увидите, реагирует ли он на определенный метод:

@some_var.respond_to?(:each)

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

Если вы действительно хотите знать тип, и если это 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

Ответ 4

Hash === @some_var #=> return Boolean

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

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

Ответ 5

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

@var.respond_to?(:keys)

Он работает для Hash и ActiveSupport:: HashWithIndifferentAccess.

Ответ 6

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

например

@some_var.instance_of?(Hash)

Ответ 7

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

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

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

Ответ 8

irb(main):005:0> {}.class
=> Hash
irb(main):006:0> [].class
=> Array