在Ruby Gosu中构建平铺游戏或模拟总是让我结束所有可用平铺的列表,由他们的班级保存。例如[Pipe, PipeJunktion, Box, Pump]
等等。每个类都是在几个单独的文件中定义的,我从主程序中需要这些文件。现在,每次我在游戏中添加新的图块时,我都必须自己将该类添加到此列表中。我想知道是否有办法从文件中捕获所有加载类。
有些事情:
allTiles = []
require_relative 'tiles.rb'.each_class {|class| allTiles << class}
会很方便。 或者可以通过某种方式用模块解决这个问题吗?
答案 0 :(得分:2)
您可以这样做:
Long
什么会收集Dir['tiles/*.rb'].each { |file| require file }
子文件夹中的所有文件并要求它。
在下一步中按文件名加载所有类:
tiles
顺便说一句,在Rails中可以这样做:
all_tiles = Dir['tiles/*.rb'].map do |file|
file_name = File.basename(x, '.*')
camel_cased_name = file_name.split('_').collect(&:capitalize).join
Object.const_get(camel_cased_name)
end
答案 1 :(得分:2)
检查文件添加的类不是容易或通常做的事情。更好的方法是将所有tile类放在单个命名空间下。由于可以重新打开类,因此可以将它们分成多个文件。
class Tiles
class Pipe
# ...
end
end
class Tiles
class Box
# ...
end
end
然后Tiles.constants
可能会返回一个符号数组:[:Pipe, :Box]
,并可用于使用Tiles.constants.map { |const| Tiles.const_get const }
或Tiles.constants.map &Tiles.method(:const_get)
如果由于某种原因知道特定文件添加了哪些常量非常重要,则以下代码显示了一种方法:
constants1 = Object.constants
require "./tiles.rb"
constants2 = Object.constants
added_constants = constants2 - constants1
如果tiles.rb
具有Pipe
和Box
的类定义,则added_constants
将为[:Pipe, :Box]
。
这种方法的问题是可能显示由宝石添加的常量,例如:
constants1 = Object.constants
require 'mechanize'
class Foo
end
constants2 = Object.constants
added_constants = constants2 - constants1
自从我致电require 'mechanize'
后,added_constants
列表会很长,并且不仅包含Foo
。
答案 2 :(得分:0)
我怀疑以下方法存在缺陷,但我会将其推出并邀请评论。
首先,使用ObjectSpace::each_object编译在创建任何自定义类之前存在的所有类的列表:
DECLARE @Param NVARCHAR(MAX) = '''yellow'', ''red'', ''blue'''
DECLARE @Query NVARCHAR(MAX)
SELECT @Query = 'SELECT * FROM (VALUES(' + REPLACE(@Param, ''',', '''),(') + ')) t(c)'
--SELECT @Query
EXEC sp_executesql @Query
对于我的Ruby版本(2.4.0),在IRB中base_classes = ObjectSpace.each_object(Class).to_a
。现在用base_classes.size #=> 490
等加载代码。假设这会导致创建三个类:
require
现在编译一个现在存在的所有类的列表并减去class A; end
class B; end
class C; end
:
base_classes
这将返回由我的代码添加的类数组。
当然,这不会显示ObjectSpace.each_object(Class).to_a - base_classes
#=> [A, B, C]
中被我的代码覆盖的类或显示哪些类是由所需的gem定义的。