本帖最后由 寒冷魔王 于 2016-5-22 13:10 编辑
鉴于LZ是在查找BUG,我来说一下最常见的BUG——脚本冲突的解决方法:
有四段脚本:
# 脚本0 class A def a puts("A.a0") end def b puts("A.b0") end end
# 脚本0
class A
def a
puts("A.a0")
end
def b
puts("A.b0")
end
end
# 脚本1 class A alias old_a a # 可以正常运行的写法 def a old_a # a0有效 puts("A.a1") end def b # 可能出于需要,作者有意覆盖原本的b脚本,这可能会导致后续用到原始b的脚本冲突 # 修改此问题的方法是将这段脚本放在其他修改脚本的上方,或者用if将它包装,或者将其他脚本对照着复制一遍(按照作者的写法适当修改) puts("A.b1") end end
# 脚本1
class A
alias old_a a # 可以正常运行的写法
def a
old_a # a0有效
puts("A.a1")
end
def b # 可能出于需要,作者有意覆盖原本的b脚本,这可能会导致后续用到原始b的脚本冲突
# 修改此问题的方法是将这段脚本放在其他修改脚本的上方,或者用if将它包装,或者将其他脚本对照着复制一遍(按照作者的写法适当修改)
puts("A.b1")
end
end
# 脚本2 class A alias old_a a # 错误根源:alias重命名为同一个名称导致循环调用 # 修改方法:将这个old_a改成其他的名称,如old_old_a def a # 和脚本1放在一起,会stack level too deep old_a # 这个要改成和本段脚本alias同样的名称 puts("A.a2") end alias old_b b def b old_b puts("A.b2") end end
# 脚本2
class A
alias old_a a # 错误根源:alias重命名为同一个名称导致循环调用
# 修改方法:将这个old_a改成其他的名称,如old_old_a
def a # 和脚本1放在一起,会stack level too deep
old_a # 这个要改成和本段脚本alias同样的名称
puts("A.a2")
end
alias old_b b
def b
old_b
puts("A.b2")
end
end
# 调用脚本 a = A.new a.a puts("-") a.b
# 调用脚本
a = A.new
a.a
puts("-")
a.b
脚本0是原始脚本,脚本1是增添脚本1,脚本2是增添脚本2。
顺序:
【0】
脚本0
正确,输出
A.a0
A.b0
【1】
脚本0
脚本1
脚本2
错误1:
in `a': stack level too deep (SystemStackError)
检查名称为a的函数,看看alias是否将两个a函数重命名为同一个a函数
如两个alias old_a a。
有,改为不同名,如:
alias old_a1 a
alias old_a2 a
注意各自a函数里的调用也要改。
错误2:
改完后,输出
A.a0
A.a1
A.a2
-
A.b1
A.b2
如果b0是我们不需要的,那么就是正确结果,如果需要的话,那么需要在脚本2中调用原本的b
直接将脚本2放在脚本1上方,是不行的。因为这样的话只会输出b1。
修改这一问题的方法是在脚本0的b函数后面加一条alias:
#(脚本0) def b puts("A.b0") end alias default_b b #(脚本2) def b default_b # 这个是为b0准备的 old_b # 这个是为b1以及基于b1修改的各种脚本准备的 puts("A.b2") end
#(脚本0)
def b
puts("A.b0")
end
alias default_b b
#(脚本2)
def b
default_b # 这个是为b0准备的
old_b # 这个是为b1以及基于b1修改的各种脚本准备的
puts("A.b2")
end
【2】
脚本0
脚本2
脚本1
修改好stack错误后,会发现只输出b1。
这是因为b1粗暴地将原本的代码全部覆盖了(其实这个很多时候是作者不得不这么做的)
解决方法之一是调整顺序(见上)。
如果不想调整顺序,或者调整顺序依旧出现很多问题的话,就需要按照代码的逻辑进行修改。
将多个重载函数合成为一个函数,通过if case等语句控制,是一个比较好的方法。
许多兼容性问题,其实根源大抵都是这种重载问题。
当然还有使用同一个变量导致冲突之类。
理解增添脚本的修改内容,根据情况适当调整,是万能的解决方案。
|