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
標準ライブラリには、似た名前のメソッドのペアが見つかる場所がたくさんあります!
。含まれていないものは「安全なメソッド」と呼ばれ、コピーに変更が適用された元のコピーが返され、呼び出し先は変更されません。これは同じ例!
です:
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クラスの多くはこれに準拠しています。また、コードで何が変更されているかを追跡するのにも役立ちます。
save
とsave!
中ActiveRecord
感嘆符は多くのことを意味し、「これは危険ですので、注意してください」以外は多くのことを区別できない場合があります。
他の人が言ったように、標準的なメソッドでは、オブジェクトがそれ自体を変異させるメソッドを示すためによく使用されますが、常にそうではありません。多くの標準的な方法は、自分の受信機を変更し、(感嘆符を持っていないことを注意pop
、shift
、clear
)、および感嘆符といくつかの方法が(自分の受信機を変更しないでくださいexit!
)。たとえば、この記事を参照してください。
他のライブラリはそれを異なって使用するかもしれません。Railsでは感嘆符は多くの場合、メソッドがエラーなしで失敗するのではなく、失敗時に例外をスローすることを意味します。
これは命名規則ですが、多くの人が微妙に異なる方法で使用しています。独自のコードでは、特に同じ名前の2つのメソッドが存在し、そのうちの1つが他のメソッドよりも「危険」な場合に、メソッドが「危険」なことをしているときはいつでもそれを使用することをお勧めします。「危険」はほとんど何でも意味します。
1.3.5命名規則
慣例により、常にブール値を返すプロシージャの名前は通常「?」で終わります。このような手続きは述語と呼ばれます。
慣例により、以前に割り当てられた場所(セクション3.4を参照)に値を格納するプロシージャの名前は、通常「!」で終わります。このような手順は突然変異手順と呼ばれます。慣例により、ミューテーションプロシージャによって返される値は指定されていません。
!通常、メソッドは結果を返す代わりにオブジェクトに作用することを意味します。本からRubyのプログラミング:
「危険」なメソッド、またはレシーバーを変更するメソッドには、末尾に「!」が付いている場合があります。
バングのあるメソッドと言うのが最も正確です!より危険なバージョンまたは意外なバージョンです。など、Bangを使用せずに変異するメソッドは多数ありますが.destroy
、一般的には、コアlibに安全な代替手段が存在する場合にのみbangを使用します。
例えば、アレイ上の我々は持っている.compact
と.compact!
、両方の方法は、配列を変化させますが、.compact!
単なる自己を返すよりも驚くべきことである配列、にはゼロのが存在しない場合はリターンは、自己の代わりにnilを。
私はバタンと見つけた唯一の非変異方法があるKernel
の.exit!
を超える驚くべきことである.exit
あなたがキャッチすることはできませんので、SystemExit
プロセスが終了している間。
RailsとActiveRecordはこの傾向を続けており、bangを使用して.create!
、障害発生時にエラーが発生するなど、より「驚くべき」効果をもたらします。
themomorohoax.comから:
bangは、個人的な好みの順に、以下の方法で使用できます。
1)アクティブレコードメソッドは、メソッドが意図したとおりに実行しない場合、エラーを発生させます。
2)アクティブなレコードメソッドがレコードを保存するか、メソッドがオブジェクトを保存する(例:ストリップ!)
3)メソッドは、どこかへの投稿のような「特別な」何かを行うか、または何らかのアクションを行います。
重要なのは、他の開発者がなぜbangを使用しているのかを確認しなければならないという煩わしさをなくすために、本当に必要かどうかを考えたときにのみbangを使用することです。
強打は他の開発者に2つの手がかりを提供します。
1)メソッドを呼び出した後にオブジェクトを保存する必要がないこと。
2)メソッドを呼び出すと、dbが変更されます。
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!
どうしても必要な場合以外は使用しないことをお勧めします。
「破壊的メソッド」と呼ばれる彼らはあなたが参照しているオブジェクトの元のコピーを変更する傾向があります。
numbers=[1,0,10,5,8]
numbers.collect{|n| puts n*2} # would multiply each number by two
numbers #returns the same original copy
numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array
numbers # returns [nil,nil,nil,nil,nil]
結論:!
メソッドは呼び出されたオブジェクトの値を変更するだけですが、メソッドのない!
メソッドは、メソッドが呼び出されたオブジェクトを上書きせずに操作された値を返します。
!
メソッドを呼び出した変数に格納されている元の値を必要としない場合にのみ使用してください。
私は次のようなことをすることを好みます:
foo = "word"
bar = foo.capitalize
puts bar
または
foo = "word"
puts foo.capitalize
の代わりに
foo = "word"
foo.capitalize!
puts foo
元の値に再度アクセスしたい場合に備えて。
!
変更されたコピーを返すのではなく、オブジェクトを変更します。
User.create!