Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does `&method(:function)` mean?

Tags:

ruby

What does &method(:function) mean? For example, I have this line:

res = integrate(0, 1, a, &method(:function))
like image 772
RubyBeginner Avatar asked Jan 11 '20 19:01

RubyBeginner


People also ask

What is the meaning of “…”?

And the final meaning of “…” is quite simply “I don’t know”. Unless you happen to be a super genius (and if you need to read this, you’re not), none of us knows everything. And sometimes, you just have to admit that you don’t know.

What does “/” mean in writing?

In writing, the “/” symbol is used to stand in for “and”, “or” or “and & or”. You can use it to join two things, meaning “and”. You can also use it to denote two options, meaning “or”. Or you can use it to mean both, “and & or”. In writing, therefore, “/” can be an incredibly powerful ally if you know how to use it well.

What does the “/” symbol mean?

What Does / Mean? The “/” symbol or “slash” symbol is a punctuation symbol generally used for separating dates and representing divisions, as well as presenting alternatives in English writing. This means that the “slash” symbol is incredibly versatile, and to understand what it means in any given situation, you must examine the context.

Does “…” mean the same thing in every text?

But in text, themeaning changes, and to make things even more confusing, even in text “…” doesn’t always have the same meaning. Today, we’ll look at the four possible meanings of “…” in text, explaining what each of them is when they might be used, and we’ll also be providing some examples to help you. What does… mean in text?


2 Answers

method(:function) is a message send (sometimes called a method call) to the implicit receiver (i.e. self). It is sending the message method to the implicit receiver (i.e. self), passing :function as the sole argument.

:function is a Symbol literal, i.e. it is the literal notation of a Symbol. Symbol is a data type representing "the name of something".

The unary prefix ampersand & operator "unrolls" a Proc into a block. I.e. it allows you to pass a Proc where a block is expected. If the object is not already a Proc, it will be sent the to_proc message allowing it to convert itself into a Proc. (The operator is only legal in an argument list and only for the last argument. It is the dual of the & sigil in a parameter list, which "rolls" a block into a Proc object.)

Proc is a datatype representing executable code. It is Ruby's core library class for first-class subroutines.

So, what this does, is call the method method on self with :function as the argument, call to_proc on the return value, "unroll" the resulting Proc object into a block and pass that block to the call to integrate as if you had written something like

res = integrate(0, 1, a) do
  # something
end

The method method here is most likely, the Object#method method, which returns a bound Method object.

So, all in all, this is somewhat equivalent to

res = integrate(0, 1, a) do |*args, &block|
  function(*args, &block)
end

But expressed in what is commonly called pointfree style.

like image 29
Jörg W Mittag Avatar answered Oct 11 '22 23:10

Jörg W Mittag


Say we have a method

def add_one(num)
  num + 1
end

and an array of strings

arr = ["1", "2"]

We want to map the list of strings to their corresponding outputs from add_one.

To start out we can call

nums = arr.map(&:to_i)

This is the same thing as

nums = arr.map do |str|
  str.to_i
end

You can see What does map(&:name) mean in Ruby? for more info on this.

However, it won't work to call:

nums.map(&:add_one)

Why? Because numbers have no built in method add_one. So you'll get a NoMethodError.

So, rather than providing just a method name :add_one you can pass an bound method method(:add_one):

nums.map(&method(:add_one))

Now, rather than each num being used as the receiver for the add_one method, they will be used as arguments. So, it's essentially the same as:

nums.map do |num|
  add_one(num)
end

To give another example, compare the following:

[1].map(&:puts)
# this is the same as [1].map { |num| num.puts }
# it raises NoMethodError

[1].map(&method(:puts))
# this is the same as [1].map { |num| puts num }
# it prints 1 successfully
like image 148
max pleaner Avatar answered Oct 11 '22 23:10

max pleaner