1

Railsアプリケーションの異なるモジュール(グローバル名前空間/名前空間なしと「Foo」)に同じ名前(「Bar」)の2つのクラスがあるとします。両方のクラスはそれぞれ「app/models/bar.rb」または「app/models/foo/bar.rb」に存在するため、レールによって自動ロードされます。

# "app/models/foo/bar.rb"
module Foo
  class Bar
    def self.some_method
    end
  end
end

# "app/models/bar.rb"
class Bar
end

Foo 名前空間に、クラス メソッドで Bar クラスを使用する別のクラスがあります。

module Foo
  class Qux
    class << self
      def something
        Bar.some_method # This raises a NoMethod error because
                        # it uses the Bar defined in the global namespace
                        # and not the one in Foo
      end
    end
  end
end

nameRails オートローディングは、シングルトン クラスにある現在の classes を使用して Bar をロードしようとしnil、デフォルトは "Object" です。

klass_name = name.presence || "Object"  # from active_support/dependencies.rb

これにより、RailsBarは "app/models/foo/bar.rb" ではなく "app/models/bar.rb" からロードされます。thenで定義するQux.somethingと、nil ではなく "Foo::Qux" になり、オートロードは正しく機能します。def self.something.name

現時点では、この問題を回避するための 3 つのオプションがあります。

1) いずれかのBarクラスの名前を変更する
2)self.どこでも構文を使用する 3)どこでも明示的に
名前空間Barを使用するFoo::Bar

次の理由から、これらのオプションはどれも好きではありません。

1)Barはまさに最適な名前です
2)class << selfそれ自体はまったく問題なく、ほとんどの Ruby 開発者が使用しているため、次の貧しい人がすぐに同じ問題に遭遇する可能性が高くなります
3) 2) と同じです。根底にある「問題」を実際に修正しないと、誰かが将来、自分のコードが期待どおりに機能しない理由を理解するために時間を無駄にするでしょう.

あなたが考えることができる別のより良いオプションはありますか?

4

0 に答える 0