crystal-lang : how to fill an array with all modules defined in files in a specific package of the project?

℡╲_俬逩灬. 提交于 2021-01-29 09:20:34

问题


All in the question, I would like to know if it's possible to do something like this in Crystal (pseudo-code) :

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

回答1:


Crystal doesn't have packages but modules. If you want to get all modules in a file you can try this:

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")

Then you'd get an Array(String) with all modules names

Try it online!

If you want to get all included modules in a class try this:

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!



来源:https://stackoverflow.com/questions/50508991/crystal-lang-how-to-fill-an-array-with-all-modules-defined-in-files-in-a-speci

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!