2013-04-30 167 views
2

我試圖通過閱讀代碼來學習Ruby,但是我遇到了以下情況,這是我在任何教程/作弊表中找不到的。是什麼!是指在Ruby方法定義的末尾?

def foo! 
    # do bar 

    return bar 
    end 

「!」是什麼意思?在方法定義中?

+0

在// Ruby方法定義體的開始處,// //是什麼意思? – sawa 2013-04-30 14:28:44

回答

11

Ruby不會將!視爲方法名稱末尾的特殊字符。按照慣例,以!結尾的方法會產生某種副作用或方法作者試圖引起注意的其他問題。示例是可以進行就地更改的方法,或者可能會引發異常,或者不顧警告而繼續執行操作的方法。

例如,這裏是如何String#upcase!比較String#upcase

1.9.3p392 :004 > foo = "whatever" 
=> "whatever" 
1.9.3p392 :005 > foo.upcase 
=> "WHATEVER" 
1.9.3p392 :006 > foo 
=> "whatever" 
1.9.3p392 :007 > foo.upcase! 
=> "WHATEVER" 
1.9.3p392 :008 > foo 
=> "WHATEVER" 

的ActiveRecord大量使用爆炸的方法對於像save!,這引起了對失敗的異常(VS save,返回true/false,但不會引發例外)。

這是一個「擡頭!」國旗,但沒有什麼可以強制這一點。如果你想混淆和/或嚇唬人,你可以在!結束你的所有方法。

+0

可能要添加一個需要注意的是'!'方法往往有不同的返回值(最明顯的是'nil'當什麼也沒發生變化),這可能會導致意外和微妙的錯誤。 – 2013-04-30 14:29:21

1

!是一個「爆炸」的方法,它改變了接收器,並且是Ruby中的慣例。

你可以定義一個!版本,它可能像非重載方法一樣工作,但如果他們沒有看你的方法定義,那麼它會誤導其他程序員。

bang方法反過來返回nil當沒有更改接收器。沒有!

例子 - 你可以看到,源字符串尚未改變:

str = "hello" 
p str.delete("l") #=> "heo" 
p str #=> "hello" 

例子與! - 你可以看到,源字符串已經改變:

str = "hello" 
p str.delete!("l") #=> "heo" 
p str #=> "heo" 

注意:有一些非爆炸版本的方法,它也可以改變接收器對象:

str = "hello" 
p str.concat(" world") #=> "hello world" 
p str #=> "hello world" 
+0

謝謝,它是有道理的,所以它只是一個紅寶石約定:D – 2013-04-30 14:03:09

+0

爆炸本身不被使用。當有非爆炸選擇時,它會被使用。 http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist – thomthom 2013-04-30 14:19:39

+0

@thomthom我知道,我在那裏提到什麼錯?指向我那裏,我會糾正。 – 2013-04-30 14:21:09

0

!不是方法的定義,但是,當你聲明的方法的約定使用,此方法將變化的對象。

1.9.3-p194 :004 > a="hello " 
=> "hello " 
1.9.3-p194 :005 > a.strip 
=> "hello" 
1.9.3-p194 :006 > a 
=> "hello " 
1.9.3-p194 :007 > a.strip! 
=> "hello" 
1.9.3-p194 :008 > a 
=> "hello" 
相關問題