質問するログイン新規登録

回答編集履歴

2

強調追加

2016/03/20 13:25

投稿

raccy
raccy

スコア21784

answer CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  通常であれば、安全なメソッドと破壊的メソッドの両方があるとプログラマーは混乱するでしょう。そこで、Rubyコミュニティでは、同じような動作をするメソッドが二つある場合は、**より危険な方に"!"を付ける**としました。"!"マークで危険ですよと知らせると言うことです。もう気付いた方もいるかも知れませんが、「破壊的メソッドにはすべて"!"が付く」わけでも、「"!"が付いていれば破壊的メソッドである」わけでも**ありません**。`Array#push`は"!"が無いけど破壊的メソッドですし、`Kernel.#exit!`は破壊的メソッドではありません(と言ってもプログラムが終了しますが)。"!"はあくまで通常より危険なメソッドと教えることが目的であり、破壊的変更であることが慣習的に自明なメソッド名(start, close, name=とか)や演算子(<<とか)の場合は付けません。
22
22
 
23
- なお、破壊的メソッドと言っても、引数のオブジェクトを破壊的に変更してしまうようなメソッドのことではありません。そのようなメソッドは**行儀が悪いメソッド**であり、作るべきではないとされています。Rubyは参照の値渡しですので、引数へ副作用を与えることは可能ですが、コードが複雑になり、バグの温床になるため、余程の理由が無い限り避けるべきです。実際に、組み込みライブラリや標準ライブラリにそのようなメソッドはほとんどありません(というより、見つけられませんでした)。
23
+ なお、破壊的メソッドと言っても、引数のオブジェクトを破壊的に変更してしまうようなメソッドのことでは**ありません**。そのようなメソッドは**行儀が悪いメソッド**であり、作るべきではないとされています。Rubyは参照の値渡しですので、引数へ副作用を与えることは可能ですが、コードが複雑になり、バグの温床になるため、余程の理由が無い限り避けるべきです。実際に、組み込みライブラリや標準ライブラリにそのようなメソッドはほとんどありません(というより、見つけられませんでした)。
24
24
 
25
25
  "!"のついでに、似たような慣習として"?"を末尾に付けるがあります。真偽値を返すようなメソッドは"?"を付けるというものです。これは他言語も"isAbc"や"hasAbc"とすると慣習があったりするので、珍しいものではないと思います。
26
26
 

1

文章がおかしいようなきがしたので、修正

2016/03/20 13:25

投稿

raccy
raccy

スコア21784

answer CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ###Rubyの破壊的メソッドをよく知らない人へ
4
4
 
5
- Rubyではほとんどのオブジェクトがmutable(変更可能)です。しかし、最近流行り__らしい__関数型プログラミングでは、オブジェクトがimmutabel(変更不可)であることや、関数が純粋関数(副作用が無く、引数が同じなら、戻り値も常に同じになる関数)であることが重視されつつあります。そんな流行がやってる前から、Rubyではオブジェクトが変更されるのかされないのかが初期の頃から重視されてきました。
5
+ Rubyではほとんどのオブジェクトがmutable(変更可能)です。しかし、最近流行り__らしい__関数型プログラミングでは、オブジェクトがimmutabel(変更不可)であることや、関数が純粋関数(副作用が無く、引数が同じなら、戻り値も常に同じになる関数)であることが重視されつつあります。そんな最近の流行とは**関係な**、初期の頃から、Rubyではオブジェクトが変更されるのかされないのかが重視されてきました。
6
6
 
7
7
  さて、今、文字列を扱っているとします。Rubyで文字列を扱うStringはmutableです。その文字列を全て大文字にした文字列が必要になったとします。Rubyで大文字にするメソッドは`String#upcase`です。では、`upcase`を呼び出した後に元の文字列はどうなるのでしょうか?
8
8
  ```
@@ -18,7 +18,7 @@
18
18
  ```
19
19
  `String#upcase!`はレシーバそのものを大文字に変更します。新しいオブジェクトを生成するわけでは無いため、`String#upcase`より高速です。**1.9より前のとても重いRuby**にとってはこの速度差は無視できないものでした。そのため、安全で副作用がないメソッドと危険だけど速く動くメソッドの二つを用意したのです。このようなレシーバに対して副作用がある(破壊してしまう)メソッドを**破壊的メソッド**と呼びます。破壊的メソッドという言葉はRubyコミュニティ独特の用語ですが、この概念は他の言語でも重要です。
20
20
 
21
- 通常であれば、安全なメソッドと破壊的メソッドの両方があるとプログラマーは混乱するでしょう。そこで、Rubyコミュニティでは、同じような動作をするメソッドが二つある場合は、より危険な方に"!"を付けるとしました。"!"マークで危険ですよと知らせると言うことです。もう気付いた方もいるかも知れませんが、「破壊的メソッドにはすべて"!"が付く」わけでも、「"!"が付いていれば破壊的メソッドである」わけでも**ありません**。`Array#push`は"!"が無いけど破壊的メソッドですし、`Kernel.#exit!`は破壊的メソッドではありません(と言ってもプログラムが終了しますが)。"!"はあくまで通常より危険なメソッドと教えることが目的であり、破壊的変更であることが慣習的に自明なメソッド名(start, close, name=とか)や演算子(<<とか)の場合は付けません。
21
+ 通常であれば、安全なメソッドと破壊的メソッドの両方があるとプログラマーは混乱するでしょう。そこで、Rubyコミュニティでは、同じような動作をするメソッドが二つある場合は、**より危険な方に"!"を付ける**としました。"!"マークで危険ですよと知らせると言うことです。もう気付いた方もいるかも知れませんが、「破壊的メソッドにはすべて"!"が付く」わけでも、「"!"が付いていれば破壊的メソッドである」わけでも**ありません**。`Array#push`は"!"が無いけど破壊的メソッドですし、`Kernel.#exit!`は破壊的メソッドではありません(と言ってもプログラムが終了しますが)。"!"はあくまで通常より危険なメソッドと教えることが目的であり、破壊的変更であることが慣習的に自明なメソッド名(start, close, name=とか)や演算子(<<とか)の場合は付けません。
22
22
 
23
23
  なお、破壊的メソッドと言っても、引数のオブジェクトを破壊的に変更してしまうようなメソッドのことではありません。そのようなメソッドは**行儀が悪いメソッド**であり、作るべきではないとされています。Rubyは参照の値渡しですので、引数へ副作用を与えることは可能ですが、コードが複雑になり、バグの温床になるため、余程の理由が無い限り避けるべきです。実際に、組み込みライブラリや標準ライブラリにそのようなメソッドはほとんどありません(というより、見つけられませんでした)。
24
24