Я пишу библиотеку, которые зависят от определенного драгоценного камня. Я требую драгоценного камня и использую его в моем коде, и все - целая и невредимая легкая рыбачья плоскодонка, пока драгоценный камень установлен на машине пользователя. но что, если это не?!
Я думал, что это - прекрасная причина, которую я могу спасти от потребовать команды и распечатать сообщение к выводу, чтобы сообщить пользователю о недостающем драгоценном камне и закончить его корректно, но я получаю ошибку!
Могли Вы говорить мне, как это должно быть сделано или что не так с этой частью кода:
begin
require "some_gem"
rescue
puts "please install some_gem first!"
end
По соглашению следует добавить событие OnResizing
, которое срабатывает сразу после изменения, но не изменяется, а затем запустить OnResize
после изменения размера. Старое значение будет получено из события EventArg
в событии OnResizing
.
Изменить:
создаете ли вы собственное событие или запускаете один из включенных элементов управления?
Если вы делаете собственное событие, вы можете извлечь из EventArg
и сделать что-то вроде ResityEventArg
, которые включают размер нужной вещи.
Я использую ResityEventArg
для событий Resize
и OnResizing
и продолжаю следовать тому, что я сказал ранее.
Или если вы знаете, какой это тип управления, вы можете поместить Отправитель объекта
в тип и затем прочитать свойство.
Ваше помещение неисправно. x * (a + b)
, является (в общем случае) не менее точным, чем x * a + x * b
. На самом деле, она часто будет более точной, потому что она выполняет только две операции с плавающей точкой (и, следовательно, несет только две ошибки округления), тогда как последняя выполняет три операции.
Если вы знаете что-то об ожидаемом распределении значений для x
, a
и b
априори, то вы можете принять осознанное решение, но компиляторы почти никогда не имеют доступа к такому типу информации.
Что, кроме того, если человек, пишущий программу, на самом деле имел в виду x * (a + b)
и конкретно хотел точно округлить, которые вызваны этой конкретной последовательностью операций? Такие вещи на самом деле довольно распространены в высококачественных числовых алгоритмах.
Лучше делать то, что написал программист, а не то, что, по вашему мнению, он мог задумать.
Edit -- Пример, иллюстрирующий случай, когда предложенное преобразование приводит к катастрофической потере точности: предположим,
x = 3.1415926535897931
a = 1.0e15
b = -(1.0e15 - 1.0)
Затем при оценке в double
получается:
x*(a + b) = 3.1415926535897931
, но
x*a + x*b = 3.0
-121--4716580- требуется
возникает исключение LoadError
, если не удается загрузить требуемую библиотеку. Однако никогда не восстанавливает LoadError
в любом месте, а StandardError
.
Если вы хотите восстановить LoadError
, вы должны сказать:
begin
require 'some_gem'
rescue LoadError
puts 'please install some_gem first!'
end
Еще лучше, убедитесь, что вы действительно печатаете правильную отсутствующую зависимость:
begin
require 'some_gem'
rescue LoadError => e
raise unless e.message =~ /some_gem/
puts 'please install some_gem first!'
end
(Это повторно вызывает то же самое исключение, которое было спасено из, в случае, если исключение действительно было вызвано какой-то другой отсутствующей библиотекой где-то еще. Вы не хотите печатать вводящую в заблуждение информацию, верно?)
В зависимости от того, какова целевая аудитория библиотеки и могут ли они быть напуганы тем, что обратная трассировка будет свалена на их консоль, вы можете повторитьподнять исключение в любом случае, вместо того, чтобы просто глотать его:
begin
require 'some_gem'
rescue LoadError => e
puts 'please install some_gem first!' if e.message =~ /some_gem/
raise
end
Или можно пропустить puts
и вместо этого создать исключение с сообщением, набором тому, что вы хотите сказать:
begin
require 'some_gem'
rescue LoadError => e
raise e.exception('please install some_gem first!') if e.message =~ /some_gem/
raise
end
За исключением того, что теперь исключение поднимается в неправильном месте и, таким образом, имеет неправильный номер строки и трассировку стека и, таким образом, вводит в заблуждение, но это легко исправить:
begin
require 'some_gem'
rescue LoadError => e
raise unless e.message =~ /some_gem/
friendly_ex = e.exception('please install some_gem first!')
friendly_ex.set_backtrace(e.backtrace)
raise friendly_ex
end
Теперь вы печатаете почти то же самое, что вы бы напечатали с puts
, , но у вас есть «правильное» исключение, которое, например, позволяет лучше отлаживать или позволяет потребителю вашей библиотеки спасти это исключение и обработать его своим путем, оба из которых были бы невозможны или, по крайней мере, трудны с вашим решением, которое просто проглатывает исключение.
begin
require "some_gem"
rescue LoadError
puts "message"
end