Ruby 1.9.2-p-180因"非法指令"或"堆栈级别太深(SystemStackError)"而失败

phi*_*dad 6 ruby rvm

行为:Ruby 1.9.2p180因"非法指令"失败而没有其他细节.Ruby 1.9.1p378运行完全没有任何问题.

pin = fronto.index(k)仅在一些迭代中,该行发生故障.

from并且into都是对象数组,by是该对象的属性(x或y).

代码:

  def add_from_to_by from, into, by
    nto = into.sort_by{|k| k.send(by)}
    fronto = (from + nto).sort_by{|k| k.send(by)}
    dict = {}
    nto.each{|k| dict[k] = []}
    nto.each do |k|
      pin = fronto.index(k)
      up = pin+1
      down = pin-1
      while up < fronto.length and ((fronto[pin].send(by)) - (fronto[up].send(by))).abs <= $sensor_range
        if fronto[up].kind_of?(BasicNode) then 
          dict[k].push(fronto[up]) 
        end
        up += 1
      end
      while down >= 0 and ((fronto[pin].send(by)) - (fronto[down].send(by))).abs <= $sensor_range
        if fronto[down].kind_of?(BasicNode)
          dict[k].push(fronto[down])
        end
        down -= 1
      end
    end
    return dict
  end 
Run Code Online (Sandbox Code Playgroud)

我正在使用rvm来管理Mac 10.6.6上的ruby版本.知道为什么会这样吗?

修订:

如果上面的代码减少到这个:

def add_from_to_by from, into, by
        nto = into.sort_by{|k| k.send(by)}
        fronto = (from + nto).sort_by{|k| k.send(by)}
        dict = {}
        nto.each{|k| dict[k] = []}
        x = nto.select{|k| !fronto.include?(k)}
end
Run Code Online (Sandbox Code Playgroud)

这将再现最后一行的错误.在输入中,崩溃,进入和离开是不相交的点集.应该有效的类定义是:

class BasicNode
    attr_reader :x, :y
    def initialize x, y
        @x = x
        @y = y
    end
end
Run Code Online (Sandbox Code Playgroud)

其中x和y是数字.在崩溃的测试中,有15个节点into,5个节点from.

编辑:

stack level too deep (System Stack Error)当我稍微隔离代码时,我确实得到了一个.但是,我不确定为什么会这样,因为在此代码或数组索引的C实现中没有递归调用.

附录:此问题的完整源代码可在此处找到:http://code.google.com/p/graphcomplexity/

repository:rvertex branch:默认测试文件:test/test_deeps_hypersim.rb

Yen*_*rst 2

在Linux上使用1.9.2-p180,我无法重现你的问题。这是我的测试设置:

$sensor_range=5
list1=Array.new(1000) {|i| BasicNode.new(rand(100),rand(100))}
list2=Array.new(1000) {|i| BasicNode.new(rand(100),rand(100))}
res=add_from_to_by(list1,list2,:x);
Run Code Online (Sandbox Code Playgroud)

使用该指令集后,您的错误是否仍然出现?如果您仍然遇到该错误,但没有按照这些说明进行操作,您能否提供一些示例数据和函数调用来演示该问题?(如果它很大,你可以使用像pastebin.com这样的服务)


另外,我不能 100% 确定它是否完全相同,但这可能是编写相同函数的更直接的方法(您的程序可能更容易使用更简单的代码进行调试):

def add_from_to_modified(from,into,sensor_range,&block)
  into.inject({}) do |result,key|
    result.merge({key=>(into+from).select {|check| (yield(check)-yield(key)).abs <= sensor_range}})
  end
end

add_from_to_modified(list1,list2,5,&:x)
Run Code Online (Sandbox Code Playgroud)

如果效率太低,可以在循环外部使用yield() 重写它。此实现还允许您传递任意块,而不仅仅是要调用的函数

add_from_to_modified(list1,list2,5) {|node| node.x*3-node.y}
Run Code Online (Sandbox Code Playgroud)