2011-12-21 53 views
12

Tại sao is_a? trả về false cho lớp học Hash?Tại sao is_a? trả về false cho lớp Hash?

Ví dụ:

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

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

Output:

Hash 
false 

Im sử dụng của Ruby 1.9.2

CẬP NHẬT: nguồn đầy đủ các lớp học của tôi:

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

Tất cả mọi thứ là ok trên ruby ​​1.9.2p290 (2011/07/09) (tôi đã nhận một giá trị true) – cristian

+0

công trình đối với tôi ... – Chowlett

+0

Cũng làm việc ở đây. Bạn có thể kiểm tra nếu 'Hash.new.is_a? (Hash)' cũng trả về false? Điều đó khá lạ lùng. –

Trả lời

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 

cố gắng vô hiệu hóa bất kỳ viên ngọc/extensions bạn đã tải và thử với ruby ​​sạch

UPDATE:

thử value.is_a?(::Hash)

PS: cố gắng đọc về Duck Typing trong Ruby. Có thể bạn nên gọi số value.respond_to?(:key) thay vì value.is_a?(Hash)

+0

(Đó là 1.9.3 :) –

+0

Nó hoạt động trong irb, nhưng không phải trong mẫu của tôi. Tôi đã liệt kê toàn bộ nguồn lớp học –

+4

thử 'value.is_a? (:: Hash)' –

2

Không.

[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 

Một Mongoid Hash không phải là một tinh khiết-Ruby Hash, cũng không mở rộng nó. Bạn nên kiểm tra loại thực tế, có thể bằng cách sử dụng type.

Chỉ vì một cái gì đó in ra Hash không có nghĩa là (a) là một phần của chuỗi thừa kế bạn nghĩ, và (b) đó là Hash (chứng kiến ​​ActiveRecord Array, nằm ở một mức độ).

+0

Nó hoạt động trong irb, nhưng không có trong mẫu của tôi. Tôi đã liệt kê toàn bộ lớp nguồn –

+1

@AlexeyZakharov Nếu đó là một băm Mongoid bạn có lẽ nên kiểm tra một cách rõ ràng cho toàn bộ lớp - một Mongoid Hash không phải là một Ruby Hash, cũng không mở rộng nó. [docs] (http://rubydoc.info/github/mongoid/mongoid/master/Mongoid/Fields/Serializable/Hash) –

3

Khi tôi thêm "::" trước khi lớp Hash, nó bắt đầu hoạt động.

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

Output:

Hash 
true 
+4

Thay vì trả lời câu hỏi của riêng bạn, tại sao không chấp nhận câu trả lời được cập nhật ở trên từ zed_oxff? – Yule

+0

Zed, tôi đã chấp nhận câu trả lời của bạn. Sự thật là tôi tìm thấy câu trả lời cùng một lúc. =) Cảm ơn bạn –

Các vấn đề liên quan