3

したがって、どうやらルビーはパスバイ参照言語のようです。

$ irb --simple-prompt 
>> @foo=1
=> 1
>> @bar=2
=> 2
>> @foo.object_id
=> 3
>> @bar.object_id
=> 5
>> [@foo,@bar].each {|e| puts e.object_id }
3
5
=> [1, 2]

つまり、構築された配列とブロックの両方が、元のクラス インスタンス変数オブジェクトへの参照を処理しているように見えます。

ただし、これらの参照は、書き込みを試みるとすぐにコピーを作成するようです。

>> [@foo,@bar].each {|e| puts e+=1 }
2
3
=> [1, 2]
>> @foo
=> 1
>> @bar
=> 2
>> [@foo,@bar].map! {|e| e+1 }
=> [2, 3]
>> @foo
=> 1
>> @bar
=> 2

関数を介して変換する必要があるクラスインスタンス変数オブジェクトがいくつかあったので、参照渡しを利用してキーストロークを節約し、次のようにすることにしました。

[@var1, @var2, @var3].map! {|v| my_function(v) }

しかし、このコピーオンライトが進行しているように見えるため、機能していないようです。

オフにする方法はありますか?コードを DRY と効率の両方を同時に維持しながら、どのように私を達成しますか?

4

3 に答える 3

3

Ruby は常に値渡しです。しかし、場合によっては、この値はポインターです (参照渡しと考える人もいると思います)。

編集:

Arup の回答に基づいて、一部の ivar のみを処理するバージョンを次に示します。

[:@foo, :@bar].each do |var| 
  instance_variable_set(var, myfunction(instance_variable_get(var)))
end
于 2013-11-21T19:43:47.433 に答える
2

これはあなたが探しているものですか?

@foo = 1
@bar = 2
instance_variables.each do |var| 
  instance_variable_set(var,instance_variable_get(var)+1)
end
@foo # => 2
@bar # => 3
于 2013-11-21T19:35:50.780 に答える
1

Ruby は値渡しのみです。Ruby には参照渡しはありません。Ruby のすべての値はリファレンス(オブジェクトへのポインター) です。@fooオブジェクトへのポインタ、オブジェクト@barへのポインタ、オブジェクトへのポインタなども同様です。Ruby@foo.object_idでは「オブジェクト」は値ではありません。Ruby のすべての値は、値によって渡されるか、割り当てられます。

コードの最初の部分では、各参照が指すオブジェクトのメソッドにアクセスしています。参照を渡すか割り当てると、参照の新しいコピーが作成されますが、もちろん元の参照と同じオブジェクトを指します。

コードの 2 番目の部分では、参照のローカル コピーに代入して、別のものを指すようにしています。もちろん、これは元のスコープの参照が指しているオブジェクトを変更しません。

于 2013-11-25T09:31:38.670 に答える