2

コードを読んで Ruby を学ぼうとしているのですが、どのチュートリアルやチートシートにも載っていない次のような状況に遭遇しました。

def foo!
    # do bar

    return bar  
  end

「!」のポイントは何ですか?メソッド定義で?

4

3 に答える 3

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!、失敗時に例外を発生させる (vssaveは true/false を返しますが、例外は発生させません) のようなものに対して bang-methods を広範囲に使用します。

それは「ヘッズアップ!」です。フラグですが、これを強制するものは何もありません。!人々を混乱させたり怖がらせたりしたい場合は、すべてのメソッドを で終了できます。

于 2013-04-30T14:05:44.850 に答える
1

!は受信者を変更する "bang" メソッドであり、Ruby の慣例です。

bang 以外のメソッドのように機能するバージョンを定義することはできます!が、その場合、他のプログラマーがメソッド定義を見ていない場合、誤解を招く可能性があります。

bang メソッドはnil、レシーバーに変更が加えられていない場合に戻ります。

なしの例!- ソース文字列が変更されていないことがわかります。

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

使用例!- ソース文字列が変更されていることがわかります。

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

注: bang 以外のバージョンのメソッドがいくつかあり、これらもレシーバー オブジェクトを変更できます。

str = "hello"
p str.concat(" world") #=> "hello world"
p str #=> "hello world"
于 2013-04-30T14:01:07.157 に答える
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" 
于 2013-04-30T14:06:03.043 に答える