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