Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@isaacsanders
Created August 30, 2013 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isaacsanders/6393470 to your computer and use it in GitHub Desktop.
Save isaacsanders/6393470 to your computer and use it in GitHub Desktop.
An naïve implementation of a Closure object in Ruby
class Closure
attr_reader :formals, :bodies, :env
def initialize(formals, bodies, env)
@formals = Array(formals)
@bodies = Array(bodies)
@env = env
end
def call(*args)
raise argument_error(args) if args.length != formals.length
bodies.map {|body| body.call(env.merge(bind(args))) }.last
end
def bind(args)
formals.zip(args).each_with_object({}) do |(key, value), hash|
hash[key] = value
end
end
def argument_error(args)
ArgumentError.new("wrong number of arguments (#{args.length} for #{formals.length})")
end
end
# Examples:
body = lambda {|env| puts "#{env[:level]}: #{env[:format] % env[:args]}" }
logger = Closure.new([:level, :format, :args], body, {})
logger.call(:info, "%s on the bridge of the %s", ["Kirk", "Enterprise"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment