在 Ruby 中,在初始化类时传递 “self” 时它是如何工作的?

In Ruby how does it work when passing "self" when initialising a class?

提问人:Jenny Higgins 提问时间:12/9/2022 更新时间:12/9/2022 访问量:55

问:

我遇到了以下问题的解决方案,并且正在努力理解该方法。这究竟是如何工作的?从一般意义上讲,当你创建一个新的类实例时,它有什么作用?attach_tail!Knot.new(self)

该程序的想法比这更广泛,本质上是关于“结”的头部在网格周围移动,然后是尾部,在类中还有更多我没有包括的方法。

class Knot
  attr_reader :x, :y, :head, :tail

  def initialize(head=nil)
    @x = @y = 0     # Position at the start is 0,0
    @head = head    # Head is passed, but the default is nil
    @tail = nil     # Tail is nil to begin with
  end

  def attach_tail!
    @tail = Knot.new(self)   # Tail can then be added
  end

  def location = [x, y]
end
Ruby 方法 初始化 self

评论

0赞 Cpt.Hook 12/9/2022
这里 self 是当前实例。因此,在这种情况下,构造函数采用一个(父)对象,这是默认的。当您创建一个 (子) 时,您将创建一个新实例,并将当前实例注册为 head(同时将新实例注册为 tail (child) 。这对你有意义吗?headniltail

答:

2赞 Jörg W Mittag 12/9/2022 #1

这里没有什么特别的关于“初始化类”的。self

new是与任何其他方法一样的方法,并且引用的对象与任何其他对象一样是对象。self

而不是

Knot.new(self)

它可能是

Knot.new(baz)

foo.bar(self)

foo.bar(baz)

您只需对一个对象调用一个方法,并将另一个对象作为参数传递。就是这样。

0赞 Stefan 12/9/2022 #2

从外面看可能更容易。

出于演示目的,让我们简要地更改为 attr_accessor,以便使所有属性都可以从外部设置:attr_reader

class Knot
  attr_accessor :x, :y, :head, :tail

  # ...
end

有了上述和给定的结:a

a = Knot.new

我们可以将尾巴连接到 via:a

a.tail = Knot.new(a)

Knot.new(a)创建一个新结,作为其 .然后,它将该新结分配给 的 。aheadtaila

现在,如果要将该赋值从对象外部移动到对象中,则必须以某种方式将自身作为参数传递给 。而这正是 – 在实例方法中,指的是当前实例。aKnot.newselfself

外面:a

a.tail = Knot.new(a)

里面:a

self.tail = Knot.new(self)

如果没有访问器,我们将直接分配给实例变量:tail=

@tail = Knot.new(self)

这正是它的作用。attach_tail!