Created
August 22, 2008 23:57
-
-
Save jamiew/6877 to your computer and use it in GitHub Desktop.
Allows attributes to be declared as lazy, meaning that they won't be # computed until they are asked for
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
# pseudoforked from mojombo: http://rubyisawesome.com/2007/10/13/lazy-mixin | |
# Before you ask--yes, this has a very specific use case and is not | |
# generally applicable to the problem of fine-grained lazy evaluation. | |
# But it does *exactly* what I need it to do. =) | |
# Allows attributes to be declared as lazy, meaning that they won't be | |
# computed until they are asked for. Just mix this module in: | |
# | |
# class Foo | |
# include Lazy | |
# ... | |
# end | |
# | |
# To specify a lazy reader: | |
# | |
# lazy_reader :att | |
# | |
# Then, define a method called __bake__ that computes all your lazy | |
# attributes: | |
# | |
# def __bake__ | |
# @att = ... | |
# end | |
# | |
# That's it! (Tom Preston-Werner: rubyisawesome.com) | |
module Lazy | |
module ClassMethods | |
def lazy_reader(*args) | |
args.each do |arg| | |
define_method(arg) do | |
self.__prebake__ | |
instance_variable_get(('@' + arg.to_s).intern) | |
end | |
end | |
end | |
end | |
def __prebake__ | |
return if @__baked__ | |
self.__bake__ | |
@__baked__ = true | |
end | |
def self.included(base) | |
base.extend(ClassMethods) | |
end | |
end | |
# A pedagogical class with a lazy attribute | |
class Foo | |
include Lazy | |
attr_reader :id | |
lazy_reader :body | |
def initialize(id) | |
@id = id | |
end | |
def __bake__ | |
puts "__baking__" | |
@body = "The 30th fibonacci is #{self.fib(30)}" | |
end | |
def fib(n) | |
return 1 if n == 0 || n == 1 | |
return fib(n-1) + fib(n-2) | |
end | |
end | |
t = Foo.new('abc') | |
puts t.id # => (immediate) "abc" | |
puts t.body # => (short pause) The 30th fibonacci is 1346269 | |
puts t.body # => (immediate) The 30th fibonacci is 1346269 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment