質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

2回答

3067閲覧

Rubyの replace メソッド

valin

総合スコア8

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2014/11/15 16:25

Rubyのreplace() は何のためにあるのでしょうか?
http://docs.ruby-lang.org/ja/2.0.0/class/String.html#I_REPLACE

マニュアルを読むと以下のように書いてあります

lang

1str = "foo" 2str.replace "bar" 3p str # => "bar"

これは 以下となにが違うのでしょうか?

lang

1str = "foo" 2str = "bar" 3p str # => "bar"

replace を使わなければいけないような状況はあるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

replace! はついてませんが 破壊的メソッド です。
これはオブジェクトを共有している時に変化が出てきます。

例えば、次のように定義すると str, str2 は同じオブジェクトを指します。

lang

1str = str2 = "foo" 2# str → "foo" ← str2

ここで replace を使わない場合は、 新しいオブジェクトを作り str が指しているオブジェクトを変える ので、 str2 の方は変化しません。

lang

1str = str2 = "foo" 2str = "bar" 3p str # "bar" 4p str2 # "foo" 5 6# "foo" ← str2 7# str → "bar"

しかし、 replace を使うと、 オブジェクトの中身を変える ので、 str2 の方も変化します。

lang

1str = str2 = "foo" 2str.replace("bar") 3p str # "bar" 4p str2 # "bar" 一緒に変わる 5 6# str → "bar" ← str2

そのため、あえて変数を共有しているという場合は、 replace を使う必要があります。
ただし、基本的に破壊的メソッドの使用は避けるべきなので、 そういう状況にはしない方がいいです。

cf. Ruby 破壊的メソッドについて詳しく教えてください。| teratail
cf. 配列のコピーについて| teratail

投稿2014/11/17 06:48

yohshiy

総合スコア863

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2014/11/18 16:26

> 基本的に破壊的メソッドの使用は避けるべき そんなことはありませんので、必要に応じて使ってください。 必要性がわからなければ使わなくてもいいですが。
yohshiy

2014/11/19 02:05

そんなことない、ことはないです。 一度作成したオブジェクトは変更しない方が、わかりやすく、安全性の高いコードになります。特に並列処理での安全性が上がります。 実際、 そのような理由から .NET, Java, JavaScript などでは、文字列オブジェクトは不変です。 ただ、効率を考えると、オブジェクトを変えた方がよくなります。 例えば、長い文字列の場合 chop と chop! では効率が全然違います。 しかし、 Ruby は Lisp 色が強く、書きやすさを重視した言語です。 効率よりも、わかりやすく、関数型的な方が Ruby としては良いプログラミングだと思います。 これが C, C++ などの質問であれば、私も別のアドバイスをしたと思います。 少なくとも、初心者に積極的に勧める類のものではありません。
otn

2014/11/20 11:24

なるほど。Stringオブジェクトに限定した話だったんでしょうか?そうは読み取れず失礼しました。ただ、今後回答を見る人のことも考えて、「Stringオブジェクトについては~」と編集しておいた方がいいと思います。 Stringオブジェクトに限定した話であれば、「初心者のうちは、破壊的メソッドを使うとバグを生みやすいので避けた方がいい」という指導はありだと思います。 いずれはArrayやHash等でエイリアシングによる予期せぬ副作用に直面すると思うので、そのときに改めて学べば良いということでしょうかね。ArrayやHashその他で破壊的メソッドを避けてプログラミングするのは現実的でないので。 私なら、「避けた方がいい」じゃなくて「十分考えて使え」と指導しますが。
yohshiy

2014/11/21 02:19

別に文字列オブジェクトに限定したつもりはありません。文字列オブジェクトはあくまで例です。 文字列オブジェクトが不変な方がいいということが本当に理解で聞いているのであれば、同じことが他のオブジェクトにも言えることはわかると思います。 もちろん、 Ruby は関数型言語ではないので、すべてのオブジェクトを不変にするのは難しいです。 破壊的メソッドを使ってはいけないではなく、使うべきじゃないと書いているのは、基本的な方針としてオブジェクトは不変にしておいた方がいいという意図です。 破壊的メソッドを使うか使わないかがわからない、迷うぐらいであれば、そこは使うべきじゃないですし、 使わないと書けないのであれば、何も言わなくても使うはずです。 質問の回答として、 replace の動作の違いをメインにし、破壊的メソッドの方針は一言にとどめています。 そこで長々と説明しても話がぼやけるだけです。なんで と興味をもってもらったのであれば、追加で質問があるはずですし、その時ちゃんと答えればよいと思ってました。 > そんなことはありませんので、必要に応じて使ってください。 > 必要性がわからなければ使わなくてもいいですが。 という書き方は、ちょっと小バカにしたような印象を受けるので、それよりは言葉足らずにしておいた方が追加で質問をしやすいと思います。
otn

2014/11/21 12:08

>破壊的メソッドを使うか使わないかがわからない、迷うぐらいであれば、そこは使うべきじゃないですし、 >使わないと書けないのであれば、何も言わなくても使うはずです。 適材適所で使えば良いと言うことですよね。であれば、賛成です。 オブジェクトを書き換える方法をとるべきか、書き換えない方法をとるべきか迷うのなら書き換えないというのも賛成です。迷わないならいくらでも書き換えればいい。 「基本的に避けるべき」は書き方が悪すぎです。 言葉足らずと受け取る人ばかりでは無い。真に受ける人がいなければいいのですが。
yohshiy

2014/11/22 02:26

言っていることは近いのですが、私は破壊的メソッドの使用はどうしても使わざるをえないときだけで、なるべくオブジェクトを不変にすることを重視しています。 設計、コーディングのやり方により、ある程度不変に保っておくことは可能です。 - http://www.h6.dion.ne.jp/~machan/misc/FPwithRuby.html 書き方の問題ではなく、オブジェクトの不変にしておくことの重要性に対して考え方に違いがあるのだと思います。 それについて、これ以上続けても宗教戦争になってくるので、この辺でやめておきます。
otn

2014/11/23 00:31

考え方の違いは少ないと思いますよ。言い方の問題が大きいです。 「基本的に破壊的メソッドの使用は避けるべき」でなく、 「オブジェクトを書き換えるとデバッグが難しくなりバグの元なので、書き換えずにプログラムが書けるならそれに越したことは無い」あたりでしょうか。freezeに触れるとなお良いでしょう。 そこまで長く書くつもりが無いのであれば、最初から言わない方がいい。 「基本的に破壊的メソッドの使用は避けるべき」と書いたときの懸念点は、 再掲ですが、 > 言葉足らずと受け取る人ばかりでは無い。真に受ける人がいなければいいのですが。 「なんかしらんけど、~~~と書いてあった」と思考停止に陥る若者は少なからずいます。
guest

0

replace は新しいインスタンスを割り当てるのではなく、現在のインスタンスを変更します。以下

replaceを使う場合

lang

1a = 'old' 2b = a 3b.replace('new') 4a 5# => "new"

replaceを使わない場合

lang

1a = 'old' 2b = a 3b = 'new' 4a 5# => "old

投稿2014/11/17 02:30

yokohama3

総合スコア105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問