Ruby Facets: Symbol.to_proc, Class.to_proc

One pretty well-know idiom in Ruby, and Facets, is Symbol.to_proc. It lets you turn these:

[1, 2, 3].map { |num| }  #=> [2, 3, 4]

%w[alpha beta gamma].map { |word| word.upcase }
#=> ["ALPHA", "BETA", "GAMMA"]

…into these:

[1, 2, 3].map(&:next)
%w[alpha beta gamma].map(&:upcase)

It’s a nice little trick, though it’s not to everyone’s taste. If you’re already comfortable with Symbol.to_proc, you can skip down to the Class.to_proc section. But if you’re not, it’s worth a minute of your attention to learn it. Read on…

How it’s done

When a method takes a block, you can call yield, to run the block.

def with_a_block(a_param)
with_a_block('param') {
    puts 'in the block'

Or, you can name the block as the last parameter to the method, and put an ampersand in front of it. The ampersand makes ruby convert the block to a procedure, by calling to_proc on it. (So any object with a to_proc method can work this way, if you want.) This example works just like the last one:

def named_block(a_param, &blk)
named_block('my_param') {
    puts 'in the named block'

Symbol’s to_proc method creates a procedure that takes one argument, and sends the symbol to it. Sending a symbol to an object is the same as calling a method on it: object.send(:method) works the same as object.method. In the earlier upcase example, each word is passed to a procedure that calls upcase on it, giving us a list of uppercased strings.

# becomes...
lambda { |obj|
# or...
lambda { |obj|


So Symbol.to_proc creates a function that takes an argument, and calls that method on it. Class.to_proc creates a function that passes its argument to its constructor, yielding an instance of itself. This is a welcome addition to the to_proc family.

require 'facets'

class Person
    def initialize(name)
        @name = name
names = %w[mickey minney goofy]
characters =

puts characters.inspect

# becomes...
lambda { |obj|

Why it’s nice

  • It’s fewer characters — it semantically compresses your code.
  • It lets you think, makes you think, on a higher level. You think about operations on your data, rather than handling one item at a time. It raises your level of thinking.
  • It works with first-class functions, which are worth understanding. They give you new ways to elegantly solve some problems (well, new to some audiences). They’re not fringe anymore — they’ve been in C# since v2.0.

4 thoughts on “Ruby Facets: Symbol.to_proc, Class.to_proc

  1. Just to be pedantic, Symbol#to_proc is not part of Ruby 1.8, which is still the most commonly used version. Did you mean “One pretty well-known idiom in *Rails*, and in Facets…”?

    Class#to_proc does indeed look handy.

  2. Avdi, that’s a good point, and you’re 100% correct…I was being a bit loose with my language. Maybe I should have said “One pretty well-known idiom in Ruby, FROM Rails and Facets…”

    I guess I think of Symbol.to_proc as a Ruby idiom, because: it’s useful in any Ruby code, it’s easy to implement yourself w/o any libraries, it’s built into both Rails and Facets, and it’s part of Ruby 1.9.

    But for the record, to any others who might be confused: if you want to use Symbol.to_proc in Ruby 1.8, you need to require facets, or work in Rails, or implement Symbol.to_proc yourself. Hint:

    class Symbol
    def to_proc{|*args| args.shift.__send__(self, *args)}
    # copied from Facets v2.3.0

    Avdi, thanks for keeping me honest.

  3. Pingback: Nikos D.

Comments are closed.