我想在某些代码中减少变量定义;特别是那些只定义空哈希或数组的人。我发现的解决方案是:
原件:
my_array = Array.new
0..10.each do |i|
my_array << i
end
Redone版本:
0..10.each do |i|
( my_array ||= Array.new ) << i
end
当我在rails控制台中运行它们时会发生以下情况:运行原始版本后,我可以访问“my_array”,而使用重做版本时我无法...它仍然未定义。我做错了什么?
答案 0 :(得分:3)
一般来说,我发现如果你必须声明一个空容器,然后运行一个循环来填充内容,那么(几乎)总是有更好的方法。
以下是编写代码的改进方法:
my_array = (0..10).map do |i|
i # do your complex processing here
end
my_array # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
答案 1 :(得分:2)
在第二个示例中,变量my_array
是块的本地变量,因此它在块本身外部不可见。对于这类工作,我喜欢使用each_with_object
方法:
my_array = (1..10).each_with_object([]) do |i, my_array|
my_array << i
end
my_array
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
答案 2 :(得分:1)
因为修改后版本中my_array
的范围仅限于块
尝试定义全局变量
1.9.3-p448 :001 >
1.9.3-p448 :002 > [*0..10].each do |i|
1.9.3-p448 :003 > ( @my_array ||= Array.new ) << i
1.9.3-p448 :004?> end
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1.9.3-p448 :005 > @my_array
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1.9.3-p448 :006 >
在控制台中使用@
变量可提供全局范围
答案 3 :(得分:1)
在这种情况下,我喜欢使用Object#tap
方法,该方法比Enumerable#each_with_object
更通用:
my_array = [].tap do |my_array|
0..10.each { |i| my_array << i }
end