2011-12-21 12 views
12

Perché is_a? restituisce false per una classe Hash?Perché is_a? restituisce false per la classe di hash?

Esempio:

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

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

uscita:

Hash 
false 

Im usando rubino 1.9.2

AGGIORNATO: sorgente completo della mia classe:

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 
+0

Tutto ok su Ruby 1.9.2p290 (2011-07-09) (ho ottenuto un valore vero) – cristian

+0

funziona per me ... – Chowlett

+0

funziona anche qui. Puoi controllare se 'Hash.new.is_a? (Hash)' restituisce anche false? Sarebbe piuttosto strano. –

risposta

19
#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 

cercare di disattivare qualsiasi gemme/estensioni che hai caricato, e cercare con rubino pulita

UPDATE:

provare value.is_a?(::Hash)

PS: cercano di leggere su Duck Typing in Ruby. Forse dovresti chiamare value.respond_to?(:key) invece di value.is_a?(Hash)

+0

(That's 1.9.3 :) –

+0

Funziona in irb, ma non nel mio esempio. Ho elencato l'intera classe sorgente –

+4

try 'value.is_a? (:: Hash)' –

2

Non è così.

[email protected]:~ $ 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 ] 

[email protected]:~ $ pry 
pry(main)> value = {"x" => 3, "y" => 2} 
=> {"x"=>3, "y"=>2} 
pry(main)> value.is_a? Hash 
=> true 

Un Mongoid Hash non è una pura rubino Hash, né estenderla. Dovresti controllare il tipo effettivo, probabilmente usando type.

Solo perché qualcosa viene stampato Hash non significa che (a) che è parte della catena di ereditarietà si pensa che è, e (b) che si tratta di un Hash (testimone ActiveRecord Array, che si trova, ad un grado).

+0

Funziona in irb, ma non nel mio esempio. Ho elencato l'intera fonte della classe –

+1

@AlexeyZakharov Se si tratta di un hash Mongoid probabilmente dovresti controllare esplicitamente la classe completa - un Hash Mongoid non è un Hash di Ruby, né lo estende. [docs] (http://rubydoc.info/github/mongoid/mongoid/master/Mongoid/Fields/Serializable/Hash) –

3

Quando ho aggiunto "::" prima della classe di hash, inizia a funzionare.

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

uscita:

Hash 
true 
+4

Invece di rispondere alla tua stessa domanda, perché non accettare la risposta aggiornata sopra da zed_oxff? – Yule

+0

Zed, ho accettato la tua risposta. La verità è che ho trovato la risposta nello stesso momento. =) Grazie –

Problemi correlati