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.
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.