简单的'或'没有按预期工作

时间:2010-09-11 09:47:31

标签: ruby rubygame

我遇到了一个有趣的问题,下面的分配相对简单。开头的每个带括号的块都计算为 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]

类似的测试按预期运行IRB工作,所以我很确定'或'语句格式正确,但我无法弄清楚为什么当其他一切都是

3 个答案:

答案 0 :(得分:5)

Ruby中的orand关键字具有非常非常低的优先级。甚至低于赋值运算符=。因此,只需分别用||&&替换它们(两者都比=更紧密),它应该按预期工作。 Ruby的operator precedence is listed here

除此之外,我会说你的代码非常密集。考虑将其重构为类似下面的内容,我认为这样可以更好地传达代码的意图。

@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]

答案 1 :(得分:1)

您是否尝试过更多级别的括号?

@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]))

答案 2 :(得分:-1)

你为什么使用RubyGame? Ruby的Gosu游戏开发框架更快,更受欢迎。