Почему это?возвращает false для класса Hash? - PullRequest
12 голосов
/ 21 декабря 2011

Почему is_a? возвращает false для Hash класса?

Пример:

value = {"x" => 3, "y" => 2}

puts value.class
puts value.is_a?(Hash)

Выход:

Hash
false

Я использую Ruby 1.9.2

ОБНОВЛЕНО : полный источник моего класса:

class LatLng
  include Mongoid::Fields::Serializable

  attr_reader :lat, :lng

  def serialize(value)
    return if value.nil?

    puts value.class
    puts value.is_a?(Hash)

    if value.is_a?(self.class)
      puts "is geopoint" + value.to_json
      {'lng' => value.lng.to_f, 'lat' => value.lat.to_f}
    elsif value.is_a?(Hash)
      hash = value.with_indifferent_access
      puts "is hash" + value.to_json
      {'lng' => hash['lng'].to_f, 'lat' => hash['lat'].to_f}
    end
  end

  def deserialize(value)
    return if value.nil?

    value.is_a?(self.class) ? value : LatLng.new(value['lat'], value['lng'])
  end

  def initialize(lat, lng)
    @lat, @lng = lat.to_f, lng.to_f
  end

  def [](arg)
    case arg
      when "lat"
        @lat
      when "lng"
        @lng
    end
  end

  def to_a
    [lng, lat]
  end

  def ==(other)
    other.is_a?(self.class) && other.lat == lat && other.lng == lng
  end
end

Ответы [ 3 ]

19 голосов
/ 21 декабря 2011
#irb
ruby-1.9.3-p0 :001 > value = {"x" => 3, "y" => 2}
 => {"x"=>3, "y"=>2} 
ruby-1.9.3-p0 :002 > value.is_a?(Hash)
 => true

попробуйте отключить все загруженные гемы / расширения и попробуйте с чистым ruby ​​

ОБНОВЛЕНИЕ:

попробуйте value.is_a?(::Hash)

PS: попробуйте прочитать о Duck Typing в Ruby.Может быть, вам следует позвонить value.respond_to?(:key) вместо value.is_a?(Hash)

4 голосов
/ 21 декабря 2011

Когда я добавил "::" перед классом Hash, он начинает работать.

puts value.class
puts value.is_a?(::Hash)

Выход:

Hash
true
2 голосов
/ 21 декабря 2011

Это не так.

dave@hpubuntu1:~ $ rvm list

rvm rubies

   ruby-1.8.7-p334 [ i386 ]
   jruby-1.6.2 [ linux-i386-java ]
   ruby-1.9.2-p0 [ i386 ]
   ruby-1.9.2-p290 [ i386 ]
   ruby-1.9.3-p0 [ i386 ]
=> ruby-1.9.2-p180 [ i386 ]

dave@hpubuntu1:~ $ pry
pry(main)> value = {"x" => 3, "y" => 2}
=> {"x"=>3, "y"=>2}
pry(main)> value.is_a? Hash
=> true

Mongoid Hash не является чистым Ruby Hash и не расширяет его. Вы должны проверить фактический тип, вероятно, используя type.

То, что что-то печатает Hash, не означает (а) что это часть цепочки наследования, о которой вы думаете, и (б) что это Hash (свидетель ActiveRecord Array, который лежит, в определенной степени).

...