Является ли Ruby идиоматическим добавление метода Assert() в класс ядра Ruby?

StackOverflow https://stackoverflow.com/questions/147969

  •  02-07-2019
  •  | 
  •  

Вопрос

Я расширяю свое понимание Ruby, написав на Ruby эквивалент xUnit Кента Бека.Python (на котором пишет Кент) имеет широко используемый метод Assert().Руби нет.Я думаю, добавить это будет легко, но является ли Kernel подходящим местом для этого?

КСТАТИ, Я знаю о существовании различных фреймворков Unit в Ruby. - это упражнение для изучения идиом Ruby, а не для того, чтобы «что-то сделать».

Это было полезно?

Решение

Нет, это не лучшая практика.Лучшая аналогия с Assert() в Ruby — это просто повышение

 raise "This is wrong" unless expr

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

Другие советы

Я думаю, что использование утверждений в Ruby вполне допустимо.Но вы говорите о двух разных вещах:

  • Фреймворки xUnit используют assert методы проверки ожиданий от тестов.Они предназначены для использования в тестовом коде, а не в коде приложения.
  • Некоторые языки, такие как C, Java или Python, включают assert конструкция, предназначенная для использования внутри кода ваших программ для проверки ваших предположений об их целостности.Эти проверки встроены внутри самого кода.Это утилиты не для тестирования, а для разработки.

Я недавно написал твердое_утверждение:небольшая библиотека Ruby, реализующая утилиту утверждения Ruby а также пост в моем блоге, объясняющий его мотивацию..Это позволяет вам писать выражения в форме:

assert some_string != "some value"
assert clients.empty?, "Isn't the clients list empty?"

invariant "Lists with different sizes?" do
    one_variable = calculate_some_value
    other_variable = calculate_some_other_value
    one_variable > other_variable
end    

И их можно деактивировать так assert и invariant оцениваются как пустые утверждения.Это позволит вам избежать проблем с производительностью в производстве.Но заметьте, что Прагматичные программисты не рекомендую их деактивировать.Вам следует деактивировать их только в том случае, если они действительно влияют на производительность.

Что касается ответа о том, что идиоматический способ Ruby использует обычный raise высказыванию, мне кажется, ему не хватает выразительности.Одно из золотых правил ассертивного программирования — не использовать утверждения для нормальной обработки исключений.Это две совершенно разные вещи.Если вы используете один и тот же синтаксис для обоих из них, я думаю, ваш код будет более непонятным.И, конечно же, вы теряете возможность их деактивировать.

Вы можете убедиться, что использование утверждений — это хорошо, потому что две обязательные к прочтению классические книги, такие как Программист-прагматик: от подмастерья до мастера и Код завершен посвящайте им целые разделы и рекомендуйте их использование.Еще есть хорошая статья под названием Программирование с утверждениями они очень хорошо иллюстрируют, что такое ассертивное программирование и когда его использовать (оно основано на Java, но концепции применимы к любому языку).

По какой причине вы добавили метод Assert в модуль ядра?Почему бы просто не использовать другой модуль под названием Assertions или что-то?

Так:

module Assertions
  def assert(param)
    # do something with param
  end

  # define more assertions here
end

Если вам действительно нужно, чтобы ваши утверждения были доступны повсюду сделайте что-то вроде этого:

class Object
  include Assertions
end

Отказ от ответственности:Я не проверял код, но в принципе сделал бы так.

Это не особенно идиоматично, но я думаю, что это хорошая идея.Особенно если сделать так:

def assert(msg=nil)
    if DEBUG
        raise msg || "Assertion failed!" unless yield
    end
end

Таким образом, если вы решите не запускать DEBUG (или какой-либо другой удобный переключатель, в прошлом я использовал Kernel.do_assert), это не повлияет.

Насколько я понимаю, вы пишете свой собственный набор тестов, чтобы лучше познакомиться с Ruby.Таким образом, хотя Test::Unit может быть полезен в качестве руководства, вероятно, это не то, что вам нужно (потому что он уже выполнил свою работу).

Тем не менее, утверждение Python (по крайней мере, для меня) более похоже на C. утверждать(3).Он не предназначен специально для модульных тестов, а скорее для выявления случаев, когда «этого никогда не должно происходить».

Встроенные модульные тесты Ruby склонны рассматривать проблему так: каждый отдельный класс тестовых примеров является подклассом Прецедент, и это включает в себя оператор «assert», который проверяет достоверность переданной ему информации и записывает ее для отчета.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top