#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. Я просто ищу плавную интеграцию между частями… с таким подходом, как «Указать правильное направление» с предупреждением в текущем выпуске, а затем «наказать» исключение, вызывающее исключение в основном выпуске