Определение одного и того же класса дважды в Ruby - PullRequest
0 голосов
/ 10 апреля 2020

Следующий код работает, но я не понимаю, почему. У меня есть два файла. Первым является класс с именем walmart.rb, расположенный в active_market/walmart.rb. Вот определение класса:

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

Для моего Walmart класса у меня есть "реализации API" для API Walmart, такие как Order, Fulfillment, Report и др. c. Поэтому я создал папку и другой класс для своей первой реализации 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 внутрь. Это сработало, как и ожидалось, но я не понимаю, почему я могу успешно вызвать все три из этих функций.

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

Итак, вопрос в том, почему это работает? Почему я могу вызывать функции test_one и test_two в одном классе, которые определены в двух совершенно разных файлах? Я ожидал, что один из ActiveMarket::Walmart классов будет полностью переопределен. Есть ли какие-либо недостатки в этом, или я должен изменить свою реализацию?

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

Ruby позволяет повторно открыть существующие классы и добавить к ним дополнительные методы или переопределить существующий метод.

В вашем примере фактически существует только один класс ActiveMarket::Walmart, который определяет два метода экземпляра. Попробуйте это:

walmart = ActiveMarket::Walmart.new
walmart.test_one
#=> test one
walmart.test_two
#> test two
1 голос
/ 10 апреля 2020

Для пояснения давайте предположим, что сначала загружается первый кодовый блок, затем второй кодовый блок.

Первый кодовый блок определяет класс ActiveMarket::Walmart с помощью метода test_one. Второй блок кода открывает класс заново и добавляет к нему метод test_two. Это поведение описано в документации Ruby .

Вообще говоря, лучше всего выполнять большинство определений методов ActiveMarket::Walmart в файле active_market/walmart.rb. Таким образом, вы знаете, где искать, когда вы ищете определенное определение c. Например, если метод test_one из ActiveMarket::Walmart был определен в foo/bar.rb, найти его было бы не интуитивно понятно.

Если у вас есть веские основания определять методы ActiveMarket::Walmart в другом файле, не стесняйтесь делать это. В конце концов, это все еще ваш проект, и вы должны решить, какой код должен принадлежать одному и тому же файлу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...