Ruby - 覆盖/启用多个赋值(例如`a,b,c = d,e,f`)

时间:2010-12-28 02:53:44

标签: ruby

在红宝石中,你可以这样做:

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

abc将分别收到值1,2和3。

d,在本例中为Array,ruby知道将其内容分配给abc。但是,如果dFixnum,则只有a会被分配给dbcnil被分配d

Array的哪些属性允许它用于多次分配?在我到目前为止的探索中,我只能使{{1}}的子类的实例以这种方式运行。

2 个答案:

答案 0 :(得分:11)

这是一个非常无证的功能,我会谨慎使用它,但是我们走了。摘自“红宝石编程语言”一书:

  

当有多个左值和   Ruby试图只有一个rvalue   将rvalue扩展为列表   要分配的值。如果值是   数组,Ruby扩展数组,以便   每个元素都成为自己的右值。   如果值不是数组但是   实现了to_ary方法,Ruby   调用该方法,然后展开   它返回的数组。

在Ruby 1.8中,它是to_ary方法,Ruby 1.9文档中的称它调用to_splat,但我没有测试过(在这台机器上没有1.9) < sub>它没有按预期工作。因此,您必须在对象中定义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' ...]

,这是一个单词数组的特殊表示法

答案 1 :(得分:7)

  

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中的几乎所有方法都期望ArrayStringInteger或{{1} }还将接受响应Floatto_aryto_strto_int的对象。顺便说一下,你的自己的方法也应该这样!