Если вам действительно нужно выполнять проверки типов, то да, вы проверяете только время выполнения. Код в вопросе в порядке. Вы также можете использовать .is_a?
.
def someFixNumMangler(input)
raise "wrong type: integer required" unless input.is_a?(FixNum)
other_stuff
end
Проверки могут иметь разные формы. Если вы ожидаете, скажем, строки, и вы вызываете на ней строковые методы (upcase
, gsub
и т. Д.), Код взорвется, если передается что-либо, кроме строки. Если, конечно, вы не передаете объект, который не является строкой, а ведет себя точно так же, как один (имеет те же методы, которые вы называете). В этом суть утиной печати.
Что делать, если ваш метод выглядит так?
def someFixNumMangler(input)
input = input.to_i
puts "got this: #{input} of #{input.class}"
end
someFixNumMangler(10)
someFixNumMangler('42')
someFixNumMangler(File)
# >> got this: 10 of Fixnum
# >> got this: 42 of Fixnum
# ~> -:2:in `someFixNumMangler': undefined method `to_i' for File:Class (NoMethodError)
# ~> from -:9:in `<main>'
Пока аргумент отвечает #to_i
, вы на самом деле не волнует, что его тип.
Я согласен с настроением. Общий подход, который я придерживаюсь, заключается в том, чтобы выполнить минимальную проверку, чтобы избежать * странных, бесполезных * ошибок (или Segfaults при работе с расширениями C), которые возникают позже при использовании общедоступного API библиотеки. Тип защитного программирования, который вы получаете, проверяя типы по всем методам, в Ruby не очень практичен. Вы можете покрыть некоторые пробелы в тестах и документации, оба из которых * хорошо поддерживаются. –