2013-11-22 25 views
2

我嘗試做與細化功能有點黑客(我使用Ruby 2.1.0)哈希從零隱式轉換與瑞風錯誤

目的是重定向隱式轉換(to_hash)的顯式轉換避免這個錯誤:

data = {test: :t}.merge!(nil) 
# Return TypeError: no implicit conversion of nil into Hash 

當我重新打開NilClass一切正常:

class NilClass 
def to_hash 
    to_h 
end 
end 
data = {test: :t}.merge!(nil) 
# { :test => :t } 

,當我用完善的功能,我得到一個無方法錯誤。

module MyRefine 
    module NilClass 
    refine ::NilClass do 
     def to_hash 
     selt.to_h 
     end 
    end 
    end 
end 

module Aer 
    using MyRefine::NilClass 
    data = {test: :t}.merge!(nil) 
    puts data 
end 
# NoMethodError: super: no superclass method `to_hash' for nil:NilClass 

我該如何解決這個問題?

+1

如何使用一個空的散列作爲後備,所以你不需要路徑'NilClass':'data = {test::t} .merge!(nil || {})' –

+0

這是一個極簡主義者重現問題的例子。 主要思想是擴展NilClass,以避免編寫此代碼。 和精化功能使我可以做到這一點比直接延伸NilClass更乾淨。 – Naremy

回答

1

細化在詞彙範圍內。它們只在腳本,模塊聲明或類聲明中可見,您可以在其中激活它們。這就是整個目的其中。

在你的情況下,你使用Aer模塊聲明中的細化,這意味着該模塊聲明中的NilClass將有一個to_hash方法。但只有內部的該模塊。並且不是內部的任何其他模塊或類別,包括Hash,其中merge!被定義。

+0

這是我一開始所期望的,但是當我使用細化並且不使用細化時,錯誤是不同的。怎麼會這樣? – Naremy

+0

我的猜測是這是一個實現工件,泄漏了YARV在底層實現細化的私有內部實現細節。 –

+1

但重點是:*整點*的改進是這些猴子補丁* *不可見其他代碼。 –