Skip to content

Instantly share code, notes, and snippets.

@rsliter
Created December 3, 2012 18:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rsliter/4196841 to your computer and use it in GitHub Desktop.
Save rsliter/4196841 to your computer and use it in GitHub Desktop.
Closures in Ruby
# 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