Метод Setter (присвоение) с несколькими аргументами
У меня есть пользовательский класс и вы хотите переопределить оператор присваивания.
Вот пример:
class MyArray < Array
attr_accessor :direction
def initialize
@direction = :forward
end
end
class History
def initialize
@strategy = MyArray.new
end
def strategy=(strategy, direction = :forward)
@strategy << strategy
@strategy.direction = direction
end
end
В настоящее время это не работает должным образом. при использовании
h = History.new
h.strategy = :mystrategy, :backward
[:mystrategy, :backward]
присваивается переменной стратегии, а переменная направления остается :forward
.
Важная часть состоит в том, что я хочу иметь возможность назначить стандартное значение параметру направления.
Любые подсказки для выполнения этой работы высоко оценены.
Ответы
Ответ 1
Из-за синтаксического сахара методов, имена которых заканчиваются на =
, единственный способ, которым вы действительно можете передать несколько параметров методу, - обходить синтаксический сахар и использовать send
...
h.send(:strategy=, :mystrategy, :backward )
... в этом случае вы можете просто использовать обычный метод с лучшими именами:
h.set_strategy :mystrategy, :backward
Однако вы можете переписать свой метод для автоматического удаления массивов значений, если вы знали, что массив никогда не легален для параметра:
def strategy=( value )
if value.is_a?( Array )
@strategy << value.first
@strategy.direction = value.last
else
@strategy = value
end
end
Тем не менее, это кажется грубым взломом. Я бы использовал имя метода non-assigment с несколькими аргументами, если они вам понадобятся.
Альтернативное предложение: если единственными направлениями являются :forward
и :backward
, то что:
def forward_strategy=( name )
@strategy << name
@strategy.direction = :forward
end
def reverse_strategy=( name )
@strategy << name
@strategy.direction = :backward
end
Ответ 2
Проблема
def strategy=(strategy, direction = :forward)
@strategy = strategy
@strategy.direction = direction
end
Когда вы устанавливаете
h.strategy = :mystrategy, :backward
вы фактически переопределяете исходный экземпляр @strategy
. После этого вызова @strategy
является экземпляром Symbol
, а не MyArray
.
Что вы хотите сделать? Заменить объект или обновить его?