functional programing with ruby - pinedance/codenote GitHub Wiki
ref : RubyFunctionalProgramming
def df(f, *arg)
f.call(*arg) # equivalent to: f.(*arg)
end
f1 = ->(a,b){ a + b } # equivalent to: lambda{|a,b| a + b }
f2 = ->(a,b,c){ a + b * c }
df( f1, 1, 3 ) # => 4
df( f2, 1, 3, 2 ) # => 7
method
function
def f3(a,b)
a ** b
end
df( method(:f3), 3, 2 ) # => 9
send
function
def f3(a,b)
a ** b
end
send( :f3, 3, 2 ) # => 9
a = [1,2,3,4]
a.send( :join, ":" )
ref : Learning Ruby through Clojure
Returning more than one value from a function:
def get_position
[10, 20, 50]
end
x, y, z = get_position
puts “x = #{x}, y = #{y}, z = #{z}”
# x = 10, y = 20, z = 50
Argument destructuring:
peeps = [[“John”, [“male”, 28]], [“Jane”, [“female”,40]]]
peeps.each do |(name, (gender, age))|
puts “#{name} is a #{age} year old #{gender}”
end
# John is a 28 year old male
# Jane is a 40 year old female
general infinite loop:
# Given an infinite range, return the result of n+1
# for the first 10 items
(1..Float::INFINITY).map { |n| n+1 }.first(10)
# Don't hold your breath
lazy infinite loop:
(1..Float::INFINITY).lazy.map { |n| n+1 }.first(10)
=> [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Using lazy enumerators to work with large files in Ruby
- Lazy-loading the lines of the file using
each_line
File.open("moby.txt") do |f|
# Get the first 3 lines with the word "whale"
f.each_line.lazy.select { |line| line.match(/whale/i) }.first(3)
# Go back to the beginning of the file.
f.rewind
# Prepend the line number to the first three lines
f.each_line.lazy.each_with_index.map do |line, i|
"LINE #{ i }: #{ line }"
end.first(3)
f.rewind
# Get the first three lines containing "whale" along with their line numbers
f.each_line.lazy.each_with_index.map { |line, i| "LINE #{ i }: #{ line }" }.select { |line| line.match(/whale/i) }.first(3)
end
One of the best things you can do to speed up your Ruby app is to decrease the number of objects that are created. One annoying source of object allocations comes from the string literals that are sprinkled throughout most apps. Every time you do a method call like log("foobar"), you create a new String object. If your code calls a method like this thousands of times per second, that means you're creating (and garbage-collecting) thousands of strings per second. That's a lot of overhead! Fortunately, Ruby gives us a way out. If we freeze string literals, the Ruby interpreter will only create one String object and will cache it for future use. I've put together a quick benchmark showing the performance of frozen vs. non-frozen string arguments. It shows around a 50% performance increase.