Skip to content

Instantly share code, notes, and snippets.

@klappradla
Last active October 21, 2016 21:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klappradla/3d4d248079039102ee02b13840e671c7 to your computer and use it in GitHub Desktop.
Save klappradla/3d4d248079039102ee02b13840e671c7 to your computer and use it in GitHub Desktop.
Procs vs. Lambdas (example)

Procs vs. Lambdas

Seem the same:

[1] pry(main)> pr = proc { p "Hi" }
=> #<Proc:0x007fdc7a1398f0@(pry):8>
[2] pry(main)> lam = -> { p "Hi" }
=> #<Proc:0x007fdc79c53110@(pry):9 (lambda)>
[3] pry(main)> pr.class
=> Proc
[4] pry(main)> lam.class
=> Proc
[5] pry(main)> pr.class == lam.class
=> true
[6] pry(main)> pr.call == lam.call
"Hi"
"Hi"
=> true

1st approach: lambda (works 🚜)

Unnecessary arguments...

def callback
  @callback ||= {
    0  => ->(a, b) { success(a) },
    10 => ->(a, b) { raise Error::A },
    11 => ->(a, b) { raise Error::B },
    12 => ->(a, b) { raise Error::C.new(b) },
    13 => ->(a, b) { success(a) },
    14 => ->(a, b) { handle(b) },
  }
end

def method_name
  resp   = conn.post("hello")
  body   = JSON.parse(resp).with_indifferent_access
  status = body[:status]
  callback[status].call(body, @params)
end


# alternative, better readability

def callback
  @callback ||= {
    0  => ->(a, _) { success(a) },
    10 => ->(_, _) { raise Error::A },
    11 => ->(_, _) { raise Error::B },
    12 => ->(_, b) { raise Error::C.new(b) },
    13 => ->(a, _) { success(a) },
    14 => ->(a, _) { handle(b) },
  }
end

2nd approach: lambda (does not work 😿)

NoMethod Error

def callback
  @callback ||= {
    0  => ->(a) { success(a) },
    10 => ->{ raise Error::A },
    11 => ->{ raise Error::B },
    12 => ->(_, b) { raise Error::C.new(b) },
    13 => ->(a) { success(a) },
    14 => ->(_, b) { handle(b) },
  }
end

3rd approach: proc (works 👯)

Procs do not check number of arguments.

def callback
  @callback ||= {
    0  => proc { |a| success(a) },
    10 => proc { raise Error::A },
    11 => proc { raise Error::B },
    12 => proc { |_, b| raise Error::C.new(b) },
    13 => proc { |a| success(a) },
    14 => proc { |_, b| handle(b) },
  }
end

4th approach: proc & default_proc

Hash can return default proc if key not found

def callback
  @callback ||= default.merge(
    10 => proc { raise Error::A },
    11 => proc { raise Error::B },
    12 => proc { |_, b| raise Error::C.new(b) },
    14 => proc { |_, b| handle(b) },
  )
end

def default
  Hash.new { proc { |a| success(a) } }
end

Links

What Is the Difference Between a Block, a Proc, and a Lambda in Ruby?

Ruby Hash#refault_proc (1.9)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment