Make the object behave like an array for parallel assignment in ruby

Suppose you do this in Ruby:

ar = [1, 2]
x, y = ar

Then x == 1 and y == 2. Is there a way that I can define in my own classes that will give the same effect? eg.

rb = AllYourCode.new
x, y = rb

So far, all I could do with that purpose was to do x == rb and y = nil. Python has a function like this:

>>> class Foo:
...     def __iter__(self):
...             return iter([1,2])
...
>>> x, y = Foo()
>>> x
1
>>> y
2
+5
source share
3 answers

Yeah. Define #to_ary. This will allow your object to be considered as an array for assignment.

irb> o = Object.new
=> #<Object:0x3556ec>
irb> def o.to_ary
       [1, 2]
     end
=> nil
irb> x, y = o
=> [1,2]
irb> x
#=> 1
irb> y
#=> 2

#to_a #to_ary , #to_a , #to_ary , . .

+7

:

class AllYourCode
   def to_a
     [1,2]
   end
end

rb = AllYourCode.new
x, y = *rb
p x
p y

Splat to_ary, to_a. , , , Array , Array.

, - , :

# swap
x, y = y, x

# multiple return values
quot, rem = a.divmod(b)

# etc.
name, age = "Person", 100

, , (Array), .

+2

, . AllYourCode Array, .

Ruby , , rvalue, . . lvalue, .

def foo 
  return "a", "b", "c" # three rvalues
end

x = foo # => x == ["a", "b", "c"]

lvalue ( , ), rvalues ​​ .

x, y, z = foo # => x == "a", y == "b", z == "c"
x, y = foo    # => x == "a", y == "b"
x, = foo      # => x == "a"

, , .

def bar
  ["a", "b", "c"]
end

x = bar       # => x == ["a", "b", "c"]
x, y, z = bar # => x == "a", y == "b", z == "c"
x, y = bar    # => x == "a", y == "b"
x, = bar      # => x == "a"

, , rb , x y .

+1

All Articles