Skip to content

Instantly share code, notes, and snippets.

@bmabey
Forked from patmaddox/lazy_ivar_init.rb
Created April 1, 2011 10:31
Show Gist options
  • Save bmabey/897987 to your computer and use it in GitHub Desktop.
Save bmabey/897987 to your computer and use it in GitHub Desktop.
module LazyInit
class Delay # < BlankSlate or similar so other method calls aren't answered by Delay
def initialize(obj, var_name, &block)
@parent_obj, @var_name, @block = obj, var_name, block
end
def method_missing(method, *args, &block)
realized_object = @block.call
@parent_obj.instance_variable_set(@var_name, realized_object)
realized_object.send(method, *args, &block)
end
end
def lazy_init(var, &block)
var_name = "@#{var}"
self.instance_variable_set(var_name, Delay.new(self, var_name, &block))
end
end
class Foo
def initialize
puts "Hi, I'm a Foo object that was just created."
end
def something
puts "Yo, I'm doing something"
42
end
end
class SomethingDoer
include LazyInit
def initialize
lazy_init(:foo) { Foo.new }
end
def do_something
@foo.something # doesn't blow up because it auto-init'd
end
end
doer = SomethingDoer.new
puts "A doer whas just created..."
puts "Now, I will call #do_something to force the realization of the @foo instance var..."
puts doer.do_something
puts doer.instance_variable_get("@foo").inspect # make sure the delay object was replaced with Foo object so the operation is transparent to clients
## Output:
# A doer whas just created...
# Now, I will call #do_something to force the realization of the @foo instance var...
# Hi, I'm a Foo object that was just created.
# Yo, I'm doing something
# 42
#<Foo:0x1001b9eb8>
#
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment