Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
716 views
in Technique[技术] by (71.8m points)

ruby - Symbol#to_proc with custom methods

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
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}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...