Ruby では、問題のオブジェクトが含まれているかどうかを尋ねるような疑問符 ( ?) を持つメソッドがいくつかinclude?あり、これは true/false を返します。
しかし、感嘆符 ( !) が付いているメソッドと付いていないメソッドがあるのはなぜでしょうか?
どういう意味ですか?
Ruby では、問題のオブジェクトが含まれているかどうかを尋ねるような疑問符 ( ?) を持つメソッドがいくつかinclude?あり、これは true/false を返します。
しかし、感嘆符 ( !) が付いているメソッドと付いていないメソッドがあるのはなぜでしょうか?
どういう意味ですか?
一般に、 で終わるメソッドは、メソッドが呼び出されたオブジェクトを変更する!ことを示します。Ruby はこれらを「危険なメソッド」と呼んでいます。これは、他の誰かが参照している可能性のある状態を変更するためです。文字列の簡単な例を次に示します。
foo = "A STRING" # a string called foo
foo.downcase! # modifies foo itself
puts foo # prints modified foo
これは出力されます:
a string
標準ライブラリには、似たような名前のメソッドのペア (1 つは あり、もう 1 つはなし) が見られる場所がたくさんあります!。ないものは「安全なメソッド」と呼ばれ、コピーに変更が適用され、呼び出し先が変更されていない元のコピーを返します。を除いた同じ例を次に示し!ます。
foo = "A STRING" # a string called foo
bar = foo.downcase # doesn't modify foo; returns a modified string
puts foo # prints unchanged foo
puts bar # prints newly created bar
これは以下を出力します:
A STRING
a string
これは慣例にすぎませんが、多くの Ruby クラスがこれに従っていることに注意してください。また、コード内で何が変更されているかを追跡するのにも役立ちます。
感嘆符には多くの意味があり、「これは危険です、注意してください」以外に多くのことが分からない場合があります。
他の人が言ったように、標準的なメソッドでは、オブジェクトがそれ自体を変化させるメソッドを示すためによく使用されますが、常にではありません。多くの標準メソッドはレシーバーを変更し、感嘆符 ( pop、shift、clear) を持たないことに注意してください。また、感嘆符を含む一部のメソッドはレシーバーを変更しません ( exit!)。たとえば、この記事を参照してください。
他のライブラリでは、別の方法で使用される場合があります。Rails では、感嘆符は、多くの場合、メソッドが失敗時に暗黙のうちに失敗するのではなく、例外をスローすることを意味します。
これは命名規則ですが、多くの人が微妙に異なる方法で使用しています。独自のコードでは、メソッドが何か「危険」なことをしている場合、特に同じ名前のメソッドが 2 つ存在し、そのうちの 1 つが他のメソッドよりも「危険」である場合はいつでも、これを使用することをお勧めします。ただし、「危険」はほとんど何でも意味します。
この命名規則はSchemeから削除されました。
1.3.5命名規則
慣例により、常にブール値を返すプロシージャの名前は通常、「?」で終わります。このような手順は述語と呼ばれます。
慣例により、以前に割り当てられた場所(セクション3.4を参照)に値を格納するプロシージャの名前は、通常、「!」で終わります。このような手順は、突然変異手順と呼ばれます。慣例により、ミューテーションプロシージャによって返される値は指定されていません。
! 通常、メソッドが結果を返すのではなく、オブジェクトに作用することを意味します。プログラミングRubyという本から:
「危険」なメソッドやレシーバーを変更するメソッドは、末尾に「!」が付く可能性があります。
より:
私の個人的な好みの順序で、次の方法で前髪を使用できます。
1) アクティブ レコード メソッドは、メソッドが要求したことを実行しない場合、エラーを発生させます。
2) アクティブなレコード メソッドがレコードを保存するか、メソッドがオブジェクトを保存します (例: strip!)
3) メソッドは、どこかに投稿したり、何らかのアクションを実行したりするなど、「余分な」ことを行います。
ポイントは、他の開発者が bang を使用している理由を確認しなければならないという煩わしさを避けるために、必要かどうかを本当に考えたときにのみ bang を使用することです。
強打は、他の開発者に 2 つの手がかりを提供します。
1) メソッドを呼び出した後にオブジェクトを保存する必要がないこと。
2) メソッドを呼び出すと、データベースが変更されます。
http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-rails-methods
簡単な説明:
foo = "BEST DAY EVER" #assign a string to variable foo.
=> foo.downcase #call method downcase, this is without any exclamation.
"best day ever" #returns the result in downcase, but no change in value of foo.
=> foo #call the variable foo now.
"BEST DAY EVER" #variable is unchanged.
=> foo.downcase! #call destructive version.
=> foo #call the variable foo now.
"best day ever" #variable has been mutated in place.
ただし、downcase!上記の説明でメソッドを呼び出した場合は、foo永久に小文字に変更されます。downcase!新しい文字列オブジェクトを返すのではなく、文字列をその場で置き換え、完全に小文字に変更しfooます。絶対に必要な場合を除き、使用しないことをお勧めしますdowncase!。
!
私はこれを、これまでのすべてを破壊する爆発的な変化だと考えています。感嘆符または感嘆符は、コードに永続的に保存された変更を加えていることを意味します。
たとえば、グローバル置換gsub!に Ruby のメソッドを使用すると、作成した置換は永続的になります。
想像できるもう 1 つの方法は、テキスト ファイルを開き、検索と置換を行ってから保存することです。!コードで同じことを行います。
あなたがbashの世界から来た場合のもう1つの便利なリマインダーsed -iは、永続的に保存された変更を作成するという同様の効果があることです。
結論:!メソッドは呼び出されたオブジェクトの値を変更するだけですが、メソッドを持たない!メソッドは、メソッドが呼び出されたオブジェクトを上書きせずに、操作された値を返します。
!メソッドを呼び出した変数に格納されている元の値を必要としない場合にのみ使用してください。
私は次のようなことをすることを好みます:
foo = "word"
bar = foo.capitalize
puts bar
また
foo = "word"
puts foo.capitalize
それ以外の
foo = "word"
foo.capitalize!
puts foo
元の値に再度アクセスしたい場合に備えて。