Ruby Tuesday – Symbol#to_proc

Today’s Ruby Tuesday is on Symbol#to_proc.

Symbol#to_proc returns a Proc object which corresponds to the method represented by the symbol it is called on.

First, we will create a new method foo which just puts the string Foo to output.

def foo
  puts "Foo"
end
# => :foo

Now let’s call Symbol#to_proc on a couple of different symbols, and see what their return values are.

:foo.to_proc
# => #<Proc:0x007ff08395d9b0>
:to_s.to_proc
# => #<Proc:0x007ff0829f42a8>
:keys.to_proc
# => #<Proc:0x007ff0828280f0>

And we will also capture the results of calling to_proc on the symbol :to_s, so that we can be assured that it is the same Proc object later on.

to_s_proc = :to_s.to_proc
# => #<Proc:0x007ff0829f42a8>

Now that we have seen that Procs are being returned, it’s time to call those Procs to see how they behave.

:to_s.to_proc.call(1)
# => "1"
:foo.to_proc.call(1)
# Foo
# => nil
:keys.to_proc.call({:a => 1, :b => 2, :c => 3})
# => [:a, :b, :c]
:foo.to_proc.call()
# ArgumentError: no receiver given
# from (pry):40:in `call'
:foo.to_proc.call(1, 2, 3)
# ArgumentError: wrong number of arguments (2 for 0)
# from (pry):1:in `foo'

When we call a Proc generated in this way at the Ruby shell, the first argument is the context for what the Proc will be called against.

If we pass no arguments, we get an error of no receiver given, telling us that the Proc doesn’t have anything to call the method on.

:foo.to_proc.call()
# ArgumentError: no receiver given
# from (pry):40:in `call'

And if we pass in extra arguments to a Proc that was generated from calling Symbol#to_proc, it will error out as it expects the right number of arguments to be passed to the Proc.

:foo.to_proc.call(1, 2, 3)
# ArgumentError: wrong number of arguments (2 for 0)
# from (pry):1:in `foo'

And finally, we will call the Proc we captured in a variable, to show that the same Proc will operate against multiple objects of different types.

to_s_proc.call(1)
# => "1"
to_s_proc.call({:a => 1, :b => 2, :c => 3})
# => "{:a=>1, :b=>2, :c=>3}"

So we can see that the Proc we got from calling :to_s.to_proc will work and call to_s on both and integer and a Hash.

–Proctor