我喜欢从文件系统中读取ruby文件并获取实际的ruby类
Dir["app/controllers/admin/*.rb"].select{ |f|
require File.expand_path(f)
#how to turn 'f' into an actual class
}
我遇到的问题是Kernel.load或者只需要用布尔值响应。有没有办法获得实际的课程。我知道我可以使用文件路径来确定名称,但我不喜欢处理命名空间。我怎样才能做到这一点?
答案 0 :(得分:1)
首先,我要事先告诉你这可能是一个坏主意。 Ruby中的文件与类无关。文件可以定义一个类,没有类或许多类,甚至可以根据任意条件动态定义类。此外,类定义可能分布在多个文件中,并且可以在运行时动态更改类。出于这个原因,至少可以说,确定一个类是否在文件中定义是一项艰巨的任务。
那就是说,这是解决问题的一种方法。请注意,此解决方案非常hacky,在所有情况下都不起作用,如果您不小心,可以多次加载同一个文件:
module ClassLoader
def self.load_classes(file)
context = Module.new
context.class_eval(File.read(file), file)
context.constants.map{|constant| [constant, context.const_get(constant)]}.to_h
end
end
用法:
./test_file.rb
:
if rand < 0.5
class A
end
else
class B
end
end
class C
end
您的代码:
ClassLoader.load_classes('./test_file.rb') #=> {:A=>#<Module:0x9a3c128>::A, :C=>#<Module:0x9a3c128>::C}
或者,如果您正在使用Rails,则通常可以从文件名中推断出类名。这有点更可靠,因为它依赖于Rails为自动加载常量所做的相同约定:
Dir["app/controllers/admin/*.rb"].select{ |f|
File.basename(f).camelize.constantize
}