2011-04-29 62 views
5
def moo 
    puts "moo" 
end 

moo.moo.moo.moo 

這給爲什麼紅寶石的方法有自身的方法

moo 
moo 
moo 
moo 

只是一個怪胎,我很好奇,如果這是故意的,並擔任一些目的...

+1

我只是嘗試這樣在IRB和我沒有得到同樣的結果。你如何編寫這個腳本,你如何執行它? – Mario 2011-04-29 20:52:40

+0

哪個版本的紅寶石?你還有什麼東西是壓倒一切的東西嗎?因爲如果我在1.9.2-p180上嘗試它,我會得到'NoMethodError:私有方法'moo'調用nil:NilClass' – Doon 2011-04-29 20:55:08

+0

@Mario在IRB中,Ruby 1.8.7 - 不確定是否有特殊的方法來執行它; ) – npiv 2011-04-29 21:09:20

回答

5

我猜你正在做的,在控制檯上,所以你實際上在Object上定義方法,然後在Object的所有孩子中定義方法......這就是一切。所以,你的方法:

def moo 
    puts "moo" 
end 

返回nil,因爲你在Object定義的方法,NilClass有法爲好,這樣你就可以打電話NilClassmoo

如果你這樣做:

class Foo 
    def bar 
    1 + 1 
    end 
end 

然後:

f = Foo.new 
f.bar.bar 

你得到:

NoMethodError: undefined method `bar' for 2:Fixnum 
+0

真棒答案,謝謝!這是特定於我的版本嗎,還是在1.9 IRB中仍然一致? – npiv 2011-04-29 21:08:11

+4

它改變了'1.9'。 '1.9'中的'irb'實際上將該方法定義爲'main'上的私有實例方法,它是'irb'運行的對象。 – jaredonline 2011-04-29 21:14:15

+1

另外,你在'irb 1.9'中的方法也會返回一個'String'的實例,它沒有定義它的'moo'方法,所以你會得到'NoMethodError'。 – jaredonline 2011-04-29 21:15:01

0

puts "moo"回報nil。來自範圍的方法可以用於下面的任何範圍。由於moo處於最佳範圍內,所有對象都可以調用它:

"teste".moo # => prints "moo" 

如果你不希望這樣,讓moo私人:

private :moo 
moo # => ok 
nil.moo # => NoMethodError 
moo.moo # => prints once and raise NoMethodError 
0

這不應該工作。

您正在將moo定義爲「主」對象上的方法。調用moo應該可以工作,但是你的方法返回nil(因爲puts返回nil)。你沒有定義NilClass#moo,所以moo.moo應該會失敗,對我來說也是如此。

+0

這很有趣。我得到一個'私有方法'moo',調用nil:NilClass' 錯誤,而不是像我期望的那樣'nil:NilClass'的'未定義方法'moo'。 – steenslag 2011-04-29 21:02:00

+0

@steenslag耶,我也是。不知道那裏發生了什麼。 – noodl 2011-04-29 21:03:46

+4

他沒有將moo定義爲主對象上的方法(這將是'def self.foo'),他將其定義爲Object上的私有實例方法。無論哪種方式'moo.moo'仍然不應該工作。然而,在紅寶石1.8的irb中存在不一致性,這使得「全局」定義的方法公開而不是私有的(在irb中,而不是在普通的ruby中),這就解釋了爲什麼OP會看到他所看到的行爲。 – sepp2k 2011-04-29 21:03:51

1

也許你正在定義Object類的東西。因爲Ruby中的所有內容都是Object,並且每個方法都返回一些內容(默認爲nil),所以您可以根據自己的結果調用該方法。 moo方法返回nil,所以你在做的是先調用moo首先在全局對象上,然後再返回每個nil

您可以更明確地做到這一點:

class Object 
    def moo 
    puts 'moo' 
    end 
end 

如果您一般要鏈的方法,你可以試試這個:

class Mooer 
    def moo 
    puts 'moo' 
    self 
    end 
end 

a = Mooer.new 
a.moo.moo.moo.moo.inspect