Избегание `Строка не может быть принудительно приведена в BigDecimal`

Я написал логику / метод, который возвращает два разных объекта (Integer и String), так что для примера возвращаемое значение будет 5000.00 Dollars,

Поэтому я написал метод для моих ожиданий. Смотрите логику ниже:

s = x.currency # This assigns the string `dollarpounds` to s
a = s.slice(6..11) # This slice off 6 to 11 and returns just pounds to variable a
price_value = x.price # This is integer (price)
volume_volume = x.volume # This is integer (volume)
value = price_value * volume_volume # This multiplies price and volume and returns the value
value + "#{a}" # Now this throws TypeError-String can't be coerced into BigDecimal

Поэтому, чтобы покончить с этой проблемой, я реорганизовал свой метод, но я думаю, что его очень оскорбительный фрагмент можно считать мастером в Ruby. Как мне переписать эту переработанную логику ниже, чтобы быть достаточно умным, как код Ruby?

Итак, вот что я сделал:

Переосмысленная логика. Возвращается 5000.00 Dollars как и ожидалось

s = x.currency # This assigns the string `dollarpounds` to s
a = s.slice(6..11) # This slice off 6 to 11 and returns just pounds to variable a
price_value = x.price # This is integer (price)
volume_volume = x.volume # This is integer (volume)
value = price_value * volume_volume # This multiplies price and volume and returns the value
[[value].join(' '), "#{a}"].split(',').join(' ') # This returns 5000.00 Dollars

Столько же мой re-factored код работает, я все еще чувствую, что это оскорбительно для сообщества ruby ​​и может быть лучше, чем это. Любая помощь, как сделать это лучше, будет оценена.

2 ответа

Решение

Используйте интерполяцию:

"#{value} #{a}"

Или конкатенация:

value.to_s + ' ' + a

Довольно забавно, как я использовал интерполяцию в последней строке рефактора [[value].join(' '), "#{a}"].split(',').join(' ') и я никогда не думал, что это просто - использовать интерполяцию. Помимо предложенной интерполяции в ветке ответов, я смог сделать код более простым, меньшим и более быстрым.

s = x.currency
a = s.slice(6..11)
value = x.price * x.volume
"#{value} #{a}" # Thanks to @PavelPuzin for this suggestion in this line.

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

require "benchmark"

numbers = (1..1000).to_a

n = 1000
Benchmark.bm do |x|
  x.report { n.times do   ; numbers.each_cons(2) {|a, b| "#{a} #{b}"}; end }
  x.report { n.times do   ; numbers.each_cons(2) {|a, b| [a, b].join(" ")}; end }
end 

###############################Result###################################
    user     system      total        real
   0.467287   0.000731   0.468018 (  0.468641)
   1.154991   0.001563   1.156554 (  1.157740)
Другие вопросы по тегам