ruby:获得来电课程

时间:2016-04-20 12:17:07

标签: ruby recursion

您好我的数据结构存在一些问题。 让我们想想一个有很多孩子的男人,但一个孩子只能有一个父亲。所以孩子知道他的父亲,而父亲知道他所有的孩子。 我想使用to_s方法创建一个答案,具体取决于谁在上课。 我已经发现caller代表实际的堆栈。我必须用它来产生这个决定(接缝很完美,因为不需要宝石)。

问题是什么:我不知道怎么决定何要打电话,看看这个课程:

class child
    ...
    def to_s
      str = "I'm "
      str += @first_name
      str += @last_name
      str += " my dad is"
      str += @father.to_s
    end
  end

 class dad
    ...
    def to_s
      str = "I'm "
      str += @first_name
      str += @last_name
      str += " my childs are"
      @kids.each{|child| str+= child.to_s}
    end
  end

如果childto_s个实例调用dad,它应该只返回名称,反之如果dad调用他的child之一它的实例也应该返回名字。 我的原始问题更复杂,所以为了解决这个问题,我必须在这种情况下防止无限递归。

如何与来电者的班级进行比较?

2 个答案:

答案 0 :(得分:0)

在创建子节点时传递父实例怎么样? 以下是粗略的,但它确实有效。

class Child

  attr_accessor :father, :first_name, :last_name

  def initialize(father, first_name)
    @father = father
    @first_name = first_name
    @last_name = father.last_name
  end

  def to_s
    "I'm #{first_name} #{last_name} my dad is #{father.first_name} #{father.last_name}"
  end
end


class Dad

  attr_accessor :kids, :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
    @kids = []
  end

  def make_kid(first_name)
    kids << Child.new(self, first_name)
  end

  def to_s
    "I'm #{first_name} #{last_name} my childs are #{kids.map(&:first_name).join(', ')}"
  end
end

dad = Dad.new 'OShea', 'Jackson'
dad.make_kid 'Darrell'
dad.make_kid 'Tommy'

dad.to_s
# => "I'm OShea Jackson my childs are Darrell, Tommy"

dad.kids.first.to_s
# => "I'm Darrell Jackson my dad is OShea Jackson"

答案 1 :(得分:0)

您可以传递参数来中断递归:

def to_s skip_recursion=false
  return "#{first_name} #{last_name}" if skip_recursion
  # then goes as before
  # ...
  str += " my dad is"
  str += @father.to_s(true)
end

但实际上这将表现得像一个单独的方法name