Ruby: Каков наилучший подход к отказу только от одного аргумента метода?

#ruby

#ruby

Вопрос:

Рассмотрим класс с методом, который раньше получал 2 аргумента, но теперь в новых версиях аргумент больше не нужен. Каков наилучший подход к отказу от аргумента этого метода?

У Ruby stdlib есть deprecate метод, который не одобряет весь метод, но я все еще хочу, чтобы метод существовал, ему просто не нужен один из аргументов, которые он использовал для получения, и уже был необязательным аргументом.

И примером может быть

 class DateValidator
  def date_valid?(date_string, fmt="%Y-%m-%d")
    # any check that does not even look for `_fmt` anymore
  end
  

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

Я хочу в ближайшее время изменить арность метода, чтобы явно исключить аргумент, но я хочу сделать это в новой версии, и я не хочу нарушать совместимость с классами, которые все еще передают второй аргумент, даже если в этом больше нет необходимости.

Итак, каким был бы наилучший подход для предупреждения об отказе от 2-го аргумента в этом примере?

Комментарии:

1. По умолчанию fmt аргумент равен нулю, и если он задан, отображается предупреждение.

2. @maxpleaner это действительно хороший момент … простой, но точно в точку! Не могли бы вы поместить свой комментарий в качестве ответа? В противном случае я не смогу пометить вопрос как отвеченный

3. У какого класса есть метод deprecate ?

4. Разрешение вызова нового метода с двумя аргументами, в этом случае вы бы проигнорировали один и выдали предупреждение, — это уродливая и потенциально опасная ошибка. Самый безопасный подход заключается в принятии только одного аргумента, позволяя создавать исключение, если предпринимается попытка передать два аргумента, и отслеживать и исправлять части всей вашей кодовой базы, которые в настоящее время вызывают метод с двумя аргументами. Обратите внимание, что предупреждение может быть легко пропущено, если это всего лишь одно сообщение среди многих.

5. Я мог бы дать ответ, он очень простой, но мне интересно, почему вы хотите отказаться от него. Второй аргумент уже необязателен (он имеет значение по умолчанию), поэтому вызов его с 1 или 2 аргументами все равно будет работать. Если вы действительно не хотите разрешать пользователю указывать это значение.

Ответ №1:

Вы можете проверить, предоставлен ли второй аргумент следующим образом:

   def date_valid?(date_string, fmt=nil)
    if fmt
      warn "second argument to `date_valid?` is deprecated (#{caller[-2]})"
    end
    fmt ||= "default value"
    # ... 
  end
  

Но, как я упоминал в комментарии, не уверен, почему вы вообще хотите отказаться от второго аргумента (в конце концов, это необязательно), если только не важно, чтобы пользователь не настраивал это значение

Комментарии:

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

2. проверка, был ли он передан, и отправка warn будет работать в значительной степени … тогда в будущей основной версии второй аргумент будет полностью удален.

3. Я просто ищу плавную интеграцию между частями… с таким подходом, как «Указать правильное направление» с предупреждением в текущем выпуске, а затем «наказать» исключение, вызывающее исключение в основном выпуске