Skip to content

Instantly share code, notes, and snippets.

@kazjote
Created July 29, 2014 19:25
Show Gist options
  • Save kazjote/e1d56949ce658580b118 to your computer and use it in GitHub Desktop.
Save kazjote/e1d56949ce658580b118 to your computer and use it in GitHub Desktop.
# http://www.skorks.com/2010/05/closures-a-simple-explanation-using-ruby/
# "In computer science, a closure is a first-class function with free variables that are bound in the lexical environment."
#
# "A closure is a function that is said to be "closed over" it’s free variables"
#
#
# * You can pass it around like an object (to be called later)
#
# * It remembers the values of all the variables that were in scope when the function was created. It is then able to
# access those variables when it is called even though they may no longer be in scope.
#######################################################################################################################
# - Spy -
#
# Responsibility of a spy is to collect messages
#
#######################################################################################################################
class Spy
attr_accessor :messages
def initialize
self.messages = []
end
def overhear(message)
puts "Spy: ..."
messages << message
end
def report
messages.each do |message|
puts "Pssst! spied person said: '#{message}'"
end
end
end
class Journalist
attr_accessor :messages
def initialize
self.messages = []
end
def note(message)
puts "Journalist: Mhm"
messages << message
end
def report
messages.each do |message|
puts "Dear readers! #{message}"
end
end
end
class Friend
attr_accessor :messages
def hear(message)
puts "Friend: I am so happy! #{message}"
end
end
#######################################################################################################################
# Person
#
# Person reports its thoughts to all that want to listen
#######################################################################################################################
class Person
attr_accessor :report_channels
def initialize
self.report_channels = []
end
def add_report_channel(callback)
report_channels << callback
end
def say(message)
report_channels.each { |e| e.call(message) }
nil
end
end
def bootstrap
spy = Spy.new
journalist = Journalist.new
friend = Friend.new
magda = Person.new
name = "Magda"
# Callback using Proc
_proc = Proc.new { |message| journalist.note("#{name} said: #{message}") }
# Callback using lambda
_lambda = -> (message) { friend.hear("#{name} said: #{message}") }
# Callback using bound method (not a closure)
meth = spy.method(:overhear)
magda.add_report_channel(_proc)
magda.add_report_channel(_lambda)
magda.add_report_channel(meth)
[magda, spy, journalist, friend]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment