Метод установки (присваивание) с несколькими аргументами - PullRequest
16 голосов
/ 14 февраля 2012

У меня есть собственный класс, и я хочу иметь возможность переопределить оператор присваивания.Вот пример:

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

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

Ответы [ 2 ]

15 голосов
/ 14 февраля 2012

Из-за синтаксического сахара методов, имена которых оканчиваются на =, единственный способ, которым вы можете фактически передать несколько параметров в метод, - обойти синтаксический сахар и использовать 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

Однако это кажется мне грубым подломом.Я бы использовал имя метода, не связанного с назначением, с несколькими аргументами, если они вам нужны.


Альтернативное предложение: если единственными направлениями являются :forward и :backward, как насчет:

def forward_strategy=( name )
  @strategy << name
  @strategy.direction = :forward
end

def reverse_strategy=( name )
  @strategy << name
  @strategy.direction = :backward
end
2 голосов
/ 14 февраля 2012

Проблема в

def strategy=(strategy, direction = :forward)
  @strategy = strategy
  @strategy.direction = direction
end

Когда вы устанавливаете

h.strategy = :mystrategy, :backward

, вы фактически переопределяете исходный экземпляр @strategy.После этого вызова @strategy является экземпляром Symbol, а не MyArray.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...