简单的“或”没有按预期工作
我在下面相对简单的作业中遇到了一个有趣的问题。开头的每个括号内的块的计算结果均为 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 工作,所以我很确定“or”语句的格式良好,但我无法弄清楚为什么当其他一切都为 nil 时它不返回新的 Surface /em>。
I'm running into an interesting issue with the relatively simple assignment below. Each of the parenthesized chunks in the beginning evaluate to nil, leaving Rubygame::Surface.new
as the value that @image
ought to be assigned to. Unfortunately on the next line where I set @rect
, it throws a NoMethodError because @image
is 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]
Similar tests run through IRB work as expected, so I'm pretty sure the 'or' statement is well-formed, but I can't figure out why it isn't returning the new Surface when everything else is nil.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否尝试过更多级别的括号?
Have you tried further levels of parentheses?
你为什么使用 RubyGame?用于 Ruby 的 Gosu 游戏开发框架更快、更流行。
Why are you using RubyGame? The Gosu game development framework for Ruby is faster and more popular.
Ruby 中的
or
和and
关键字的优先级非常非常低。甚至低于赋值运算符=
。因此,只需分别将它们替换为||
和&&
(两者绑定都比=
更紧密),它应该按您的预期工作。此处列出了 Ruby 的运算符优先级。除此之外,我想说你的代码非常密集。考虑将其重构为如下所示,我认为这可以更好地传达代码的意图。
The
or
andand
keywords in Ruby have very, very low precedence. Even lower than the assignment operator=
. So simply replace them with||
and&&
respectively (both binding tighter than=
), and it should work as you expect. Ruby's operator precedence is listed here.In addition to that, I would say your code is very dense. Consider refactoring it to something like the following, which I think conveys the intent of your code much better.