问题
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