更改类和模块中子定义的样式后出现未初始化常量错误

pes8fvy9  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(326)

我有一个gem,其中所有包含模块的类都是这样的

require 'concurrent_rails/adapters/future'

module ConcurrentRails
  class Promises
    include ConcurrentRails::Adapters::Future

这是模块

module ConcurrentRails::Adapters
  module Future
    extend ActiveSupport::Concern

    class_methods do
      ....

这很好,但我试图将类和模块的定义保持在一行中:

module ConcurrentRails::Adapters::Future
  extend ActiveSupport::Concern

  class_methods do
    ...

当我像上面那样更改定义时,不接触 promises.rb 文件,我得到以下错误:

future.rb:3:in `<top (required)>': uninitialized constant ConcurrentRails::Adapters (NameError)

我试过了 require 之前的文件,在 concurrent_rails.rb 定义,但没有任何效果。
如果有帮助的话,这里是来源

mjqavswn

mjqavswn1#

一般来说,我建议不要使用嵌套类/模块定义。当然,它会保存一行代码/缩进,但您会遇到这种问题。
例如,看到这个了吗 rubocop 规则:
类:rubocop::cop::style::classandmodulechildren
概述
此cop检查类和模块中子级定义的样式。基本上有两种不同的风格:
紧凑样式仅强制用于具有一个子级的类/模块。
示例:
enforcedstyle:嵌套(默认)


# good

# have each child on its own line

class Foo
  class Bar
  end
end

强制样式:紧凑


# good

# combine definitions as much as possible

class Foo::Bar
end

定义嵌套模块是有问题的,因为它只有在父模块已经定义的情况下才能在ruby中工作。例如:

irb(main):001:1* module Foo::Bar
irb(main):002:0> end
Traceback (most recent call last):
        1: from (irb):1
NameError (uninitialized constant Foo)

鉴于此方法效果良好:

irb(main):001:1* module Foo
irb(main):002:2*   module Bar
irb(main):003:1*   end
irb(main):004:0> end

此外,即使已经定义了父模块,在ruby中嵌套模块仍然会遇到其他问题。
因此,简言之: module ConcurrentRails::Adapters::Future 没用,因为 ConcurrentRails::Adapters 还没有定义。
您可以通过首先明确定义“父模块”来解决这个问题,但是,不管怎样,我都不建议使用3+层嵌套模块定义。

相关问题