我在下面的相对简单的任务中遇到了一个有趣的问题.开头的每个带括号的块都计算为nil,留下应该分配给Rubygame::Surface.new的值@image.不幸的是,在我设置的下一行@rect,它会抛出NoMethodError,因为它@image是nil.
@image = (image unless image.nil?) or
(Rubygame::Surface.autoload(image_file) unless image_file.nil?) or
(Rubygame::Surface.autoload("#{@name}.png") unless @name.nil?) or
Rubygame::Surface.new([16, 16])
@rect = Rubygame::Rect.new [0, 0], [@image.width, @image.height]
Run Code Online (Sandbox Code Playgroud)
类似的测试按预期运行IRB工作,所以我很确定'或'语句是格式良好的,但我无法弄清楚为什么当其他所有内容都为零时它不会返回新的Surface .
Ruby中的or和and关键字具有非常非常低的优先级.甚至低于赋值运算符=.所以只需分别用||和替换它们&&(两者都比=它更紧密),它应该按预期工作.这里列出了 Ruby的运算符优先级.
除此之外,我会说你的代码非常密集.考虑将其重构为类似下面的内容,我认为这样可以更好地传达代码的意图.
@image = case
when image then image
when image_file then Rubygame::Surface.autoload(image_file)
when @name then Rubygame::Surface.autoload("#{@name}.png")
else Rubygame::Surface.new([16, 16])
end
@rect = Rubygame::Rect.new [0, 0], [@image.width, @image.height]
Run Code Online (Sandbox Code Playgroud)