Techioz Blog

Rubyで同じクラスを2回定義する

概要

次のコードは機能しますが、理由がわかりません。ファイルが 2 つあります。 1 つ目は、active_market/walmart.rb にある walmart.rb というクラスです。クラス定義は次のとおりです。

module ActiveMarket
    class Walmart
        def test_one
            puts "test one"
        end
    end
end

私の Walmart クラスには、Order、Fulfillment、Report などの Walmart API の「API 実装」があります。そのため、最初の API 実装用のフォルダーと別のクラスを active_market/walmart/order.rb に作成しました。

Order クラスの定義は次のとおりです。

class ActiveMarket::Walmart
  def test_two
    puts "test two"
  end

  class Order < ActiveMarket::Walmart
    def test_all
      test_two
      test_one
    end
  end

end

ActiveMarket::Walmart.new と ActiveMarket::Walmart::Order.new を呼び出せるようにしたいと考えていました。これを行うには、上で示したように、クラス ActiveMarket::Walmart をもう一度定義し、その中に Order クラスを配置する必要がありました。これは期待どおりに機能しましたが、なぜこれら 3 つの関数すべてを正常に呼び出すことができるのかわかりません。

ActiveMarket::Walmart.new.test_one
ActiveMarket::Walmart.new.test_two
ActiveMarket::Walmart::Order.new.test_all

それで、問題はなぜこれが機能するのかということです。まったく異なる 2 つのファイルで定義されている test_one 関数と test_two 関数を同じクラスで呼び出すことができるのはなぜですか? ActiveMarket::Walmart クラスの 1 つが完全にオーバーライドされることを期待していました。これには何か欠点はありますか、それとも実装を変更する必要がありますか?

前もって感謝します。

解決策

Ruby では、既存のクラスを再度開き、そこにメソッドを追加したり、既存のメソッドをオーバーライドしたりできます。

あなたの例では、実際には 2 つのインスタンス メソッドを定義する ActiveMarket::Walmart クラスが 1 つだけあります。

これを試して:

walmart = ActiveMarket::Walmart.new
walmart.test_one
#=> test one
walmart.test_two
#> test two