假设我有一个功能
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]
不是有效的ruby,编译器甚至在考虑它时会生我的气。但是,我如何实现同等类型的东西呢?
修改的
实际上,我的问题的解决方案对我来说比它背后的动机/推理要少得多,以帮助我更多地了解ruby如何阻止工作:)
答案 0 :(得分:13)
你真是太近了。只需删除return
即可,您就是黄金。
这是因为传递给map
的块是proc(即使用Proc.new
创建的),而不是lambda。 proc中的return
不会跳出proc-it跳出执行的方法(即调用call
)proc。另一方面,lambda中的返回只跳出lambda。
proc
方法在Ruby 1.8中返回一个lambda,在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'
从中学到的教训是使用隐式回报,除非你不能,我想。
答案 1 :(得分:9)
我怀疑这可能是一个重复的问题,但要从块中提供值,请使用next
simple.map do |n|
if n%2 == 0
next :even
else
next :odd
end
end
答案 2 :(得分:3)
使用安德鲁答案的最短变种:
simple.map { |n| next :even if n % 2 == 0; :odd }