ruby 按定义捕获 类

ruby catch classes as they are defined

在 Ruby Gosu 中构建拼图游戏或模拟总是让我最终得到一个所有可用拼图的列表,由它们 class 保存。例如[Pipe, PipeJunktion, Box, Pump]等。每个 class 都在几个单独的文件之一中定义,这是我从主程序中需要的。现在,每次我向游戏中添加新板块时,我都必须将 class 自己添加到此列表中。我想知道是否有办法从文件中捕获所有加载 classes。

大致如下:

allTiles = []
require_relative 'tiles.rb'.each_class {|class| allTiles << class}

会很方便。 或者这可以通过某种方式用模块解决吗?

你可以这样做:

Dir['tiles/*.rb'].each { |file| require file }

什么会收集 tiles 子文件夹中的所有文件并需要它。

下一步按文件名加载所有 类:

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

顺便说一下,在 Rails 中也可以这样做:

all_tiles = Dir['tiles/*.rb'].map do |file| 
  File.basename(x, '.*').camelize.constantize
end

检查文件添加了哪些 classes 不是一件容易或通常完成的事情。更好的方法是将所有 tile classes 放在一个命名空间下。由于可以重新打开 classes,因此可以将它们拆分为多个文件。

class Tiles
  class Pipe
    # ...
  end
end

class Tiles
  class Box
    # ...
  end
end

然后 Tiles.constants 可以 return 一个符号数组:[:Pipe, :Box],并且可以使用 Tiles.constants.map { |const| Tiles.const_get const } 获取 class 个引用列表或 Tiles.constants.map &Tiles.method(:const_get)

如果出于某种原因了解特定文件添加了哪些常量真的很重要,则以下代码显示了一种方法:

constants1 = Object.constants
require "./tiles.rb"
constants2 = Object.constants
added_constants = constants2 - constants1

如果 tiles.rbPipeBox 有 class 定义,那么 added_constants 将是 [:Pipe, :Box]

这种方法的问题是可能会显示由 gems 添加的常量,例如:

constants1 = Object.constants
require 'mechanize'
class Foo
end
constants2 = Object.constants
added_constants = constants2 - constants1

自从我调用了 require 'mechanize' 之后,added_constants 列表将会很长并且包含的​​不仅仅是 Foo

我怀疑下面的方法有陷阱,但我会把它放出来并征求意见。

首先,使用 ObjectSpace::each_object 编译在创建任何自定义 类 之前存在的所有 类 的列表:

base_classes = ObjectSpace.each_object(Class).to_a

对于我的 Ruby (2.4.0) 版本,在 IRB 中,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]

这个 returns 由我的代码添加的 类 数组。

当然这不会显示 base_classes 中被我的代码覆盖的 类 或显示哪些 类 由所需的宝石定义。