Puede un Rubí método de rendimiento como un iterador o devolver una matriz según el contexto?
-
20-08-2019 - |
Pregunta
Tengo un método arbitrario en Ruby que los rendimientos de los múltiples valores, por lo que puede ser entregado a un bloque:
def arbitrary
yield 1
yield 2
yield 3
yield 4
end
arbitrary { |x| puts x }
Me gustaría modificar este método, de modo que, si no hay ningún bloque, sólo devuelve los valores como una matriz.Así que este constructo funcionaría así:
myarray = arbitrary
p a -----> [1, 2, 3, 4, 5]
Es esto posible en Ruby?
Solución
Hay una sintaxis para eso:
def arbitrary(&block)
values = [1, 2, 3, 4]
if block
values.each do |v|
yield v
end
else
values
end
end
Nota:
yield v
Se puede reemplazar con:
block.call v
Otros consejos
def arbitrary
values = [1,2,3,4]
return values unless block_given?
values.each { |val| yield(val) }
end
arbitrary { |x| puts x }
arbitrary
En ruby 1.9+ puede utilizar Enumerador para implementar esto.
def arbitrary(&block)
Enumerator.new do |y|
values = [1,2,3,4]
values.each { |val| y.yield(val) }
end.each(&block)
end
Tiene la ventaja de que funciona para infinitos arroyos demasiado:
# block-only version
#
def natural_numbers
0.upto(1/0.0) { |x| yield x }
end
# returning an enumerator when no block is given
#
def natural_numbers(&block)
Enumerator.new do |y|
0.upto(1/0.0) { |x| y.yield(x) }
end.each(&block)
end
Pero la mayoría de los idiomáticas manera de hacerlo es de la guardia de su método con to_enum(your_method_name, your_args)
así:
def arbitrary
return to_enum(:arbitrary) unless block_given?
yield 1
yield 2
yield 3
yield 4
end
Este es un modismo que ruby núcleo de bibliotecas de uso en varios lugares.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow