2016-08-08 11 views
1

私は配列["moniker", @moniker]を持っています。モニカは約100個のインスタンス変数とその文字列表現のいずれかです。私は、インデックス1にあるインスタンス変数が参照しているもの(そのデータ自体ではなく、非常に不変である可能性がある)を変更したい。 array[1] = newDataを実行するだけでは、配列内のwhatsが変更されるため、機能しません。私はこれがC言語では単純だと知っていますが、私はRubyでこれを行う方法を見つけるのに苦労しています。配列内のRubyインスタンス変数を動的に変更します

+1

これは非常に興味深い質問です。それを聞いていただきありがとうございます。 –

答えて

1

あなたの闘争は、あなたがunderlyinにアクセスできるCプログラマーのように思っているからですgポインタ、そしてすべてが変更可能な場所。 Cでは、配列には変更可能な整数へのポインタが格納され、必要に応じて整数を変更できます。 Rubyでは、すべての変数はオブジェクトへの参照であり、の数字は不変オブジェクトです。したがって、@monikerはオブジェクトへの参照で、整数はです。配列を作成すると、その参照が配列にコピーされるので、整数には、@monikerからのものと配列からのものという2つの参照があります。見つけたように、配列内の参照を変更しても、@ monikerという名前の参照は変更されません。オブジェクトはまだです。

「ボックス」配列

参照これは本当に物事のRubyの方法ではありません。 Rubyがどのように参照で動作するかを説明するのに役立つかもしれないので、私はそれを示しています。

あなたは、アレイ内の参照をボックスすることができます

@moniker = [4] 
a = ["moniker", @moniker] 

これは、あなたが基礎となるオブジェクトにアクセスしたいとき、配列を欽慕する必要があります:

@moniker.first 
a[1].first 

をしかし、今あなたが根本的に変更することができます@monikerに整数があり、配列に変更が表示されます。

@moniker[0] = 42 
p a[1].first # => 42 

エンカプセラe可変オブジェクト内の数値。

オブジェクト指向言語であるため、その数値を可変オブジェクトにカプセル化することができます。

class Moniker 
    attr_accessor :value 
    def initialize(value) 
    @value = value 
    end 
end 

attr_accessor :valueは、インスタンス変数@value用リーダライタ方法をビルド)。

@moniker = Moniker.new(4) 
a = ["monikier", @moniker] 
@moniker.value = 42 
p a[1].value # => 42 

明らかに、「値」よりも優れた名前を選択しました。私は値が何を表しているのかわからないのでできませんでした。

これら二つの解決策は、これは、イェルクWミッタークによってコメントだった

動作しますが、それは答えの一部であることを値する理由:

それは明白に見えるかもしれませんが、私は明示的に言及したかったです:2つのソリューションは同じソリューションです。最初のクラスは既存のクラスを汎用のセマンティクスで使用し、2番目のクラスは特定のカプセル化された値に対して正確なセマンティクスを持つ新しいクラスを定義します。しかしどちらの場合も、不変の値を変更可能な値にラップし、「外側の」値を変更することです。

1

@moniker @monikerは決して配列に入りませんでしたが、その価値はありませんでした。 IRBでは

@moniker = 4 
a = ["moniker", @moniker] 
=> ["moniker", 4] 

あなたはちょうどそれを変更するので、とにかく配列の値で作業しているし、あなたが行ってもいいです:

a[1] = 5 
a 
=> ["moniker", 5] 

あなたは検討する必要がありますハッシュ:

h = {:moniker => @moniker} 
=> {:moniker=>4} 

h[:moniker] = 5 
h 
=> {:moniker=>5} 
関連する問題