functional programing with ruby - pinedance/codenote GitHub Wiki

functional programing with ruby

ref : RubyFunctionalProgramming

useful functions

reuse custom function

def df(f, *arg)
    f.call(*arg)    # equivalent to:  f.(*arg)
end

Lambda

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 Object

method function

def f3(a,b)
    a ** b
end

df( method(:f3), 3, 2 )     # => 9

use function like variables

send function

def f3(a,b)
    a ** b
end

send( :f3, 3, 2 )             # => 9
a = [1,2,3,4]
a.send( :join, ":" )

Destructuring

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

Lazy Sequences

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

Immutability

Object#freeze

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.

When to use freeze and frozen? in Ruby

⚠️ **GitHub.com Fallback** ⚠️