Created
August 30, 2011 13:42
-
-
Save mikebannister/1180910 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In a lot of languages callbacks are really common. You might call a function | |
with another function as an argument and at some point | |
in the body of the called function the callback function gets called. You said | |
this is done with pointers in C... not sure how | |
common this is there so bear with me. | |
# This is (psuedo-code) based on javascript where callbacks are really common | |
because it's asynchronous (i.e. you often need a callback to be notified when | |
the function you've called is complete). First two function definitions: | |
function a_function_that_takes_a_function_as_an_argument(a_regular_argument, a_function_argument) { | |
print "We're inside a_function_that_takes_a_function_as_an_argument" | |
print 'A regular argument: ' + a_regular_argument; | |
print 'OK, all done, calling back to caller' | |
a_function_argument(a_regular_argument); | |
} | |
function another_function(a_regular_argument) { | |
print 'OK, the other function is finally done! (We're inside another_function)' | |
print 'The other function gave us back this argument: ' + a_regular_argument | |
} | |
# Now we call the first function with the second one as an argument | |
a_function_that_takes_a_function_as_an_argument('a string', another_function); | |
# The output should look like | |
We're inside a_function_that_takes_a_function_as_an_argument | |
A regular argument: a string | |
OK, all done, calling back to caller | |
OK, the other function is finally done! (We're inside another_function) | |
The other function gave us back this argument: a string | |
So! In Ruby you can't pass functions around in the same way but instead we have | |
blocks which can do 'all that and more'. Notice, you call 'yield' to execute | |
the block. Notice also that you don't have to do anything special in Ruby to | |
declare that your function takes a block, it's built-in. | |
One function: | |
def a_function_that_accepts_a_code_block(a_regular_argument) | |
print "We're inside a_function_that_takes_a_code_block" | |
print 'A regular argument: ' + a_regular_argument; | |
print 'OK, all done, calling back to caller' | |
yield a_regular_argument | |
end | |
Call it with a block: | |
a_function_that_takes_a_code_block do |a_regular_argument| | |
print "OK, the other function is finally done! (We're inside another_function)" | |
print 'The other function gave us back this argument: ' + a_regular_argument | |
end | |
This is really powerful and is used all over the Ruby language and Ruby On Rails. | |
A very common pattern that the author of functions in ruby uses is 1) the function | |
does 'some stuff' 2) the function calls the block (with yield) one or many times | |
and 3) the function does some more stuff (like cleanup). A great example of this | |
is ruby's built in function for reading and writing files: | |
File.open('/path/to/file/somewhere, 'w') do |the_file| | |
the_file.write('some text') | |
end | |
So you can imagine the definition for this function 1) opens the file, 2) calls yield | |
so the caller do whatever it wants with the open file and 3) flushes the output and | |
closes the file. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment