2013-03-28 55 views
4

我想寫一個或幫助器(基於Not Method by Jay Fields)。我想實現的是:Ruby:訪問方法鏈中的調用方

s = "" 
s.nil?    # false 
s.empty?   # true 
s.nil? || s.empty? # true 
s.nil?.or.empty? # should == true 

我可以訪問的nil?的結果,但不是什麼輸入nil?了。

我得到:

NoMethodError: undefined method `empty?' for false:FalseClass 

這甚至可能嗎?

注意:這需要是原生ruby 不是軌道!

+0

我想我已經完成了,如果您有任何困惑,請查看答案和評論。 –

回答

1

你不能做到這一點。

s.nil?返回值是truefalse,它們是分別TrueClassFalseClass,唯一的實例。您不能創建這兩個類的其他實例。所以你不能猴子補丁TrueClassFalseClass記住上下文s。您可以在truefalse上定義單身方法or,但是它對s一無所知,因此您無法鏈接另一個謂詞empty?

def true.or other 
    true 
end 

def false.or other 
    other 
end 

您可以用定義的兩個輔助方法編寫s.nil?.or(s.empty?)

另一個想法是返回所有謂詞(blabla?)方法的自定義對象,而不是truefalse。然而,在紅寶石中,只有nilfalse產生錯誤,其他任何東西都會產生錯誤。自定義對象的實例將始終爲真,這將打破所有這些謂詞方法。

0

試試這個

p RUBY_VERSION 
p s = "" 
p s.nil?    
p s.empty?   
p s.nil? || s.empty? 
p (s.nil? or s.empty?) 

輸出:

"2.0.0" 
"" 
false 
true 
true 
true 

說明:

s.nil? 
#=> false 

s.nil?.or.empty? 
#NoMethodError: undefined method `or' for false:FalseClass 
#  from (irb):5 
#  from C:/Ruby200/bin/irb:12:in `<main>' 

因爲s.nil?上述錯誤給falsefalseFalseClass的一個實例,並且此類沒有or方法。所以實際的修復如上所示。

編輯

p RUBY_VERSION 
class Object 

alias :oldnil :nil? 

    def nil? 
    @@x = self 
    oldnil 
    end 
end 

class FalseClass 
    def or 
    empty? 
    end 

    def empty? 
    @@x.empty? 
    end 
end 

class TrueClass 
    def or 
    empty? 
    end 

    def empty? 
    @@x.empty? 
    end 
end 

s = "" 
p s.nil? 
p s.empty? 
p s.nil? || s.empty? 
p s.nil?.or.empty? 

輸出:

"2.0.0" 
false 
true 
true 
true 
+0

這適用於這種特定的條件組合。我認爲jamlen對更通用的解決方案感興趣。此外,它不是線程安全的。 –