【问题标题】:undefined method `configure' for MyGem:ModuleMyGem:Module 的未定义方法“配置”
【发布时间】:2017-07-25 14:56:54
【问题描述】:

问题背景

  • gem 'leanpirates-aarrr', '~> 0.1.1', :path => "/src/gem-aarrr" 运行正常
  • rails g 显示生成器 lean_pirates:aarrr:install
  • config/initializers/leanpirates_aarrr.rb下成功创建初始化器
  • 但在尝试配置 gem 时初始化程序失败

初始化器:leanpirates_aarrr.rb

LeanPirates::Aarrr.configure do |config|
  config.api_server     = "http://localhost:3000"
  config.startup_key    = Rails.configuration.leanpirates_aarrr.startup_key
  config.startup_secret = Rails.application.secrets.leanpirates_startup_secret
end

gem 定义文件:aarrr.rb

# (...)
module LeanPirates
  module Aarrr
    class << self
      attr_writer :configuration
    end

    def self.configuration
      @configuration ||= LeanPirates::Aarrr::Domain::Configuration.new
    end

    def self.reset
      @configuration = LeanPirates::Aarrr::Domain::Configuration.new
    end

    def self.configure
      yield(configuration)
    end
  end
end

错误

/src/app-ebusiness-v3/config/initializers/leanpirates_aarrr.rb:1:in &lt;top (required)&gt;: undefined method 'configure' for LeanPirates::Aarrr:Module (NoMethodError)

/src/app-ebusiness-v3/config/initializers/leanpirates_aarrr.rb:1:in `<top (required)>': undefined method `configure' for LeanPirates::Aarrr:Module (NoMethodError)
    from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `load'
    from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `block in load'
    from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:259:in `load_dependency'
    from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `load'
    (...)

这是来自https://github.com/lean-pirates/gem-aarrr/tree/simplification(分支simplification)的开源LeanPirates AARRR

【问题讨论】:

    标签: ruby-on-rails ruby configuration rubygems


    【解决方案1】:

    问题已解决

    @tadman 用他的解释引导我朝着正确的方向前进(非常感谢),尽管问题比我最初评估的要大。

    Rails Autoloader 无法加载我的文件。 为什么?因为我试图组织它们。

    问题是

    命名空间! 很久以前,当 gem 启动时,将所有内容移动到 /lib/gem 文件夹是合理的。然而,事实证明这是问题的根源。

    由于命名空间与文件夹结构不匹配,Autoloader 无法加载文件,并且无法识别它们以及我的 gem 的类等。

    命名空间是如何排序的?

    当你做你的 gem 时,请确保你很好地理解了命名空间。就我而言,使用以下命令行生成插件解决了问题:

    rails plugin new lean_pirates-aarrr

    上面的这一行以它们应该让自动加载器拾取的方式创建了一些东西。这不是我们可以抱怨的:Rails 很大程度上遵循“约定优于约定”的范式。

    我的最终结构如下: (https://github.com/lean-pirates/gem-aarrr/tree/simplification)

    - lib/
      -> generators/
        -> lean_pirates/
          -> aarrr/
            -> install/
              -> routines/*.rb
              -> templates/*.rb
              -> *.rb
      -> lean_pirates/
        -> aarrr/
          -> domain/*.rb
          -> helpers/*.rb
          -> *.rb
    

    我会更乐意将 /generators 和 /gem 放在根目录下,我相信这是可能的,但我并不想与约定作对,所以我很乐意将其保留为至少现在是这样。

    如果您遇到同样的问题,修复文件夹结构可能有助于 Autoloader 找到您的文件。更改它,或进行相应的配置。

    【讨论】:

    • 很好地解释了如何让它正常工作。
    【解决方案2】:

    Rails 中的 Autoloader 功能非常方便,它可以自动处理很多事情,但它也不是很聪明。如果命名空间已定义,则不会加载其他文件。

    作为 gem,您有义务要求您的库正常工作所需的任何和所有支持模块或类。

    这是lib/gem/aarrr/version.rb中的问题:

    module LeanPirates
      module Aarrr
          VERSION = '0.1.1'
      end
    end
    

    现在LeanPirates::Aarrr 已经定义好了,所以自动加载器不需要额外的工作。因此,您的 lib/gem/aarrr.rb 永远不会加载。

    要解决此问题,您需要避免创建该命名空间路径。您还应该确保在您的.gemspec 文件中正确设置require_paths,以便正确引用lib/gem。现在你必须require 'gem/aarrr' 这真是令人困惑和笨拙。

    我通常在 gem 主目录中设置一个普通的 VERSION 文件,该文件只有版本字符串。如果需要,gemspec 可以使用 File.read 按需读取此内容,或者您​​可以使用 rake 任务将其烘焙到 .gemspec 中。我更喜欢后一种方法,因为创建一个包含大量任意代码的.gemspec 总是过于复杂。

    【讨论】:

    • 谢谢@tadman。我想我明白了你所说的:设置阻止自动加载器加载lib/gem/aarrr.rb,但我不太清楚你的意思是什么:(a)To fix this you need to avoid creating that namespace path. 我该怎么做?,(b) I usually set up a plain-old VERSION file in the main gem directory that has nothing but the version string.,因为我的 version.rb 并没有做更多的事情,它只有版本。你能提供一些关于这些的额外信息吗?提前致谢。
    • 通常我使用Jeweler 进行打包,它会为您处理这个,按需将版本烘焙到.gemspec。还有其他包装器做同样的事情。手动构建这些可能很烦人。无论您做什么,都必须避免创建LeanPirates::Aarrr,这样即使LeanPirates::VERSION 也会这样做。
    • 谢谢@tadman。尽管我无法完全理解/使用您在此处提供的指示,但他们确实为我指明了正确的方向。为此+1,我会回答结果。
    猜你喜欢
    • 2021-10-22
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多