Skip to content

Instantly share code, notes, and snippets.

@karmiclychee
Last active February 23, 2021 00:22
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 karmiclychee/be15682aee14caf4f4b8588968cdb161 to your computer and use it in GitHub Desktop.
Save karmiclychee/be15682aee14caf4f4b8588968cdb161 to your computer and use it in GitHub Desktop.
Blocks, procs, and lambdas
# will explode at the yield if no block is provided
def with_implicit_block(a, b)
yield(a + b)
end
# does nothing if block isn't present
def with_implicit_block_safe(a, b)
yield(a + b) if block_given?
end
# will explode at .call if no block is provided
# can pass around the block now that it has a name
def with_explicit_block(a, b, &some_block)
some_block.call(a + b)
another_method(some_block)
end
# ----------------------------------------------------------------------------
# this is functionally the same as
def with_implicit_block_safe(a, b)
yield(a + b) if block_given?
end
# this
def with_explicit_block(a, b, &some_block)
some_block.call(a + b) if some_block
end
# ----------------------------------------------------------------------------
# related:
def foo(bar)
yield(bar)
end
foo(12) { |something| puts something }
=> 12
# (blocks are anonymous procs)
foo_proc = Proc.new { |something| puts something }
foo_proc.call(12)
=> 12
# similar to procs/blocks, but have different rules, like strict argument count
foo_lambda = -> (something) { puts something }
foo_lambda.call(12)
=> 12
# Don't do this
class MyClass
def foo_method(something)
puts something
end
end
dumb = MyClass.new.method(:foo_method)
dumb.call(12)
=> 12
# ----------------------------------------------------------------------------
# non blocks as explicit blocks
def with_explicit_block(a, b, &some_block)
some_block.call(a + b)
another_method(some_block)
end
with_explicit_block(1, 2) { |total| puts total }
with_explicit_block(1, 2, &-> (total) { puts total })
# non blocks as implicit blocks
def with_implicit_block(a, b)
yield(a + b)
end
with_implicit_block(1, 2) { |total| puts total }
with_implicit_block(1, 2, &-> (total) { puts total })
# ----------------------------------------------------------------------------
# & "procs" up non block arguments into blocks
with_implicit_block(1, 2, &-> (total) { puts total })
=> 3
with_implicit_block(1, 2, -> (total) { puts total })
=> ArgumentError: wrong number of arguments (given 3, expected 2)
# arity
Proc.new { |a, b, c| puts a }.call(1)
=> 1
-> (a, b, c) { puts a }.call(1)
=> ArgumentError: wrong number of arguments (given 1, expected 3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment