PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, November 11, 2022

[FIXED] Why does Ruby only allow to refer to methods by symbols when calling to_proc on them?

 November 11, 2022     proc, ruby, symbols     No comments   

Issue

This works:

strings = ["1", "2", "3"]
nums = strings.map(&:to_i)

We see that & (to_proc method) applied to a Symbol object is turned into a block. This, however, doesn't work:

strings = ["1", "2", "3"]
nums = strings.map(&to_i)
nums = strings.map("to_i".to_sym.to_proc) #...neither does this

Why doesn't it work? Isn't there any alternative way to write the code above? I'm confused because there are two ways to access a method of a class:

"1".method(:to_i).call #works as well as
"1".method("to_i").call 

So the method's name can be accessed either by symbol or a string.


Solution

Given the following valid Ruby example:

"to_i".to_sym.to_proc.call("1")

To call #to_proc on a Symbol creates a proc that receive one parameter: the object that should receive an invocation of the method named by the symbol. Something like this:

->(object) {
  object.send(:to_i)
}

What the & do is to pass the block returned by #to_proc as a proper invocation block to the method being called. When used with Enumerable#map, the final result is that the passed block will be invoked for each element on the collection and receive the current iteration element being passed as parameter to the block.

So the ["1", "2"].map(&:to_i) syntax is a shortcut to something like this:

block = ->(el) {
  el.send(:to_i)
}

["1", "2"].map &block

About your examples:

When you try to call &to_i in your example, Ruby will try to invoke a variable or method named to_i. Since it doesn't exists in the scope (it is a method of each String in the Array, not in the "global" scope), it'll generate an error.

About the other example: "to_i".to_sym.to_proc will transform the :to_i into a proc that when invoked with one parameter, will try to call the method named after the symbol (:to_i) against the target parameter. This means that you could use the & to transform the proc into a "invocation block":

["1", "2"].map(&"to_i".to_sym.to_proc)


Answered By - Ricardo Valeriano
Answer Checked By - Willingham (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing