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 Proc
s are being returned, it’s time to call those Proc
s 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