Renvoie deux valeurs et plus d’une méthode

Est-il possible de retourner plusieurs valeurs de la méthode? Quelque chose comme ça:

def do() return ["a", 10, SomeObject.new] end [a, b, c] = do 

 def sumdiff(x, y) return x+y, xy end #=> nil sumdiff(3, 4) #=> [7, -1] a = sumdiff(3,4) #=> [7, -1] a #=> [7, -1] a,b=sumdiff(3,4) #=> [7, -1] a #=> 7 b #=> -1 a,b,c=sumdiff(3,4) #=> [7, -1] a #=> 7 b #=> -1 c #=> nil 

Ruby a une forme limitée de liaison déstructurante:

 ary = [1, 2, 3, 4] a, b, c = ary pa # => 1 pb # => 2 pc # => 3 a, b, *c = ary pc # => [3, 4] a, b, c, d, e = ary pd # => 4 pe # => nil 

Il a également une forme limitée de liaison structurante:

  a = 1, 2, 3 pa # => [1, 2, 3] 

Vous pouvez combiner ces deux formes comme suit:

 a, b = b, a # Nice way to swap two variables a, b = 1, 2, 3 pb # => 2 def foo; return 1, 2 end a, b = foo pa # => 1 pb # => 2 

Il y a plusieurs autres choses que vous pouvez faire avec destructuring / structuring bind. Je n’ai pas montré en utilisant l’opérateur splat ( * ) sur le côté droit. Je n’ai pas montré de nidification (en utilisant des parenthèses). Je n’ai pas montré que vous pouvez utiliser la liaison de déstructuration dans la liste de parameters d’un bloc ou d’une méthode.

Voici juste un apéritif:

 def foo(((a, b, c, d), e, *f), g, *h) local_variables.sort.each do |lvar| puts "#{lvar} => #{eval(lvar).inspect}" end end foo([[1, 2, 3], 4, 5, 6], 7, 8, 9) # a => 1 # b => 2 # c => 3 # d => nil # e => 4 # f => [5, 6] # g => 7 # h => [8, 9] 

Bien que le retour de plusieurs valeurs soit souvent utile, je trouve généralement que c’est un pointeur vers une nouvelle exigence d’object.

C’est-à-dire que je trouve généralement que ces valeurs de retour sont étroitement liées entre elles dans le sens / le contexte et sont transmises en tant que telles. Donc, dans ces cas, je créerais un nouvel object pour les lier ensemble. C’est une odeur de code particulière que j’ai appris à reconnaître.

Vous pouvez réaliser ce retour d’un tableau aussi, comme

 def sumdiff(x, y) [x+y, xy] end 

qui semble fonctionnellement équivalent à

 def sumdiff(x, y) return x+y, xy end