Struct
позволяет мне создать новый класс, который принимает аргументы и имеет хорошую семантику. Однако аргументы не являются обязательными, и их порядок требует согласования с определением:Метапрограмма, определяющая методы Ruby, которые принимают аргументы ключевых слов?
Point = Struct.new(:x, :y)
Point.new(111, 222)
#=> <point instance with x = 111, y = 222>
Point.new(111)
#=> <point instance with x = 111, y = nil>
я хотел бы что-то похожее на структуру, но использует именованные аргументы вместо:
Point = StricterStruct.new(:x, :y)
Point.new(x: 111, y: 222)
#=> <point instance with x = 111, y = 222>
Point.new(x: 111)
#=> ArgumentError
, которые могли бы выглядеть примерно так:
module StricterStruct
def self.new(*attributes)
klass = Class.new
klass.instance_eval { ... }
klass
end
end
Но что должно идти в скобки, чтобы определить initialize
метод на klass
, что:
- Требуется наличие аргументов ключевого слова без значения по умолчанию;
- ключевые слова задаются в виде массива символов в
attributes
; и - метод
initialize
присваивает их переменным экземпляра одного и того же имени
Мне нравится сообщение, которое я только что изменил, чтобы иметь очень похожую структуру, хотя я дал вам методы getter и setter для экземпляра_переменных. Извините, я был не так быстр, как вы отвечали на свой вопрос :). Также обратите внимание, что я обновил свой ответ, чтобы принять строки или символы и отформатировать их как snake_case. – engineersmnky
Не хотите сказать 'def self.new (* attribute_names_as_symbols)'? Кроме того, я считаю, что вы можете создать каждый аксессуар для чтения с помощью 'attr_reader sym'. Интересный вопрос. –
@CarySwoveland Да, это опечатка моей копии. Спасибо, что поймал это. Вы также правы, что attr_reader намного проще; Я должен был это понять! –