11

我有以下文件 lib/a/b/c.rb

class a::b::c
  def request(env)
    #some code here
  end
end

现在我正在使用 rubocop 风格

Style/ClassAndModuleChildren:
  Enabled: true

我为此受到 rubocop 冒犯

lib/a/b/c.rb:1:7: C: Use nested module/class definitions instead of compact style.
class a::b::c

当我将代码更新为以下攻击时得到修复

样式 1

class a
  class b
    class c
      def request(env)
        #some code here
      end
    end
  end
end

风格 2

module a
  module b
    class c
      def request(env)
        #some code here
      end
    end
  end
end

我想我应该Style 2在我require 'a'的一个文件中使用。

请让我知道如何解决这种类型和违规行为及其原因

4

2 回答 2

9

这被标记为冒犯的原因是常量解析在词汇上起作用,而不是在 ruby​​ 中的语义上。这不直观,可能会导致一些晦涩的错误(例如,如果您在两个不同的范围内有两个同名的类)。比较这两种情况:

# Given
module Foo
  X = 42
end

# This
module Foo
  class Bar
    def baz
      puts X
    end
  end
end

# VS
class Foo::Bar
  def baz
    puts X
  end
end

现在当你打电话时:

Foo::Bar.new.baz

在第一种情况下你会得到42,在第二种情况下 -NameError: uninitialized constant Foo::Bar::X


至于修复它的正确方法是:请注意,如果Foo不存在,使用短语法会给你一个错误。答案是——你应该使用任何东西Foo。如果它是一个类 - 使用class,如果它是一个模块 - module

于 2016-01-07T07:38:33.063 回答
3

Classclass 本质上是从Moduleclass 派生的,这就是为什么ClassaModule添加了一些功能;基本上区别在于Classes 可能被实例化。

因此,您的问题的答案是:使用更适合您的情况的东西(并且根据给出的信息,无法说出它是什么。)

require 'a'与案例无关,因为require指令只是强制 ruby​​ 解释器加载相应的代码。

注意:这类问题正是 Rubocop 抱怨的确切原因:它阻止你使用你不确定的东西并强迫你理解,是事实上Module还是天生Class的。

顺便说一句,既然你提到你有require 'a'某个地方,这可能意味着a.rb你已经有了module Aor class A

BTW#2 类名和模块名都必须以大写字母开头,因为它们是常量

于 2016-01-07T07:37:00.193 回答