crystal-lang:如何使用项目特定包中的文件中定义的所有模块填充数组?

时间:2018-05-24 12:05:55

标签: metaprogramming crystal-lang

所有问题, 我想知道是否可以在Crystal(伪代码)中执行类似的操作:

modules = Array(Module).new
foreach (file in specific_package) do
  if (file.is_a(crystal_module) do
    modules.push(file.module)
  end
end

1 个答案:

答案 0 :(得分:1)

Crystal没有包而是模块。如果你想获得文件中的所有模块,你可以试试这个:

require "compiler/crystal/syntax"

Modules = [] of String

class ModuleVisitor < Crystal::Visitor
  def visit(node : Crystal::ModuleDef)
    Modules << node.name.names.join("::")
    true
  end

  def visit(node : Crystal::ASTNode)
    true
  end
end

Dir.glob("./*.cr").each do |file|
  visitor = ModuleVisitor.new
  parser = Crystal::Parser.new(File.read(file))
  parser.filename = file
  node = parser.parse
  node.accept(visitor)
end

puts Modules.join("\n")

然后你会得到一个包含所有模块名称的Array(String)

Try it online!

如果你想在课堂上获得所有包含的模块,请尝试:

class Class
  def included_modules
  {% if @type.ancestors.any? { |a| a.class.stringify.ends_with?(":Module") } %}
    {{ @type.ancestors.select { |a| a.class.stringify.ends_with?(":Module") } }}
  {% else %}
    [] of Nil
  {% end %}
  end
end

module Foo::Bar
end

class Baz
  include Foo::Bar
end

puts Baz.included_modules # => [Foo::Bar]

Try it online!