Скажем, у меня есть родительский класс, инициализатор имеет аргумент со значением по умолчанию:Избегайте повторения именованных аргументов по умолчанию при вызове суперкласса инициализатору в Руби (2.1+)
class Parent
attr_reader :foo
def initialize(foo: 123)
@foo = foo
end
end
Я хочу создать подкласс, который имеет то же значение по умолчанию для foo
. Я могу это сделать, если я повторю заявление:
class Child < Parent
attr_reader :bar
def initialize(foo: 123, bar: 456)
super(foo: foo)
@bar = bar
end
end
Однако, это означает, что я должен написать 123
дважды. Если я стараюсь не повторять его, оставив его -
class Child < Parent
attr_reader :bar
def initialize(foo:, bar: 456)
super(foo: foo)
@bar = bar
end
end
- это теперь означает, что ранее опциональный, по умолчанию foo
теперь требуется подкласс, и я на самом деле не получаю никакой пользы от значения по умолчанию. не
Я думал, что я мог бы быть в состоянии настроить его nil
в подклассе -
class Child < Parent
attr_reader :bar
def initialize(foo: nil, bar: 456)
super(foo: foo)
@bar = bar
end
end
- но нет; Child.new(bar:789).foo
сейчас nil
, когда я хотел был 123
.
Я не могу оставить оставить аргумент из полностью, либо -
class Child < Parent
attr_reader :bar
def initialize(bar: 456)
super(foo: foo)
@bar = bar
end
end
- потому что тогда, если я пытаюсь указать его (Child.new(foo: 345, bar:789)
) Я получаю unknown keyword: foo (ArgumentError)
.
Есть ли какой-либо способ на самом деле оставить аргумент, а не давать ему значение по умолчанию? И/или способ позволить инициализатору принимать произвольные дополнительные имена paraemetrs и передавать их в свой инициализатор суперкласса?
Update: я придумал следующий хак (ручной прокатки мои собственные «параметры по умолчанию», в основном), но я не очень рад.
class Parent
attr_reader :foo
def initialize(foo: nil)
@foo = foo || 123 # faking 'default'-ness
end
end
class Child < Parent
attr_reader :bar
def initialize(foo: nil, bar: 456)
super(foo: foo)
@bar = bar
end
end
Несомненно, есть еще один способ Ruby-ish для этого?