-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add attr_lazy.rb: displaces lazy_struct.rb and lazy_attribute.rb
- Loading branch information
Showing
6 changed files
with
218 additions
and
169 deletions.
There are no files selected for viewing
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
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 |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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
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 | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.