Ruby 中的对象赋值

发布于 2024-12-19 02:21:38 字数 322 浏览 0 评论 0原文

来自 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

Coming from a c++ background I'm curious about object assignment in Ruby. What considerations (if any) should be made for the following object assignments:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ゃ人海孤独症 2024-12-26 02:21:38

如果您熟悉 C++,那么您可能需要将 Ruby 中的每个变量、实例或其他变量视为对另一个对象的引用。由于 Ruby 中的所有内容都是对象,甚至是 NilClass 类型的 nil,因此这在任何情况下都适用。

要确定您引用的对象,可以使用 object_id 方法来区分。这类似于在 C++ 中使用 & 转换为指针。

考虑一下:

a = "foo"
b = a

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

由于 a 是对该字符串的引用,而 ba 的副本,因此它们实际上是对同一字符串的不同引用目的。

这很重要,因为修改对象的操作会同等影响对该对象的所有引用:

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

但是,创建对象的操作不会修改所有副本:

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

Ruby 中的许多方法都由 !< 标识/code> 来区分就地版本和新副本版本,但情况并非总是如此,因此您必须熟悉每种方法才能确定。

通常,分配会将旧引用替换为新引用,因此根据经验,= 将替换旧引用。这适用于 +=-=||=&&= 等。

编辑:根据 Phrogz 关于使用 ObjectSpace._id2ref(object_id) 将对象标识符转换为对象的评论进行了更新。

If you're familiar with C++, then you might want to consider every variable in Ruby, instance or otherwise, as a reference to another object. Since everything in Ruby is an object, even nil, which is of type NilClass, this holds true under every circumstance.

To determine which object you're referencing, you can use the object_id method to differentiate. That's similar to converting to a pointer using & in C++.

Consider this:

a = "foo"
b = a

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

Since a is a reference to that string, and b is a copy of a, then they are actually different references to the same object.

This is important because operations that modify an object affect all references to that equally:

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

However, operations that create a new object will not modify all copies:

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

Many methods in Ruby are identified by a ! to distinguish in-place versus new-copy versions, but this is not always the case, so you have to be familiar with each method in order to be sure.

Generally an assignment will replace an old reference with a new one, so as a rule of thumb, = will replace old references. This applies to +=, -=, ||=, &&= and so on.

Edit: Updated based on Phrogz's comment about using ObjectSpace._id2ref(object_id) to convert an object identifier into an object.

笨死的猪 2024-12-26 02:21:38

由于 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

Since everything is an object in ruby, assignment is always by reference.

So, taking your class as an input, the following will be the output for several operations:

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
夏末的微笑 2024-12-26 02:21:38

我将其重写为:

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 定义的 getter/setter 方法

当您分配 q = n 时,q 只是引用相同的方法为 n 设置的内存位置。该对象未被复制。

I would rewrite this as:

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

This way you're actually using the getter/setter methods defined by attr_accessor within your class

When you assign q = n, q just references the same memory location that was set for n. The object isn't copied.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文