Overview

14 Callable and runnable objects

The chapter introduces Ruby’s broader idea of things you can call, run, or execute beyond ordinary method calls. It focuses first on procs and lambdas as anonymous functions, then on method objects, threads, and finally ways to launch external programs. Along the way, it emphasizes that Ruby gives you multiple layers of dynamism: code can be packaged as objects, captured from blocks, passed around, invoked later, and even used to reshape execution context.

A major theme is the distinction between block syntax and proc objects. Blocks are part of method-call syntax, not objects themselves, but they can be captured as procs with the special ampersand form and then invoked with call. The chapter explores how procs act as closures, preserving the local variables in scope when they were created, which makes patterns like counters and stateful callbacks possible. It also shows how lambdas are a stricter kind of proc, especially in argument handling and return behavior, and how Ruby’s proc-conversion hooks such as to_proc enable concise constructs like symbol-to-proc shorthand and hash lookups in map.

The later sections broaden the discussion to method objects, where methods can be detached from instances, rebound, and called like other callable objects, mainly as a reflective tool rather than a common everyday technique. The chapter then shifts to the eval family, explaining how Ruby can execute strings as code, change self with instance_eval and instance_exec, and define methods dynamically with class_eval and define_method, while warning about the security and design risks of these powers. It closes with concurrency and external execution: threads for lightweight concurrent work, thread-local data and keys, a networked server example, and system command interfaces such as system, backticks, open, and Open3 for interacting with operating-system programs.

A phantom Proc instantiation intervenes between a method call and a method.

Summary

  • Objects in Ruby are products of runtime code execution but can, themselves, have the power to execute code.
  • Proc objects are anonymous functions that can be executed.
  • The lambda “flavor” of proc objects is stricter about arity than plain procs.
  • Procs bound to variables can be used as code blocks.
  • Any object can have a to_proc method, available through the & prefix operator.
  • Symbol#to_proc creates a proc that sends the symbol itself to the object(s), e.g., array_of_strings.map(&:upcase).
  • The Method class allows methods to be passed around as first-class objects.
  • The eval “family” of methods includes eval, instance_eval, and class_eval (aka module_eval).
  • Bindings represent the local variable bindings at a given point in program execution.
  • Threads offer facilities for concurrent programming.
  • Threads can store values as keys, e.g., my_thread[:message] = "Hello".
  • External programs can be executed from Ruby code with the system method, exec, backticks, and the open and Open3.popen3 facilities.

FAQ

What is a Proc object in Ruby?A Proc object is a callable object that wraps a code block. You can store it in a variable, pass it around like any other object, and execute it later with call.
How do you create a Proc object?You can create one with Proc.new or the proc method, followed by a code block. For example: pr = Proc.new { puts "Hello" }.
What is the relationship between blocks and Procs?A Ruby code block is syntax, not an object. A Proc can be created from a block, and a block can be captured as a Proc using &block in a method parameter.
How does &p work when passing a Proc to a method?The & triggers to_proc on the object and tells Ruby to use the resulting Proc as the method’s block. This lets a Proc stand in for an actual code block.
What does Symbol#to_proc do?Symbol#to_proc converts a symbol into a Proc that sends that message to each element it is called on. This is why map(&:capitalize) works.
What does it mean for a Proc to be a closure?A closure preserves the local variable bindings that were in scope when the Proc was created. That means the Proc can keep using those variables even after the surrounding method has returned.
How are lambdas different from regular Procs?Lambdas are a special flavor of Proc. They enforce arity more strictly, and return inside a lambda returns from the lambda itself, while return inside a regular Proc returns from the enclosing method.
How do you capture and use a Method object?You can get a Method object with method(:name) on an instance. The resulting bound Method can be called later with call. You can also unbind it and bind it to another compatible object.
What is instance_eval used for?instance_eval evaluates a string or block in the context of a specific object, temporarily changing self. It’s often used to access instance variables or build small DSL-style APIs.
How do Ruby threads help with concurrent execution?Thread.new runs a block concurrently with the rest of the program. Threads can be joined, stopped, killed, and they can store thread-local data using thread keys like Thread.current[:message].

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • The Well-Grounded Rubyist, Fourth Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • The Well-Grounded Rubyist, Fourth Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • The Well-Grounded Rubyist, Fourth Edition ebook for free