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

b1uwtaje  于 2022-12-12  发布在  Ruby
关注(0)|答案(2)|浏览(109)

我遇到了一个问题的解决方案,并且正在努力理解attach_tail!方法。这个Knot.new(self)究竟是如何工作的?一般来说,当你创建一个类的新示例时,它传递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
vuktfyat

vuktfyat1#

这里的self和“初始化类”都没有什么特别之处。
new是与任何其他方法类似的方法,而self所指涉的对象也是与任何其他对象类似的对象。
代替

Knot.new(self)

可能是

Knot.new(baz)

foo.bar(self)

foo.bar(baz)

你只需要调用一个对象上的方法,然后传递另一个对象作为参数,就这样。

eit6fx6z

eit6fx6z2#

从外面看可能更容易。
为了便于演示,我们将attr_reader简单地更改为attr_accessor,以使所有属性都可以从外部设置:

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

  # ...
end

用上式和给定的结a

a = Knot.new

我们可以通过以下方式将尾部附加到a

a.tail = Knot.new(a)

Knot.new(a)会以a做为其head来建立新的节点,然后将新的节点指定给atail
现在,如果你想把这个赋值从对象外部移到对象内部,a必须以某种方式将 * 本身 * 作为参数传递给Knot.new,而这正是self所做的--在示例方法中,self引用当前示例。
外部a

a.tail = Knot.new(a)

内部a

self.tail = Knot.new(self)

如果没有tail=访问器,我们将直接为示例变量赋值:

@tail = Knot.new(self)

这正是attach_tail!所做的。

相关问题