Functional Patterns in Ruby

Hexp

S-expressions for HTML

cries = %w[arrrr Arrrr ARRRRRRRRRR]

dom = H[:section, {class: 'arrrr'},
  cries.map {|arrrr| H[:p, arrrr] }
]

dom.replace('.arrrr p') {|element| element.add_class(:battle_cry) }
puts dom.to_html
<section class="arrrr">
  <p class="battle_cry">arrrr</p>
  <p class="battle_cry">Arrrr</p>
  <p class="battle_cry">ARRRRRRRRRR</p>
</section>

Immutability

FREEZE ALL THE THINGS!

class Foo
  def initialize(a,b)
    @a, @b = a.freeze, b.freeze
  end
end

Deep Freeze

[
 'pirates'.freeze,
 'parrots'.freeze
].freeze

There’s a gem for that

IceNine.deep_freeze([
 'pirates',
 'parrots'
])

Callable!

class Multiply
  def call(x,y)
    x*y
  end
end

Multiply.new.(2,3)

procable !

module Callable
  def to_proc
    method(:call).to_proc
  end
end

class Square
  include Callable

  def call(x)
    x*x
  end
end

[1,2,3].map(&Square.new) # => [1, 4, 9]

Curryable!

module Callable
  # ...
  def curry ; to_proc.curry ; end
end

class Multiply
  include Callable

  def call(x,y) ; x*x ; end
end

multiply_by_3 = Multiply.new.curry.(3)

[1,2,3].map(&multiply_by_3) # => [3, 6, 9]

Parameterizable!

class Harmonics
  def initialize(ratio = 1.61803398875, harmonic = 2)
    @ratio, @harmonic = ratio, harmonic
  end

  def call(in_value) ; out_value * factor  ; end
  def factor         ; @ratio ** @harmonic ; end
  def self.call      ; new.call            ; end
end

Pipelining

class ValueClass
  # ...snip...

  def |(callable)
    callable.call(self)
  end
end
new_value = value | MyCalculation \
  | MyCalculation.new(5) | ->(v) { v.foo }

API design

# This does not work
h << foo
h << bla
# This does... but ugly backslash
h = h << foo \
      << bla

API design

<<= to the rescue!

h = foo
h <<= H[:title, "Web Linguistics"]
h <<= H[:link, rel: 'stylesheet', href: 'stylesheets/stylesheet.css']
h <<= H[:script, src: file_uri_relative('javascripts/highlight.pack.js')]

Name your blocks

def do_x
  ->(_) { ... }
end

def only_y
  ->(_) { ... }
end

foo.map(&do_x).filter(&only_y)

Persistent Data Structures

AKA Clojure magic sauce

There’s a gem for that!

gem install hamster

Ruby 2.1

  • Sorta Generational GC

  • Sorta Tail Call Optimization

  • Frozen String Literals : "hello world"f

FIN