【问题标题】:How to get all classes in namespace without manually loading the classes?如何在不手动加载类的情况下获取命名空间中的所有类?
【发布时间】:2017-07-15 02:39:49
【问题描述】:

我正在寻找一种列出模块(命名空间)内定义的所有类的方法。 这是关于该问题的类似问题: How to get all class names in a namespace in Ruby?

但是看到最后一个回复,Module.constants 是空的,直到类被调用/加载。有没有办法在不手动引用每个类的情况下做到这一点?

我正在尝试在 Rails 3.2 中使用此功能,而我发现的唯一方法是在初始化程序中要求每个类(没有尝试过,但仍然需要手动输入...)。

提前感谢您的宝贵时间。

【问题讨论】:

    标签: ruby ruby-on-rails-3 module namespaces


    【解决方案1】:

    您可以像这样将命名空间目录中的文件全局化:

    Dir.glob('/path/to/namespaced/directory/*').collect{|file_path| File.basename(file_path, '.rb').constantize}
    

    所以在 Rails 初始化文件或模型中你可以这样做:

    Dir.glob(File.join(Rails.root, "app", "models", "my_namespace", "*")).collect{|file_path| File.basename(file_path, '.rb').constantize}
    

    【讨论】:

    • 这有点脏,但我想它会完成这项工作,所以接受了答案,通过我决定跟踪数组中的类。谢谢。
    【解决方案2】:

    基于 Bryan 提供的内容,您可以使用它从特定父命名空间获取常量/类,即使文件名/类名以某些字符串开头/结尾:

    require 'pathname'
    
    # make this the directory you are autoloading from
    autoload_dir = File.join(Rails.application.root, 'app', 'models')
    
    # this will return FooBar::BarFoo::**::*Boo constants and autoload them
    Dir.glob(File.join(autoload_dir, 'foo_bar', 'bar_foo', '**', '*_boo.rb')).collect{|pathname| Pathname.new(pathname.chomp('.rb')).relative_path_from(Pathname.new(autoload_dir)).to_s.camelize.constantize}
    

    【讨论】:

      【解决方案3】:

      Bryan Liff 简短而优雅的答案几乎是正确的,但会引发错误。相反,请尝试:

      Dir.glob(File.join(Rails.root, "app", "models", "my_namespace", "*")).collect{|file_path| File.basename(file_path, '.rb').camelize.constantize}

      注意camelize 的使用。我会在评论中发布此内容,但没有足够的声誉。

      【讨论】:

        猜你喜欢
        • 2020-04-10
        • 2014-09-08
        • 2010-10-31
        • 2019-02-22
        • 2018-08-27
        • 2013-07-28
        • 2012-02-18
        相关资源
        最近更新 更多