1

我在下面相对简单的分配中遇到了一个有趣的问题。开头的每个带括号的块都评估为nil,留下应该分配Rubygame::Surface.new的值。@image不幸的是,在我设置的下一行@rect,它抛出NoMethodError因为@imagenil

@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 运行,按预期工作,所以我很确定 'or' 语句格式正确,但我无法弄清楚为什么它没有返回新的 Surface 而其他一切都是nil

4

3 回答 3

5

Ruby 中的orand关键字具有非常非常低的优先级。甚至低于赋值运算符。因此,只需将它们分别替换为and (两者都比 绑定更紧),它应该可以按您的预期工作。此处列出了Ruby 的运算符优先级and=||&&=

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

@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]
于 2010-09-11T11:16:34.920 回答
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]))
于 2010-09-11T10:00:23.897 回答
-1

你为什么使用 RubyGame?用于 Ruby的Gosu游戏开发框架更快更流行。

于 2010-09-12T08:48:03.350 回答