首页 > 解决方案 > 水晶语言:如何用项目特定包中文件中定义的所有模块填充数组?

问题描述

总而言之,我想知道是否可以在 Crystal(伪代码)中做这样的事情:

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

标签: metaprogrammingcrystal-lang

解决方案


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)包含所有模块名称的

在线尝试!

如果你想在一个类中获取所有包含的模块,试试这个:

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]

在线尝试!


推荐阅读