En el ejemplo que sigue escribimos un módulo
Functional que usamos para extender
las clases Proc y Method con dos operaciones.
f <= a toma una operación binaria
implantada via una lambda, proc o method f como primer
operando y un enumerable a como segundo. Retorna el resultado
de operar todos los elementos de a con f (esto es hace una reducción):
1] pry(main)> require './functional'
=> true
[2] pry(main)> a = 1..5
=> 1..5
[3] pry(main)> sum = lambda { |x,y| x+y }
=> #<Proc:0x007f94ef3b8018@(pry):3 (lambda)>
[4] pry(main)> sum <= a
=> 15
f | a aplica el Proc f a cada uno de los elementos del
enumerable a retornando un enumerable:
14] pry(main)> a = 1..5
=> 1..5
[15] pry(main)> h = lambda { |x| 2*x }
=> #<Proc:0x007fd19ca482b8@(pry):14 (lambda)>
[16] pry(main)> h | a
=> [2, 4, 6, 8, 10]
Sigue un ejemplo de uso mas complicado:
if __FILE__ == $0
a = (1..5).to_a
sum = lambda {|x,y| x+y } # A function to add two numbers
mean = (sum<=a)/a.size.to_f # Or sum.reduce(a) or a.inject(&sum)
puts mean # 3.0
deviation = lambda {|x| x-mean } # Function to compute difference from mean
print "#{deviation|a}\n" # [-2, -1, 0, 1, 2]
square = lambda {|x| x*x } # Function to square a number
puts (sum<=square|(deviation|a)) # 10 = 4 + 1 + 4 + 1
standardDeviation = Math.sqrt((sum<=square|(deviation|a)).to_f/(a.size-1))
puts standardDeviation # sqrt(10/4) = 1.5811388300841898
end
Esta es la solución a los requisitos especificados:
[~/Chapter6MethodsProcsLambdasAndClosures]$ cat -n functional.rb | head -16
1 module Functional
2
3 def apply(enum)
4 enum.map &self
5 end
6 alias | apply
7
8 def reduce(enum)
9 enum.inject &self
10 end
11 alias <= reduce
12 end
13
14 # Add these functional programming methods to Proc and Method classes.
15 class Proc; include Functional; end
16 class Method; include Functional; end
Casiano Rodriguez León 2015-01-07