メソッドから2つ以上の値を返す


105

メソッドから複数の値を返す可能性はありますか?このようなもの:

def someMethod()
  return ["a", 10, SomeObject.new]
end

[a, b, c] = someMethod

回答:


160
def sumdiff(x, y)
  return x+y, x-y
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

テキスト形式ではなく、コード形式を使用する必要があります。4つのスペースをインデントすると、irbの>>プロンプトによって引き起こされる奇妙さがなくなります。
Chris Lutz、

4
:明示的なリターンを非慣用ルビーとみなされているので、あなたはまた、明示的にリストに戻り値を置くことによって、暗黙的なリターンを使用することができますdef foo_and_bar; ['foo', 'bar']; end
デニス・

43

Rubyには、構造化バインドの限定された形式があります。

ary = [1, 2, 3, 4]
a, b, c = ary
p a # => 1
p b # => 2
p c # => 3

a, b, *c = ary
p c # => [3, 4]

a, b, c, d, e = ary
p d # => 4
p e # => nil

また、バインドの構造化には制限があります。

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

これらの2つの形式を次のように組み合わせることができます。

a, b = b, a # Nice way to swap two variables

a, b = 1, 2, 3
p b # => 2

def foo; return 1, 2 end
a, b = foo
p a # => 1
p b # => 2

バインドの構造化/構造化で実行できる他のいくつかの処理があります。*右側にあるsplat演算子()の使用を示していません。ネストを表示しませんでした(括弧を使用)。ブロックまたはメソッドのパラメーターリストで構造化バインドを使用できることは示しませんでした。

これは前菜です。

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]

16

複数の値を返すことはしばしば便利ですが、私は通常、それが新しいオブジェクト要件へのポインタであることを発見しました。

つまり、通常、これらの戻り値は意味/コンテキストで密接に結び付いており、そのように渡されます。したがって、これらの場合、これらを結び付ける新しいオブジェクトを作成します。これは、私が認識できる特定のコードのにおいです。


4
より多くの自由、より多くの責任。経験豊富なルビイストはそれを利用していくつかの美しいコードを書きます。一方、ルビーの新人は物事を悪化させる可能性があります。
fengd 2013年

1
まあ明らかにそれは常にそうだとchunkは限らないか、そうでなければ何かが存在しないでしょう。優れた原則ですが。コードは確かににおいがします。ロックオン。
Darth Egregious

6

次のように配列を返すこともできます

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

これは機能的には

def sumdiff(x, y)
    return x+y, x-y
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.