In ruby, you can do this:
d = [1, 2, 3]
a, b, c = d
a
, b
, and c
, will receive the values 1, 2, and 3, respectively.
d
, in this case in an Array
and ruby knows to assign it's contents to a
, b
, and c
. But, if d
were a Fixnum
, for example, only a
would be assigned to the value of d
while b
and c
would be assigned nil
.
What properties of d
allow it to be used for multiple assignment? In my exploring so far, I've only been able to make instances of subclasses of Array
behave in this way.
This is a very undocumented feature, and I'd use it with caution, but here we go. From the book The Ruby Programming Language:
When there are multiple lvalues and only a single rvalue, Ruby attempts to expand the rvalue into a list of values to assign. If the value is an array, Ruby expands the array so that each element becomes its own rvalue. If the value is not an array but implements a
to_ary
method, Ruby invokes that method and then expands the array it returns.
In Ruby 1.8 it is the to_ary
method,
in Ruby 1.9 documentation says it calls
It didn't work as expected . So, you have to define a to_splat
, but I haven't tested (no 1.9 in this machine)
to_ary
method in your object.
class Week
def to_ary
%w(monday tuesday wednesday thursday friday saturday sunday)
end
end
mon, tue, wed, thu, *weekend = Week.new
* %w(...)
Is a special notation for an array of words, if you are lazy to write ['monday', 'tuesday' ...]
What properties of
d
allow it to be used for multiple assignment?
d
has to be an Array
or be convertible to one. IOW it must be either an instance of the Array
class (or any of its subclasses) or respond to the to_ary
message:
def (not_an_array = Object.new).to_ary; [:foo, :bar, :baz] end
foo, bar, baz = not_an_array
foo # => :foo
bar # => :bar
baz # => :baz
Note that this is an instance of a more general pattern in Ruby: almost all methods in Ruby that expect an Array
, a String
, an Integer
or a Float
will also accept an object that responds to to_ary
, to_str
, to_int
or to_float
. And your own methods should, too, by the way!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.