在 Ruby 中调用 yield 时堆栈级别错误太深


names = %w(Darko Marko Sarko Harko Yarko)
  def names
    yield names.shift
    yield names.shift
    yield names.shift
    yield names.shift
    yield names.shift
  end
names do |name|
  puts name
end

这会产生堆栈级别太深的错误。这是怎么回事?

正如 Sergio 所解释的那样,您需要将数组传递到方法

array_of_names = %w(Darko Marko Sarko Harko Yarko)
def names(array_of_names)
  yield array_of_names.shift
  yield array_of_names.shift
  yield array_of_names.shift
  yield array_of_names.shift
  yield array_of_names.shift
end
names(array_of_names) {|name| puts name }

这是名称冲突。

yield names.shift

names这里是def names,不是names = %w

因此,自然而然地,

方法进入递归,它无法从中爆发出来。

更新:

重命名

数组(或方法)时出现"未定义的局部变量"错误的原因是称为"作用域门"。

基本上,当打开方法定义时,当前范围会更改,并且所有局部变量都变得不可访问。因此,要么将数组作为方法参数传递(如 Steve 的答案中所建议的,推荐),要么将数组作为实例变量。

@name_arr = %w(Darko Marko Sarko Harko Yarko)
def names
  yield @name_arr.shift
end

你想做的是这样的

names = %w(Darko Marko Sarko Harko Yarko)
names.each do |name|
  puts name
end

这不仅可以让您使用可变长度数组,还可以避免递归错误。