Ruby - переопределение / включение множественного назначения (например, `a, b, c = d, e, f`) - PullRequest
11 голосов
/ 28 декабря 2010

В ruby ​​вы можете сделать это:

d = [1, 2, 3]
a, b, c = d

a, b и c получат значения 1, 2 и 3 соответственно.

d, в этом случае в Array и ruby ​​знает, как присвоить его содержимое a, b и c. Но, если бы d было, например, Fixnum, только a было бы присвоено значению d, тогда как b и c было бы присвоено nil.

Какие свойства d позволяют использовать его для множественного присваивания? В моем исследовании до сих пор я только мог заставить экземпляры подклассов Array вести себя таким образом.

Ответы [ 2 ]

11 голосов
/ 28 декабря 2010

Это очень недокументированная функция, и я бы использовал ее с осторожностью, но мы здесь. Из книги "Язык программирования Ruby":

Когда есть несколько значений и только одно значение, Ruby пытается разверните значение в список значения для назначения. Если значение является массив, Ruby расширяет массив так, чтобы каждый элемент становится своим собственным значением. Если значение не является массивом, но реализует метод to_ary, Ruby вызывает этот метод, а затем расширяет массив, который он возвращает.

В Ruby 1.8 это метод to_ary, в документации по Ruby 1.9 говорится, что он вызывает to_splat, но я не тестировал (на этой машине нет 1.9) Это не так т работает как ожидалось . Итак, вы должны определить метод to_ary в вашем объекте.

class Week
  def to_ary
    %w(monday tuesday wednesday thursday friday saturday sunday)
  end
end

mon, tue, wed, thu, *weekend = Week.new

* %w(...) Специальная запись для массива слов, если вам лень писать ['monday', 'tuesday' ...]

7 голосов
/ 28 декабря 2010

Какие свойства d позволяют использовать его для множественного назначения?

d должно быть Array или быть конвертируемым в единицу.IOW это должен быть экземпляр класса Array (или любого из его подклассов) или ответ на сообщение to_ary:

def (not_an_array = Object.new).to_ary; [:foo, :bar, :baz] end

foo, bar, baz = not_an_array

foo # => :foo
bar # => :bar
baz # => :baz

Обратите внимание, что это экземпляр более общего шаблона вRuby: почти все методы в Ruby, ожидающие, что Array, String, Integer или Float также примут объект, который отвечает на to_ary, to_str, to_int или to_float.И ваши собственные методы тоже, кстати, должны!

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