Created
December 3, 2012 18:18
-
-
Save rsliter/4196841 to your computer and use it in GitHub Desktop.
Closures in Ruby
This file contains 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
# Closures can be done in Ruby using both lambdas and procs. | |
# Lambdas with closures: | |
# A lambda can be declared so that it is created at runtime but evaluated only when it is called. | |
class Person | |
def initialize(age) | |
@age = age | |
end | |
def birthday | |
lambda { @age += 1 } | |
end | |
def print_age | |
lambda { puts "Age: #{@age}" } | |
end | |
end | |
# The above class has two methods that return lambda expressions. When #birthday is called, | |
# for example, a lambda is returned-- the lambda#call method must be called to execute the code | |
# contained within: | |
rebecca = Person.new(0) | |
birthday_closure = rebecca.birthday | |
age_closure = rebecca.print_age | |
# Again, birthday_closure and age_closure are simply lambdas. | |
# In order to increment and print the Person's new age, the following code must be executed: | |
rebecca.print_age.call # prints "Age: 0" | |
rebecca.birthday_closure.call # increments the age | |
rebecca.print_age.call # prints "Age: 1" | |
# This follows the properties outlined in the original Gist (gist.github.com/4196824): | |
# first, that the lambda allows the function to be passed around without executing (as we saw in calling | |
# rebecca.birthday); second, that the values persisted outside of the scope of the object-- the instance | |
# of Person, rebecca, was able to keep the @age variable and access and increment it from outside of the | |
# Person class. | |
# Procs with closures: | |
# Procs also allow for passing blocks of code around to be executed later. An example of this can be found | |
# in the Rails source code*: | |
:stderr => Proc.new { |message, callstack| | |
$stderr.puts(message) | |
$stderr.puts callstack.join("\n ") if debug | |
} | |
# In the example above, Proc.new will create an error message if the debug variable declared within the class, | |
attr_accessor :debug | |
# , is assigned "true". The Proc can be called with the message and callstack assigned while the program | |
# is executing. Furthermore, the state of :debug can be accessed from outside of the scope of the | |
# class-- from wherever the deprecated message ought to be displayed. | |
# * https://github.com/rails/rails/blob/master/activesupport/lib/active_support/deprecation/behaviors.rb |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment