Ruby でネストされたクラスをコンパクトなスタイルに自動的に変換する
概要
クラス定義にネストされたスタイルとコンパクトなスタイルを組み合わせて使用する非常に大規模なコードベースがあります。
RuboCop: クラスとモジュールの子
# Nested
class Foo
class Bar
end
end
# Compact
class Foo::Bar
end
正規表現を使用して多数のクラスの名前空間を再編成する自動ツールを構築しています。これは、クラス定義がコンパクト形式の場合は簡単に実行できますが、ネストされた形式の場合はさらに困難になります。
したがって、ネストされたスタイルのすべてのインスタンスをコンパクト スタイルに変換する方法が必要です。
RuboCop がこれを実行できることを期待していましたが、ドキュメントではオートコレクトをサポートしているようですが、機能させることができません。 RuboCop は違反行為を報告しますが、修正はしません。
bundle exec rubocop --auto-correct app/controllers/announcements_controller.rb
Inspecting 1 file
C
Offenses:
app/controllers/announcements_controller.rb:1:8: C: Style/ClassAndModuleChildren: Use compact module/class definition instead of nested style.
module Vapid
^^^^^
app/controllers/announcements_controller.rb:2:10: C: Style/ClassAndModuleChildren: Use compact module/class definition instead of nested style.
module V2
^^
1 file inspected, 2 offenses detected
誰かがこれを機能させることができるか、コンパクトなスタイルを自動的に採用するより良い方法を知っていれば幸いです。
解決策
簡単な答えは、「やらない」です。あなた (そしてそのコップを書いた人) は、2 つの「スタイル」が実際には同じことを行うという間違った仮定を立てています。そうではありません。後者は本当に悪い習慣とみなされます。
したがって、次のものがあるとします。
module Foo
TEST = "I'm nested in Foo"
end
module Foo
class Bar
puts TEST
end
end
これにより、TEST は Foo::TEST に解決されるため、I は Foo にネストされます。スコープ解決演算子を使用するようにクラス定義を変更しましょう。
TEST = "I'm in the global scope"
module Foo
TEST = "I'm nested in Foo"
end
class Foo::Bar
puts TEST
end
これにより、I’m がグローバル スコープに入ります。モジュールのネストは依然としてグローバル スコープであり、TEST は ::TEST に解決されるためです。あなたの小さな「改善」は、実際には適切なモジュールのネストに依存するコードを破壊します。