5

関数があるとしましょう

def odd_or_even n
  if n%2 == 0
    return :even
  else
    return :odd
  end
end

そして、私は単純な列挙可能な配列を持っていました

simple = [1,2,3,4,5]

そして、 do-end ブロックを使用して、関数でマップを実行しました。

simple.map do
  |n| odd_or_even(n)
end
# => [:odd,:even,:odd,:even,:odd]

そもそも関数を定義せずに、どうすればこれを行うことができますか? 例えば、

# does not work
simple.map do |n|
  if n%2 == 0
    return :even
  else
    return :odd
  end
end

# Desired result:
# => [:odd,:even,:odd,:even,:odd]

は有効なルビではなく、コンパイラはそれについて考えただけで私に腹を立てます。しかし、どうすれば同等のものを実装できますか?

編集

実際には、私の問題に対する解決策は、その背後にある動機/理由よりもはるかに重要であり、ルビーブロックがどのように機能するかをより理解するのに役立ちます:)

4

3 に答える 3

13

あなたはとても近いです。s を削除するだけで、returnゴールデンになります。

これは、渡されたブロックがラムダではなくmapproc (つまり、 で作成されたもの) であるためです。Proc.newproc 内のAreturnは、proc から飛び出すだけではなく、proc を実行した (つまり、呼び出さcallれた) メソッドから飛び出します。一方、ラムダ内のリターンは、ラムダだけから飛び出します。

このprocメソッドは、Ruby 1.8 ではラムダを返し、Ruby 1.9 では Proc を返します。おそらく、このメソッドを使用せずに、使用する構成を明示することをお勧めします。

これを試していたときは、IRB またはプレーンな Ruby スクリプトを使用していたと思います。

a = Proc.new { return }
a.call # fails. Nothing to return from.

def foobar
  a = Proc.new { return }
  a.call
  puts 'hello' # not reached. The return within the proc causes execution to jump out of the foobar method.
end
foobar # succeeds, but does not print 'hello'. The return within the proc jumps out of the foobar method.

b = lambda { return }
b.call # succeeds. The return only returns from the lambda itself.

def bazquux
  b = lambda { return }
  b.call
  puts 'hello' # this is reached. The lambda only returned from itself.
end
bazquux # succeeds, and prints 'hello'

これから学ぶべき教訓は、できない場合を除いて、暗黙のリターンを使用することです。

于 2010-06-15T01:30:10.597 に答える
9

これは重複した質問である可能性があると思いますが、ブロックから値を与えるには、次を使用しますnext

simple.map do |n|
  if n%2 == 0
    next :even
  else
    next :odd
  end
end
于 2010-06-15T03:13:05.953 に答える
3

アンドリューの答えを使用した最短のバリアント:

simple.map { |n| next :even if n % 2 == 0; :odd }
于 2012-05-05T21:00:27.767 に答える