Стоит ли возвращать объект, тип которого меняется в зависимости от внутренней логики метода?
Например.:
class Error
attr_reader :details
def initialize(details)
@details = details
end
end
def div(a, b)
return Error.new("error: division by zero") if b == 0
a / b
end
# declare foo, bar here
result = div(foo, bar)
if result.is_a?(Error)
puts result.details
else
puts "result of division: #{result}"
end
Как видите, метод div возвращает либо экземпляр Error, либо экземпляр Integer.
Является ли это плохой практикой (и почему)? Нарушает ли это принцип единой ответственности?
Кстати, я понимаю, что другим вариантом может быть возврат хеша { error: error, div_result: div_result }, но мне любопытно, можно ли его заменить только одним единственным объектом.
Спасибо.
🤔 А знаете ли вы, что...
Ruby имеет богатую стандартную библиотеку, которая упрощает разработку приложений.
Вы, кажется, заново изобретаете велосипед. В Ruby уже есть обработка исключений , а также ZeroDivisionError, которая возникает при делении целого числа на ноль:
def div(a, b)
a / b
end
begin
result = div(6, 0)
puts "result of division: #{result}"
rescue ZeroDivisionError => e
puts "error: #{e.message}"
end
# prints "error: divided by 0"
Обратите внимание, что ваш метод div
также не нужен, вы также можете написать result = 6 / 0
.
Стоит ли возвращать объект, тип которого меняется в зависимости от внутренней логики метода?
«тип» — сложный термин в Ruby. Я предполагаю, что вы имеете в виду что-то вроде «экземпляр определенного класса», например, целое число или строку? Это действительно зависит. Для большинства методов это, безусловно, было бы хорошей идеей, но из этого правила есть хорошие исключения.
1 + 2 #=> 3 (Integer)
1 + 2.0 #=> 3.0 (Float)
1 + 2r #=> (3/1) (Rational)
String#index обычно возвращает целое число, но также может возвращать nil
, чтобы указать «не найдено»:
"hello".index("o") #=> 4 (Integer)
"hello".index("x") #=> nil (NilClass)
Array#[] возвращает любой объект, хранящийся по указанному индексу, поэтому возвращаемые значения произвольны:
a = [123, :foo, "bar"]
a[0] #=> 123 (Integer)
a[1] #=> :foo (Symbol)
a[2] #=> "bar" (String)
a[3] #=> nil (NilClass)