2016-06-22 4 views
2

「goodnight」と表示される理由を説明できる人はいますか?削除した場合Rubyでオブジェクトを呼び出すと文字を変更する

string = "hello" 

"goodnight world"と表示されます。

def a_method(string) 
    string = "hello" 
    string << " world" 
end 

bedtime = "goodnight" 
a_method(bedtime) 

puts bedtime 

私は< <変異していることを理解しますが、=のハローを追加する理由は、このような大きな違いはありませんか?

+2

ruby​​は値渡しであるためです。したがって、メソッド 'a_method'は元の参照を文字列' goodnight 'に変更していません。 – user1875195

+1

あなたの場合は、変更されたバージョンを返すのではなく、オブジェクトを変更する '<<'を使います。あなたのメソッドが代わりに 'string +" world "'を持っていたら、これは起こりません。 –

+0

@ user1875195 'a_method'が文字列' goodnight "に元の参照を変更していない場合、' 'goodnight world" 'は表示されません。 ''世界 ''と ''就寝時間 'を連結することはそれを突然変異させている。 –

答えて

3

Rubyには、の実行中のオペレーションとコピーを返すオペレーションの違いがあります。時々、名前はgsubgsub!のようなヒントを提供しますが、それ以外の時は<<のように知る必要があります。

あなたがここでやっていることは、どのオブジェクトstringが参照するかを再定義しているので、元の参照を永久に変更することはありません。

string = "hello"は、元のbedtimeオブジェクト参照が変更されることを意味しません。

この効果を望む場合は、string.replace("hello")を実行します。これは、文字列のコンテンツのインプレース再割り当てです。

参照するオブジェクトを調べるには、問題のオブジェクトでobject_idを呼び出します。ここでは、値の変更を行うコードではreplaceと表示されています。

Rubyメソッドの引数は、オブジェクト参照によって渡されます。これは実際にはポインタのようなものです。その値が絶対参照で渡されることを期待している場合はそうではありません。

+0

トンに助けてくれてありがとう@タッドマン。 –

+0

この種の私の心を吹き飛ばします。与えられたメソッドが「インプレース」操作であるかどうかを知る方法は?質問のようなコード例を書くことに加えて。 –

+0

@Mikeマニュアルをよく読んで、その説明を注意深く見てください。 ['Array#push'](http://ruby-doc.org/core-2.3.0/Array.html#method-i-push)はインプレースを変更しますが、多くのArrayメソッドは' !おそらく伝統のために、JavaScript、Pythonなどと同じように動作します。他のクラスは、 'gsub'と' gsub! 'のStringのように、その意図についてより明示的です。あなたが確かに分かるまで、文書を読んで確認してください。 – tadman

関連する問題