Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symbol#to_proc with custom methods

Tags:

ruby

I like how in Ruby you can pass methods as blocks like so using Symbol#to_proc:

[1.0, 2.0, 3.0].map(&:to_i)
#=> [1, 2, 3]

I can also define my own lambda, times_two, and pass it as a block as well:

times_two = ->(x) {x * 2}

[1, 2, 3].map(&times_two)
#=> [2, 4, 6]

Though I seemingly cannot pass times_two as a symbol:

[1, 2, 3].map(&:times_two)
#=> ArgumentError: wrong number of arguments (0 for 1)

However when I try to do the same with a method I get an error:

def times_three(x)
  x * 3
end

[1, 2, 3].map(&times_three)
#=> ArgumentError: wrong number of arguments (0 for 1)

[1, 2, 3].map(&:times_three)
#=> ArgumentError: wrong number of arguments (0 for 1)

I'm guessing I can't do this because times_three is a method, not a Proc.

So how can you define custom methods so that they can be used in the Symbol#to_proc fashion like to_i in the first example above?

For example, how can I do this?

[1, 2, 3].map(&:times_three)
#=> [3, 6, 9]

EDIT: I watched the video posted below and apparently you can get close to Symbol#to_proc using the method method:

def times_three(x)
  x * 3
end

t_three = method(:times_three)
[1, 2, 3].map(&t_three)
#=> [3, 6, 9]

However, it's not quite Symbol#to_proc:

[1, 2, 3].map(&:t_three)
#=> NoMethodError: undefined method `t_three' for 1:FixNum
like image 256
garythegoat Avatar asked Feb 07 '15 22:02

garythegoat


People also ask

What is the name of this symbol @?

The at sign, @, is normally read aloud as "at"; it is also commonly called the at symbol, commercial at, or address sign.

What does ❦ mean?

Emoji MeaningA decorative heart-shaped character, which is supported on most platforms as a plain text dingbat. See also ☙ Reversed Rotated Floral Heart Bullet which has an emoji presentation on Samsung devices. Floral Heart was approved as part of Unicode 1.1 in 1993.

How do I make the text symbol?

To insert an ASCII character, press and hold down ALT while typing the character code. For example, to insert the degree (º) symbol, press and hold down ALT while typing 0176 on the numeric keypad. You must use the numeric keypad to type the numbers, and not the keyboard.


2 Answers

class Integer
  def times_three
    return self * 3
  end
end

Now, because times_three is now a method of the Integer class, you can do symbol to proc...

[1, 2, 3].map(&:times_three)

If you want to access a method that isn't part of the object's class but acts on an object, you need to pass the object as an argument to the method...

def times_three(x)
  x * 3
end

[1, 2, 3].map{|i| times_three(i) }

the symbol to proc needs to use the object as a receiver.

[1, 2, 3].map(&:some_action)

is equivalent to

[1, 2, 3].map{|i| i.some_action}
like image 102
SteveTurczyn Avatar answered Oct 04 '22 06:10

SteveTurczyn


You would have to define times_three on Integer or Numeric.

Symbol to Proc explained by Peter Cooper: https://www.youtube.com/watch?v=aISNtCAZlMg

like image 29
doesterr Avatar answered Oct 04 '22 06:10

doesterr