行为: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
我正在使用rvm来管理Mac 10.6.6上的ruby版本。知道为什么会这样吗?
REVISION:
如果上面的代码减少到:
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
这会重现最后一行的错误。 在输入中,崩溃,进入和离开是不相交的点集。应该有效的类定义是:
class BasicNode
attr_reader :x, :y
def initialize x, y
@x = x
@y = y
end
end
其中x和y是数字。在崩溃的测试中,into
中有15个节点,from
中有5个节点。
编辑:
当我稍微隔离代码时,我确实得到stack level too deep (System Stack Error)
。但是,我不确定为什么会这样,因为在此代码或数组索引的C实现中没有递归调用。
ADDENDUM:此问题的完整源代码可在此处找到:http://code.google.com/p/graphcomplexity/
repository:rvertex 分支:默认 测试文件:test / test_deeps_hypersim.rb
答案 0 :(得分: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);
你的错误是否仍然出现在那套指令中?如果您仍然遇到错误,但没有收到这些说明,您是否可以提供一些示例数据和函数调用来说明问题? (如果它很大,你可以使用像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)
如果效率太低,可以用循环外的yield()来重写它。此实现还允许您传递任意块而不仅仅是一个函数来调用
add_from_to_modified(list1,list2,5) {|node| node.x*3-node.y}