既存の文字列に追加する


104

既存の文字列に追加するには、これが私がやっていることです。

s = 'hello'
s.gsub!(/$/, ' world');

既存の文字列に追加するより良い方法はありますか?

誰かが次の回答を提案する前に、これは機能しないことを示します

s = 'hello'
s.object_id
s = s + ' world'
s.object_id 

上記の場合、object_idは2つの場合で異なります。

回答:


166

を使用<<して、文字列にインプレースで追加できます。

s = "foo"
old_id = s.object_id
s << "bar"
s                      #=> "foobar"
s.object_id == old_id  #=> true

1
どうやって<<!「バー」、オブジェクトの状態を変更するように?concat!( "bar")が機能しません...
xxjjnn

@RainbowPony私の答えが示すように、<<すでにオブジェクトの状態を変更しています。そうconcatです。
sepp2k

常にではない:irb(main):038:0> widget.notes.where(:author_id => a).first.message.concat( "Potato")=> "Y halo thar!= DPotato" irb(main): 039:0> widget.notes.where(:author_id => a).first.message => "Y halo thar!= D"#ウィジェットはウィジェットのインスタンスです。メモを付けることができます。メッセージはattr_accessibleです。
xxjjnn

1
@RainbowPonyはい、いつも。あなたの場合、widget.notes.where(:author_id => a).firstおそらく毎回新しいオブジェクトを返すため、変更されていない文字列が返されます。これには、独自の独立した文字列があります。
sepp2k

ああ。新しい質問をしました。stackoverflow.com/ questions / 13989619 / …助けてくれてありがとう!
xxjjnn

56

次のものも使用できます。

s.concat("world")

4
<<文字列を返すので、同様にチェーン可能でなければなりません。
scottysseus

確かに-そして<<も書くには短く、C ++ coutバリアントに似ています。<<美しさです!
シェビー

1
注:これにより、元の文字列が変更されます。慎重に使用してください。
ダミアンロッシュ

3

なぜこれが重要なのでしょうか。

これはあなたの質問への直接の答えではないことを知っていますが、文字列のオブジェクトIDを保持しようとしているという事実は、あなたがしようとしていることをもう一度見直す必要があることを示すかもしれません。

たとえば、文字列のオブジェクトIDに依存すると、追跡が非常に困難なバグが発生することがあります。


4
参照によってパラメータを変更するのでしょうか?(これは、本格的なoop言語ではおそらく悪い設計です)
hurikhan77

4
それとも、新しいオブジェクトの作成が多すぎないようにするだけですか?それは完全に合理的です。
ジェームズA.ローゼン

1
文字列を適切に変更して新しいオブジェクトが作成された場合、古いオブジェクトはガベージコレクションされますか?作成するStringオブジェクトの数を本当に心配する必要がありますか?
Shadowfirebird 2010年

@Shadowfirebird多分彼は毎秒数千回呼び出されるメソッドを書いていて、文字列の束でガベージコレクターを悩ませたくありません。
マイケルドースト2013


1

ここに別の方法があります:

fist_segment = "hello,"
second_segment = "world."
complete_string = "#{first_segment} #{second_segment}"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.