在此示例中如何设置对节点的引用

how to set references to nodes in this example

当我尝试设置我的图形时,它创建了一个近乎无限的循环,其中每个节点都与其他每个节点保持关系。但我只希望 `nodes.film_actor_hash' 有一个节点名称和对节点的引用。我如何只获得一个引用而不是节点本身?

我应该补充一下,如果你只是将我的代码复制并粘贴到 irb 或 pry 你就会明白我的意思。

class Node
  attr_accessor :name
  attr_accessor :film_actor_hash

  def initialize(name)
    self.name = name
    self.film_actor_hash = {}
  end
end

require_relative 'nodes'
class Graph
  attr_accessor :actors
  attr_accessor :films
  def initialize
    @actors = []
    @films = []
  end
end

graph = Graph.new()

a= Node.new("a")
b= Node.new("b")
c= Node.new("c")
d= Node.new("d")
e= Node.new("e")
f= Node.new("f")
g= Node.new("g")
h= Node.new("h")
i= Node.new("i")
j= Node.new("j")
kevin_bacon= Node.new("kevin_bacon")
l= Node.new("l")
m= Node.new("m")
n= Node.new("n")
o= Node.new("o")
p= Node.new("p")
q= Node.new("q")
r= Node.new("r")
s= Node.new("s")

one = Node.new("one")
two = Node.new("two")
three = Node.new("three")
four = Node.new("four")
five = Node.new("five")
six = Node.new("six")
seven = Node.new("seven")
eight = Node.new("eight")
nine = Node.new("nine")
ten = Node.new("ten")
eleven = Node.new("eleven")
twelve = Node.new("twelve")
thirteen = Node.new("thirteen")
fourteen = Node.new("fourteen")
fifteen = Node.new("fifteen")
sixteen = Node.new("sixteen")
seventeen = Node.new("seventeen")
eighteen = Node.new("eighteen")
nineteen = Node.new("nineteen")

a.film_actor_hash['sixteen'] = sixteen
a.film_actor_hash['one'] = one
b.film_actor_hash['one'] = one
b.film_actor_hash['two'] = two
c.film_actor_hash['two'] = two
c.film_actor_hash['three'] = three
d.film_actor_hash['three'] = three
d.film_actor_hash['four'] = four
e.film_actor_hash['four'] = four
e.film_actor_hash['five'] = five
f.film_actor_hash['five'] = five
f.film_actor_hash['six'] = six
g.film_actor_hash['six'] = six
g.film_actor_hash['seven'] = seven
h.film_actor_hash['seven'] = seven
h.film_actor_hash['eight'] = eight
i.film_actor_hash['eight'] = eight
i.film_actor_hash['nine'] = nine
j.film_actor_hash['nine'] = nine
j.film_actor_hash['ten'] = ten
l.film_actor_hash['ten'] = ten
l.film_actor_hash['eleven'] = eleven
m.film_actor_hash['eleven'] = eleven
m.film_actor_hash['twelve'] = twelve
n.film_actor_hash['twelve'] = twelve
n.film_actor_hash['thirteen'] = thirteen
o.film_actor_hash['thirteen'] = thirteen
o.film_actor_hash['fourteen'] = fourteen
p.film_actor_hash['fourteen'] = fourteen
p.film_actor_hash['fifteen'] = fifteen
kevin_bacon.film_actor_hash['fifteen'] = fifteen
kevin_bacon.film_actor_hash['sixteen'] = sixteen

one.film_actor_hash['kevin_bacon'] = kevin_bacon
one.film_actor_hash['a'] = a
two.film_actor_hash['a'] = a
two.film_actor_hash['b'] = b
three.film_actor_hash['b'] = b
three.film_actor_hash['c'] = c
four.film_actor_hash['c'] = c
four.film_actor_hash['d'] = d
five.film_actor_hash['d'] = d
five.film_actor_hash['e'] = e
six.film_actor_hash['e'] = e
six.film_actor_hash['f'] = f
seven.film_actor_hash['f'] = f
seven.film_actor_hash['g'] = g
eight.film_actor_hash['g'] = g
eight.film_actor_hash['h'] = h
nine.film_actor_hash['h'] = h
nine.film_actor_hash['i'] = i
ten.film_actor_hash['i'] = i
ten.film_actor_hash['j'] = j
eleven.film_actor_hash['j'] = j
eleven.film_actor_hash['l'] = l
twelve.film_actor_hash['l'] = l
twelve.film_actor_hash['m'] = m
thirteen.film_actor_hash['m'] = m
thirteen.film_actor_hash['n'] = n
fourteen.film_actor_hash['n'] = n
fourteen.film_actor_hash['o'] = o
fifteen.film_actor_hash['o'] = o
fifteen.film_actor_hash['p'] = p
sixteen.film_actor_hash['p'] = p
sixteen.film_actor_hash['kevin_bacon'] = kevin_bacon

您的代码实际上工作正常。在Ruby中,"the node itself"其参考。无法直接访问底层对象,因此您的代码只是传递指针。

问题在这里:

I should add if you just copy and paste my code into irb or pry you’ll see what i mean.

当您计算 irb/pry 中的表达式时,Ruby 对结果调用 inspect 并将其打印到控制台。问题是 inspect 是递归的,即当您检查自定义 class 或散列时,它也 inspect 是 class/hash 的内容。由于您的所有对象都通过它们的实例变量相互引用,因此您最终会陷入无限递归循环。我猜 inspect 最终达到堆栈限制并放弃。

观察差异:

sixteen.film_actor_hash.size # 2 elements in the hash
sixteen.film_actor_hash.inspect.size # 18743520 characters in its string representation!

从技术上讲,只要您不需要 inspect 您的对象,就没有什么需要修复的。但是为了理智,你可以重新定义 inspect 不递归:

class Node
  def inspect
    "#<#{self.class}:0x%x #{self.name}>" % object_id
  end
end