Building tile games or simulations in Ruby Gosu always makes me end upp with a list of all available tiles, saved by their class. For example [Pipe, PipeJunktion, Box, Pump]
and so on. Each class is defined in one of a few separate files, which i required from the main program. For now i have to add the class myself to this list every time I add a new tile to the game. I was wondering if there was a way to catch all loading classes from a file.
Something along the lines of:
allTiles = []
require_relative 'tiles.rb'.each_class {|class| allTiles << class}
would be handy. Or can this be solved with modules in some way?
Checking which classes were added by a file is not something that's easily or commonly done. A better approach would be to put all the tile classes under a single namespace. Since classes can be re-opened, these can be split among multiple files.
class Tiles
class Pipe
# ...
end
end
class Tiles
class Box
# ...
end
end
Then Tiles.constants
could would return an array of symbols: [:Pipe, :Box]
, and could be used to get a list of class references using Tiles.constants.map { |const| Tiles.const_get const }
or Tiles.constants.map &Tiles.method(:const_get)
If for whatever reason it was really important to know which constants were added by a specific file, the following code shows an approach:
constants1 = Object.constants
require "./tiles.rb"
constants2 = Object.constants
added_constants = constants2 - constants1
If tiles.rb
had class definitions for Pipe
and Box
, then added_constants
would be [:Pipe, :Box]
.
The problem with this approach is that might show constants added by gems, for example:
constants1 = Object.constants
require 'mechanize'
class Foo
end
constants2 = Object.constants
added_constants = constants2 - constants1
Since I called require 'mechanize'
, the added_constants
list will be quite long and include much more than just Foo
.