Skip to content

Commit

Permalink
add attr_lazy.rb: displaces lazy_struct.rb and lazy_attribute.rb
Browse files Browse the repository at this point in the history
  • Loading branch information
quix committed Aug 23, 2009
1 parent 041acc5 commit 380c14c
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 169 deletions.
67 changes: 67 additions & 0 deletions lib/quix/attr_lazy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

module Quix
#
# Lazily-evaluated attributes.
#
# An attr_lazy block is evaluated in the context of the instance
# when the attribute is requested. The same result is then returned
# for subsequent calls until the attribute is redefined with another
# attr_lazy block.
#
module AttrLazy
def attr_lazy(name, &block)
AttrLazy.define_attribute(class << self ; self ; end, name, false, &block)
end

def attr_lazy_accessor(name, &block)
AttrLazy.define_attribute(class << self ; self ; end, name, true, &block)
end

class << self
def included(mod)
(class << mod ; self ; end).class_eval do
def attr_lazy(name, &block)
AttrLazy.define_attribute(self, name, false, &block)
end

def attr_lazy_accessor(name, &block)
AttrLazy.define_attribute(self, name, true, &block)
end
end
end

def define_attribute(klass, name, define_writer, &block)
klass.class_eval do
# Factoring this code is possible but convoluted, requiring
# the definition of a temporary method.

remove_method name rescue nil
define_method name do
value = instance_eval(&block)
(class << self ; self ; end).class_eval do
remove_method name rescue nil
define_method name do
value
end
end
value
end

if define_writer
writer = "#{name}="
remove_method writer rescue nil
define_method writer do |value|
(class << self ; self ; end).class_eval do
remove_method name rescue nil
define_method name do
value
end
end
value
end
end
end
end
end
end
end
38 changes: 0 additions & 38 deletions lib/quix/lazy_attribute.rb

This file was deleted.

55 changes: 0 additions & 55 deletions lib/quix/lazy_struct.rb

This file was deleted.

151 changes: 151 additions & 0 deletions test/attr_lazy_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
require File.dirname(__FILE__) + "/common"

require 'quix/attr_lazy'

class TestAttrLazy < Test::Unit::TestCase
def test_1_reader
n = 0
cls = Class.new do
include Quix::AttrLazy
attr_lazy :f do
n += 1
33
end
end
s = cls.new

3.times { assert_equal(33, s.f) }
assert_equal(1, n)

s.attr_lazy :f do
77
end
assert_equal(77, s.f)

assert_raises(NoMethodError) {
s.f = 99
}
end

def test_1_accessor
n = 0
cls = Class.new do
include Quix::AttrLazy
attr_lazy_accessor :f do
n += 1
33
end
end
s = cls.new

3.times { assert_equal(33, s.f) }
assert_equal(1, n)

s.attr_lazy :f do
77
end
assert_equal(77, s.f)

s.f = 99
assert_equal(99, s.f)
end

def test_2
cls = Class.new do
include Quix::AttrLazy

attr_lazy :x do
33
end

attr_lazy :y do
44
end

attr_lazy_accessor :z do
x + y
end
end

assert_equal(33 + 44, cls.new.z)
a = cls.new
a.z = 99
assert_equal(99, a.z)
end

def test_3
cls = Class.new do
include Quix::AttrLazy

attr_lazy :f do
@u = 99
55
end

attr_reader :u
end

a = cls.new
assert_equal nil, a.u
assert_equal 55, a.f
assert_equal 99, a.u

a.attr_lazy_accessor :f do
77
end
assert_equal 77, a.f

a.f = 88
assert_equal 88, a.f
end

def test_4
cls = Class.new do
include Quix::AttrLazy
attr_lazy :x do
33
end
end

a = cls.new
class << a
attr_lazy :x do
99
end
end

assert_equal(99, a.x)
end

def test_5
cls = Class.new do
include Quix::AttrLazy
attr_lazy :x do
33
end
end

a = cls.new
b = cls.new

a.attr_lazy :x do
44
end
assert_equal 44, a.x
assert_equal 33, b.x
end

class A
include Quix::AttrLazy
def initialize(x)
attr_lazy :x do
x
end
end
end

def test_6
assert_equal 99, A.new(99).x
end
end

39 changes: 0 additions & 39 deletions test/lazy_attribute_test.rb

This file was deleted.

37 changes: 0 additions & 37 deletions test/lazy_struct_test.rb

This file was deleted.

0 comments on commit 380c14c

Please sign in to comment.