It can be done! As per my last blog post, with no further ado, here is how you do it:
def first_option
puts "space jam"
end
def second_option
puts "dogs rule"
end
def receives_function(func)
method(func).call
end
receives_function(:first_option)
It is imperative to notice that you must pass the function through as a symbol when you are ready to send it along.
There are a few things about this setup that you may find interesting. When I first started looking into this, I assumed that you could just pass them through normally, using receives_function(first_option)
. I figured, Ruby is nice right?
Wrong.
Just kidding, I mean Ruby is nice, but it's not magic. Because Ruby is a synchronous language and function calls only require the name of the function, Ruby will read receives_function(first_option)
and immediately invoke the first_option method, before it enters receives_function method at all.
So let's dive into the other stuff. The symbol terminology is Ruby's built-in way to allow you to reference a function without calling it. By placing the symbol in the argument for receives_function, we are able to pass all the info along and actually get into the receives_function code block before executing anything.
The next step is to figure out how to call a function which has been sent as a symbol. It gets a little hairy here because once we are inside of the receives_function code block, all we have to work with is a variable called func. Not a symbol at all. This is where Ruby's method method comes into play.
As a side note, googling "Ruby method method" is marginally annoying, so here is the link to the Ruby Docs to save you the time if you're interested.
The method method takes an argument of a symbol and returns information about that symbol. When you pass it a symbol of another method, it will return something like this:
[5] pry(main)> method(func)
=> #<Method: main.first_option>
With this it's saying hey, you passed me a method, and its name is first_option. You can chain a few commands on the end of this return value to determine other information about the symbol. For example, you could add .source_location
and it would give you the file name and the line on which the original first_option function was defined. That's very useful for debugging, but in our case we don't care about that -- we just wanna invoke it. So, as you saw in the example, we chain a .call
on there and "call" it a day.
Sigh.
So that's that! Have fun out there.
Top comments (3)
Great Hal Friday !!
I would add a small comment. This is when a function is called, we want to pass the function received as an argument
Great post! Thank you!
Very well described. I did not understand this very well.