来自.rb文件的Ruby类

时间:2015-02-06 16:20:58

标签: ruby-on-rails ruby

我喜欢从文件系统中读取ruby文件并获取实际的ruby类

Dir["app/controllers/admin/*.rb"].select{ |f|
    require File.expand_path(f)
    #how to turn 'f' into an actual class
}

我遇到的问题是Kernel.load或者只需要用布尔值响应。有没有办法获得实际的课程。我知道我可以使用文件路径来确定名称,但我不喜欢处理命名空间。我怎样才能做到这一点?

1 个答案:

答案 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
}