質問

C ++の背景から来て、Rubyのオブジェクトの割り当てに興味があります。次のオブジェクトの割り当てに対して、どのような考慮事項を作成する必要がありますか:

class MyClass

  attr_accessor :a, :b

  def initialize(a, b)
    @a = a
    @b = b
  end

  def some_method
    puts "#{self.a} #{self.b}"
  end
end

m = MyClass.new("first", "last")
n = MyClass.new("pizza", "hello")

q = n
q.some_method
役に立ちましたか?

解決

C ++に精通している場合は、別のオブジェクトへの参照として、Ruby、インスタンス、またはその他のすべての変数を考慮することをお勧めします。 Rubyのすべてがオブジェクトであるためです nil, 、これはタイプのニルクラスですが、これはあらゆる状況下で真実です。

参照しているオブジェクトを決定するには、 object_id 区別する方法。これは、使用を使用してポインターに変換することに似ています & C ++で。

このことを考慮:

a = "foo"
b = a

a.object_id == b.object_id
# => true

以来 a その文字列への参照です b のコピーです a, 、その後、それらは実際には同じオブジェクトへの異なる参照です。

オブジェクトを変更する操作は、それを等しくすべての参照に影響するため、これは重要です。

a << "bar"
# => "foobar"
b
# => "foobar"

ただし、aを作成する操作 新着 オブジェクトはすべてのコピーを変更しません:

a += "baz"
# => "foobarbaz"
b
# => "foobar"

Rubyの多くの方法は、aによって識別されます ! インプレースバージョンと新しいコピーバージョンを区別するには、常にそうであるとは限らないため、確かに各方法に精通している必要があります。

通常、割り当ては古い参照を新しいものに置き換えます。これにより、経験則として、 = 古い参照を置き換えます。これはに適用されます +=, -=, ||=, &&= 等々。

編集: 使用に関するPhrogzのコメントに基づいて更新されました ObjectSpace._id2ref(object_id) オブジェクト識別子をオブジェクトに変換します。

他のヒント

すべてがRubyのオブジェクトであるため、割り当ては常に参照されます。

したがって、クラスを入力として取得すると、以下はいくつかの操作の出力になります。

str = "foo"
foo = MyClass.new(str, "bar")
foo.some_method # foo bar
bar = foo
bar == foo # true
bar.some_method # foo bar
str << "bar" # strings are mutable on ruby, so str is now "foobar"
foo.some_method # foobar bar
bar.some_method # foobar bar

これを書き換えます:

class MyClass

  attr_accessor :a, :b

  def initialize(a, b)
    self.a = a
    self.b = b
  end

  def some_method
    puts "#{a} #{b}"
  end
end

これにより、実際に定義されたゲッター/セッターメソッドを使用しています attr_accessor あなたのクラス内

割り当てるとき q = n, 、q nに設定された同じメモリの位置を参照してください。オブジェクトはコピーされていません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top