2011-12-21 22 views
12

Neden is_a?, Hash sınıfı için false döndürür?Neden isa? Hash sınıfı için false döndürür?

Örnek:

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

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

Çıktı: Ruby 1.9.2

GÜNCELLEME kullanılarak

Hash 
false 

Im: Benim sınıfının tam kaynak:

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

Her şey yakut 1.9.2p290 (2011-07-09) (i gerçek değer var) benim için – cristian

+0

eserler üzerinde ok ... – Chowlett

+0

Ayrıca burada çalışıyor. Hash.new.is_a? (Hash) 'ın da false döndürüp döndürmediğini kontrol edebilir misiniz? Bu oldukça tuhaf olurdu. –

cevap

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 

yüklediğiniz herhangi taşlar/uzantılarını devre dışı bırakmak ve temiz Ruby ile denemek için deneyin

GÜNCELLEME:

value.is_a?(::Hash)

PS deneyin: Ruby yaklaşık Duck Typing okumaya çalışın. Belki de value.is_a?(Hash)

+0

(Bu 1.9.3 :) –

+0

Bu irb çalışır, ancak benim örneğimde değil. Tüm sınıf kaynağını listeledim –

+4

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

2

yerine value.respond_to?(:key)'u aramanız gerekir.

[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 

bir Mongoid Hash saf-Ruby Hash değildir, ne de onu uzanmaz. Muhtemelen type'u kullanarak gerçek tipi kontrol etmelisiniz.

şey yazdırır diye Hash anlamına gelmez (a) Sence miras zincirinin bir parçası ve olduğunu (b) olması bir Hash (tanık bir dereceye kadar, yalan ActiveRecord Array).

+0

Bu irb içinde çalışır, ancak örneklemde değil. Tüm sınıf kaynağını listeledim –

+1

@AlexeyZakharov Eğer bir Mongoid hash iseniz, muhtemelen tam sınıf için açıkça kontrol etmelisiniz - Mongoid Hash bir Ruby Hash değil, ne de uzatıyor. [docs] (http://rubydoc.info/github/mongoid/mongoid/master/Mongoid/Fields/Serializable/Hash) –

3

Karma sınıfından önce "::" eklediğimde çalışmaya başlar.

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

Çıktı:

Hash 
true 
+4

Kendi sorunuzu yanıtlamak yerine, neden zed_oxff adresinden güncelleştirilmiş yanıtı kabul etmiyorsunuz? – Yule

+0

Zed, cevabını kabul ettim. Gerçek şu ki, aynı anda cevabı buldum. =) Teşekkürler –

İlgili konular