Подтвердить что ты не робот

Метод 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.
Важная часть состоит в том, что я хочу иметь возможность назначить стандартное значение параметру направления.

Любые подсказки для выполнения этой работы высоко оценены.

4b9b3361

Ответ 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.

Что вы хотите сделать? Заменить объект или обновить его?