4

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
4

3 に答える 3

12

C ++に精通している場合は、Rubyのすべての変数、インスタンスなどを別のオブジェクトへの参照と見なすことができます。Rubyのすべてがオブジェクトでありnil、NilClass型であっても、これはあらゆる状況で当てはまります。

参照しているオブジェクトを判別するには、object_idメソッドを使用して区別することができます。&これは、C++で使用するポインターへの変換に似ています。

このことを考慮:

a = "foo"
b = a

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

aはその文字列への参照でbあり、はのコピーであるためa、実際には同じオブジェクトへの異なる参照です。

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

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

ただし、新しいオブジェクトを作成する操作では、すべてのコピーが変更されるわけではありません。

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

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

通常、割り当てによって古い参照が新しい参照に置き換えられるため、経験則として、=古い参照が置き換えられます。+=これは、、、などに-=適用されます。||=&&=

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

于 2011-12-01T17:44:57.057 に答える
3

すべてがルビーのオブジェクトであるため、割り当ては常に参照によるものです。

したがって、クラスを入力として使用すると、いくつかの操作の出力は次のようになります。

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
于 2011-12-01T17:43:30.463 に答える
1

私はこれを次のように書き直します:

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に設定されたのと同じメモリ位置を参照するだけです。オブジェクトはコピーされません。

于 2011-12-01T17:46:06.423 に答える