Да это эквивалентно, но позволяет базовому коду изменять реализацию того, что пустой () на самом деле означает в зависимости от OS/Hardware/anything, и не влияют на Ваш код вообще. Существует подобная практика в Java и.NET
Huh, you are entirely correct that the object still lives even if initialize
raises an exception. However, it will be quite hard for anyone to hang on to a reference unless you leak self
out of initialize
like the following code I just wrote does:
>> class X
>> def initialize
>> $me = self
>> raise
>> end
>> def stillHere!
>> puts "It lives!"
>> end
>> end
=> nil
>> t = X.new
RuntimeError:
from (irb):14:in `initialize'
from (irb):20:in `new'
from (irb):20
>> t
=> nil
>> $me
=> #<X:0xb7ab0e70>
>> $me.stillHere!
It lives!
Я не уверен насчет этого утверждения:
Из того, что я сделал до сих пор, если я подниму исключение в initialize (), объект все еще создается, но будет в недопустимое состояние (например, некоторые nil значения в переменных экземпляра).
class Foo
def initialize(num)
raise ArgumentError.new("Not valid number") if num > 1000
@num = num
end
end
f = Foo.new(4000) #=> n `initialize': not valid (RuntimeError)
Если я правильно читаю ваш вопрос, вам нужно примерно следующее:
class SerialNumber
VALID_SERIAL_NUMBERS = (0..10,000,000,000)
def initialize(n)
raise ArgumentError.new("Serial numbers must be positive integers less than 10 Billion") unless VALID_SERIAL_NUMBERS.include?(n)
@n = n
end
end
Не беспокойтесь, что SerialNumber.new создает перед этим вызывается метод initialize
- он будет очищен, если возникнет ошибка.
Использование проверяемого модуля кажется действительно подходящим для контекста.
Вот пример того, как его использовать:
class Person
include Validatable
validates_numericality_of :age
end
Для вычисления чисел только в определенном диапазоне это будет:
class Person
include Validatable
validates_numericality_of :age
validates_true_for :age, :logic => lambda { (0..100).include?(age) }
end
Это, конечно, подтвердит, что возраст находится в диапазоне от 0 до 100.