deject 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/deject.gemspec +2 -3
- data/lib/deject.rb +98 -6
- data/lib/deject/version.rb +1 -1
- data/spec/acceptance_spec.rb +4 -4
- data/spec/class_methods_spec.rb +51 -4
- data/spec/deject_function_spec.rb +8 -2
- data/spec/global_registration_spec.rb +47 -0
- data/spec/instance_methods_spec.rb +9 -2
- data/spec/spec_helper.rb +19 -0
- metadata +12 -9
- data/lib/deject/functional.rb +0 -48
- data/lib/deject/object_oriented.rb +0 -82
data/deject.gemspec
CHANGED
@@ -12,9 +12,9 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.description = %q{Provides a super simple API for dependency injection}
|
13
13
|
|
14
14
|
s.rubyforge_project = "deject"
|
15
|
-
|
15
|
+
|
16
16
|
s.required_ruby_version = "~> 1.9.2"
|
17
|
-
|
17
|
+
|
18
18
|
s.files = `git ls-files`.split("\n")
|
19
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -23,5 +23,4 @@ Gem::Specification.new do |s|
|
|
23
23
|
# specify any dependencies here; for example:
|
24
24
|
s.add_development_dependency "rspec"
|
25
25
|
s.add_development_dependency "pry"
|
26
|
-
# s.add_runtime_dependency "rest-client"
|
27
26
|
end
|
data/lib/deject.rb
CHANGED
@@ -1,8 +1,100 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
require "deject/version"
|
2
|
+
|
3
|
+
module Deject
|
4
|
+
UninitializedDependency = Class.new StandardError
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def register(name, &initializer)
|
8
|
+
raise ArgumentError, "#{name} has been registered multiple times" if registered? name
|
9
|
+
raise ArgumentError, "#{name} has been registered with Deject without an initialization block" unless initializer
|
10
|
+
@registered[name.intern] = initializer
|
11
|
+
end
|
12
|
+
|
13
|
+
def registered(name)
|
14
|
+
@registered[name.intern]
|
15
|
+
end
|
16
|
+
|
17
|
+
def registered?(name)
|
18
|
+
@registered.has_key? name.intern
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset
|
22
|
+
@registered = {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
reset
|
6
27
|
end
|
7
28
|
|
8
|
-
|
29
|
+
# Not a common way of writing code in Ruby, I know.
|
30
|
+
# But I tried out several implementations and found this was the easiest to
|
31
|
+
# work with within the constraints of the gem (that it doesn't leave traces
|
32
|
+
# of itself all over your objects)
|
33
|
+
def Deject(klass)
|
34
|
+
uninitialized_error = lambda do |meth|
|
35
|
+
raise Deject::UninitializedDependency, "#{meth} invoked before being defined"
|
36
|
+
end
|
37
|
+
|
38
|
+
define_instance_methods = lambda do |meth, default_block|
|
39
|
+
# define the getter
|
40
|
+
define_method meth do
|
41
|
+
block = default_block || Deject.registered(meth)
|
42
|
+
uninitialized_error[meth] unless block
|
43
|
+
value = block.call self
|
44
|
+
define_singleton_method(meth) { value }
|
45
|
+
send meth
|
46
|
+
end
|
47
|
+
|
48
|
+
# define the override
|
49
|
+
define_method :"with_#{meth}" do |value=nil, &block|
|
50
|
+
|
51
|
+
# redefine getter if given a block
|
52
|
+
if block
|
53
|
+
define_singleton_method meth do
|
54
|
+
value = block.call self
|
55
|
+
define_singleton_method(meth) { value }
|
56
|
+
send meth
|
57
|
+
end
|
58
|
+
|
59
|
+
# always return value if given a value
|
60
|
+
else
|
61
|
+
define_singleton_method(meth) { value }
|
62
|
+
end
|
63
|
+
|
64
|
+
self
|
65
|
+
end
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
has_dependency = lambda do |meth|
|
70
|
+
instance_methods.include?(meth.intern) && instance_methods.include?(:"with_#{meth}")
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# define klass.dependency
|
75
|
+
klass.define_singleton_method :dependency do |meth, &default_block|
|
76
|
+
if instance_exec meth, &has_dependency
|
77
|
+
warn "Deprecation: Use .override instead of .dependency to override a dependency"
|
78
|
+
end
|
79
|
+
instance_exec meth, default_block, &define_instance_methods
|
80
|
+
end
|
81
|
+
|
82
|
+
# define klass.override
|
83
|
+
klass.define_singleton_method :override do |meth, &override_block|
|
84
|
+
if !override_block
|
85
|
+
raise ArgumentError, "Cannot override #{meth} without an override block" unless override_block
|
86
|
+
elsif !instance_exec(meth, &has_dependency)
|
87
|
+
raise ArgumentError, "#{meth} is not a dependency of #{klass.inspect}"
|
88
|
+
else
|
89
|
+
instance_exec meth, override_block, &define_instance_methods
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# override multiple dependencies
|
94
|
+
klass.send :define_method, :with_dependencies do |overrides|
|
95
|
+
overrides.each { |meth, value| send "with_#{meth}", value }
|
96
|
+
self
|
97
|
+
end
|
98
|
+
|
99
|
+
klass
|
100
|
+
end
|
data/lib/deject/version.rb
CHANGED
data/spec/acceptance_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Deject, 'acceptance tests' do
|
4
4
|
example 'setting and overriding' do
|
@@ -22,13 +22,13 @@ describe Deject, 'acceptance tests' do
|
|
22
22
|
|
23
23
|
class Service
|
24
24
|
Deject self
|
25
|
-
dependency(:client) { Client.new credentials }
|
25
|
+
dependency(:client) { |service| Client.new service.credentials }
|
26
26
|
|
27
27
|
attr_accessor :name
|
28
28
|
|
29
29
|
def initialize(name)
|
30
30
|
self.name = name
|
31
|
-
end
|
31
|
+
end
|
32
32
|
|
33
33
|
def login
|
34
34
|
client.login name
|
@@ -51,7 +51,7 @@ describe Deject, 'acceptance tests' do
|
|
51
51
|
Service.new('sally').with_client(client).login
|
52
52
|
|
53
53
|
client_class, client = double, double
|
54
|
-
george = Service.new('george').with_client { client_class.new credentials }
|
54
|
+
george = Service.new('george').with_client { |service| client_class.new service.credentials }
|
55
55
|
client_class.should_receive(:new).with(george.credentials).and_return(client)
|
56
56
|
client.should_receive(:login).with('george')
|
57
57
|
george.login
|
data/spec/class_methods_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
|
4
4
|
describe 'Klass.dependency' do
|
@@ -10,7 +10,7 @@ describe 'Klass.dependency' do
|
|
10
10
|
meth = 'meth'.freeze
|
11
11
|
result = 100
|
12
12
|
before { klass.dependency(meth) { result } }
|
13
|
-
|
13
|
+
|
14
14
|
it 'adds the instance method' do
|
15
15
|
klass.new.should respond_to meth
|
16
16
|
end
|
@@ -18,11 +18,20 @@ describe 'Klass.dependency' do
|
|
18
18
|
specify 'the instance method defaults to the result of the init block' do
|
19
19
|
klass.new.send(meth).should == result
|
20
20
|
end
|
21
|
-
|
22
|
-
specify 'the instance method is evaluated within the context of the
|
21
|
+
|
22
|
+
specify 'the instance method is evaluated within the context of the caller' do
|
23
23
|
klass.dependency(:a) { b }
|
24
24
|
instance = klass.new
|
25
25
|
def instance.b() 10 end
|
26
|
+
def self.b() 20 end
|
27
|
+
instance.a.should == self.b
|
28
|
+
end
|
29
|
+
|
30
|
+
specify 'the instance method is passed the instance' do
|
31
|
+
klass.dependency(:a) { |instance| instance.b }
|
32
|
+
instance = klass.new
|
33
|
+
def instance.b() 10 end
|
34
|
+
def self.b() end
|
26
35
|
instance.a.should == instance.b
|
27
36
|
end
|
28
37
|
end
|
@@ -37,5 +46,43 @@ describe 'Klass.dependency' do
|
|
37
46
|
klass.dependency :jjjjj
|
38
47
|
expect { klass.new.jjjjj }.to raise_error(Deject::UninitializedDependency, /jjjjj/)
|
39
48
|
end
|
49
|
+
|
50
|
+
it 'uses the global block if provided, passing it the instance' do
|
51
|
+
Deject.register(:meth) { |instance| instance.value }
|
52
|
+
klass.dependency :meth
|
53
|
+
instance = klass.new
|
54
|
+
def instance.value() :value end
|
55
|
+
instance.meth.should == :value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'writes a deprecated warning when using dependency to override an existing dependency' do
|
60
|
+
catch_stderr { klass.dependency :dep }.should == ""
|
61
|
+
catch_stderr { klass.dependency :dep }.should =~ /deprecat/i
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
describe 'Klass.override' do
|
67
|
+
let(:klass) { Deject Class.new }
|
68
|
+
|
69
|
+
it "raises an ArgumentError if called for a dependency that doesn't exist" do
|
70
|
+
expect { klass.override(:dep) {} }.to raise_error ArgumentError, /dep/
|
71
|
+
end
|
72
|
+
|
73
|
+
it "raises an ArgumentError if called without a block" do
|
74
|
+
klass.dependency :dep
|
75
|
+
expect { klass.override :dep }.to raise_error ArgumentError, /block/
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'overrides the dependency on the instance' do
|
79
|
+
klass.dependency :dep
|
80
|
+
klass.override(:dep) { 123 }
|
81
|
+
klass.new.dep.should == 123
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'returns the class' do
|
85
|
+
klass.dependency :dep
|
86
|
+
klass.override(:dep) { 123 }.should equal klass
|
40
87
|
end
|
41
88
|
end
|
@@ -1,14 +1,20 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Deject()' do
|
4
4
|
let(:klass) { Class.new }
|
5
|
-
|
5
|
+
|
6
6
|
it 'adds the dependency method to the class' do
|
7
7
|
klass.should_not respond_to :dependency
|
8
8
|
Deject klass
|
9
9
|
klass.should respond_to :dependency
|
10
10
|
end
|
11
11
|
|
12
|
+
it 'adds the override_dependency method to the class' do
|
13
|
+
klass.should_not respond_to :override
|
14
|
+
Deject klass
|
15
|
+
klass.should respond_to :override
|
16
|
+
end
|
17
|
+
|
12
18
|
it 'returns the class' do
|
13
19
|
Deject(klass).should be klass
|
14
20
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Deject, '.register and registered' do
|
4
|
+
let(:value) { 12 }
|
5
|
+
|
6
|
+
after { Deject.reset }
|
7
|
+
|
8
|
+
it 'accepts a string' do
|
9
|
+
Deject.register("abc") { value }
|
10
|
+
Deject.registered("abc").call.should == value
|
11
|
+
Deject.registered(:abc).call.should == value
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'accepts a symbol' do
|
15
|
+
Deject.register(:abc) { value }
|
16
|
+
Deject.registered("abc").call.should == value
|
17
|
+
Deject.registered(:abc).call.should == value
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'register raises an ArgumentError if not provided with a block' do
|
21
|
+
expect { Deject.register :abc }.to raise_error ArgumentError, /block/i
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'remembers what it was registered with' do
|
25
|
+
i = 0
|
26
|
+
Deject.register(:abc) { i += 1 }
|
27
|
+
Deject.registered(:abc).call.should == 1
|
28
|
+
i.should == 1
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns nil when asked for something not registered' do
|
32
|
+
Deject.registered(:abc).should == nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'raises an ArgumentError error if registration clobbers a previously set value' do
|
36
|
+
Deject.register(:abc){}
|
37
|
+
expect { Deject.register(:abc){} }.to raise_error ArgumentError, /abc/
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'knows what has been registered' do
|
41
|
+
Deject.should_not be_registered :abc
|
42
|
+
Deject.should_not be_registered 'abc'
|
43
|
+
Deject.register(:abc) {}
|
44
|
+
Deject.should be_registered :abc
|
45
|
+
Deject.should be_registered 'abc'
|
46
|
+
end
|
47
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'after initializing a dependency' do
|
4
4
|
let(:klass) { Deject Class.new }
|
@@ -27,7 +27,7 @@ describe 'after initializing a dependency' do
|
|
27
27
|
klass.dependency(:number1) { 1 }
|
28
28
|
klass.dependency(:number2) { 2 }
|
29
29
|
i = 0
|
30
|
-
instance = klass.new.with_number2 { i += number1 }
|
30
|
+
instance = klass.new.with_number2 { |instance| i += instance.number1 }
|
31
31
|
instance.number2.should == instance.number1
|
32
32
|
instance.number2.should == instance.number1
|
33
33
|
i.should == instance.number1
|
@@ -43,4 +43,11 @@ describe 'after initializing a dependency' do
|
|
43
43
|
instance.a.should == 10
|
44
44
|
instance.b.should == 20
|
45
45
|
end
|
46
|
+
|
47
|
+
specify '#with_<dependency> is passed the instance' do
|
48
|
+
klass.dependency(:a) { |instance| instance.b }
|
49
|
+
instance = klass.new
|
50
|
+
def instance.b() 10 end
|
51
|
+
instance.a.should == instance.b
|
52
|
+
end
|
46
53
|
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'deject'
|
2
|
+
|
3
|
+
catch_stderr = Module.new do
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
def catch_stderr
|
7
|
+
old_stderr = $stderr
|
8
|
+
$stderr = StringIO.new
|
9
|
+
yield
|
10
|
+
ensure
|
11
|
+
to_return = $stderr.string
|
12
|
+
$stderr = old_stderr
|
13
|
+
return to_return
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.include catch_stderr
|
19
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deject
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70114295054960 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70114295054960
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: pry
|
27
|
-
requirement: &
|
27
|
+
requirement: &70114295054020 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70114295054020
|
36
36
|
description: Provides a super simple API for dependency injection
|
37
37
|
email:
|
38
38
|
- josh.cheek@gmail.com
|
@@ -46,13 +46,13 @@ files:
|
|
46
46
|
- Readme.md
|
47
47
|
- deject.gemspec
|
48
48
|
- lib/deject.rb
|
49
|
-
- lib/deject/functional.rb
|
50
|
-
- lib/deject/object_oriented.rb
|
51
49
|
- lib/deject/version.rb
|
52
50
|
- spec/acceptance_spec.rb
|
53
51
|
- spec/class_methods_spec.rb
|
54
52
|
- spec/deject_function_spec.rb
|
53
|
+
- spec/global_registration_spec.rb
|
55
54
|
- spec/instance_methods_spec.rb
|
55
|
+
- spec/spec_helper.rb
|
56
56
|
homepage: https://github.com/JoshCheek/deject
|
57
57
|
licenses: []
|
58
58
|
post_install_message:
|
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
73
|
version: '0'
|
74
74
|
requirements: []
|
75
75
|
rubyforge_project: deject
|
76
|
-
rubygems_version: 1.8.
|
76
|
+
rubygems_version: 1.8.11
|
77
77
|
signing_key:
|
78
78
|
specification_version: 3
|
79
79
|
summary: Simple dependency injection
|
@@ -81,4 +81,7 @@ test_files:
|
|
81
81
|
- spec/acceptance_spec.rb
|
82
82
|
- spec/class_methods_spec.rb
|
83
83
|
- spec/deject_function_spec.rb
|
84
|
+
- spec/global_registration_spec.rb
|
84
85
|
- spec/instance_methods_spec.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
has_rdoc:
|
data/lib/deject/functional.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
module Deject
|
2
|
-
UninitializedDependency = Class.new StandardError
|
3
|
-
end
|
4
|
-
|
5
|
-
def Deject(klass)
|
6
|
-
uninitialized_error = lambda do |meth|
|
7
|
-
raise Deject::UninitializedDependency, "#{meth} invoked before being defined"
|
8
|
-
end
|
9
|
-
|
10
|
-
# define klass.dependency
|
11
|
-
klass.define_singleton_method :dependency do |meth, &default_block|
|
12
|
-
|
13
|
-
# define the getter
|
14
|
-
define_method meth do
|
15
|
-
uninitialized_error[meth] unless default_block
|
16
|
-
value = instance_eval &default_block
|
17
|
-
define_singleton_method(meth) { value }
|
18
|
-
send meth
|
19
|
-
end
|
20
|
-
|
21
|
-
# define the override
|
22
|
-
define_method :"with_#{meth}" do |value=nil, &block|
|
23
|
-
|
24
|
-
# redefine getter if given a block
|
25
|
-
if block
|
26
|
-
define_singleton_method meth do
|
27
|
-
value = instance_eval &block
|
28
|
-
define_singleton_method(meth) { value }
|
29
|
-
send meth
|
30
|
-
end
|
31
|
-
|
32
|
-
# always return value if given a value
|
33
|
-
else
|
34
|
-
define_singleton_method(meth) { value }
|
35
|
-
end
|
36
|
-
|
37
|
-
self
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# override multiple dependencies
|
42
|
-
klass.send :define_method, :with_dependencies do |overrides|
|
43
|
-
overrides.each { |meth, value| send "with_#{meth}", value }
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
47
|
-
klass
|
48
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
def Deject(klass)
|
2
|
-
klass.extend Deject
|
3
|
-
end
|
4
|
-
|
5
|
-
module Deject
|
6
|
-
UninitializedDependency = Class.new StandardError
|
7
|
-
|
8
|
-
def dependency(meth, &block)
|
9
|
-
InstanceMethods.for self, meth, block
|
10
|
-
end
|
11
|
-
|
12
|
-
|
13
|
-
class InstanceMethods
|
14
|
-
attr_accessor :klass, :meth, :initializer, :ivar
|
15
|
-
|
16
|
-
def self.for(klass, meth, initializer)
|
17
|
-
instance = new klass, meth, initializer
|
18
|
-
instance.define_getter
|
19
|
-
instance.define_override
|
20
|
-
instance.define_multi_override
|
21
|
-
end
|
22
|
-
|
23
|
-
def initialize(klass, meth, initializer)
|
24
|
-
self.klass, self.meth, self.initializer, self.ivar = klass, meth, initializer, "@#{meth}"
|
25
|
-
end
|
26
|
-
|
27
|
-
def define_getter
|
28
|
-
ivar, meth, initializer = self.ivar, self.meth, self.initializer
|
29
|
-
klass.send :define_method, meth do
|
30
|
-
unless instance_variable_defined? ivar
|
31
|
-
instance_variable_set ivar, Deject::Dependency.new(self, meth, initializer)
|
32
|
-
end
|
33
|
-
instance_variable_get(ivar).invoke
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def define_override
|
38
|
-
ivar, meth = self.ivar, self.meth
|
39
|
-
klass.send :define_method, "with_#{meth}" do |value=nil, &initializer|
|
40
|
-
initializer ||= Proc.new { value }
|
41
|
-
instance_variable_set ivar, Deject::Dependency.new(self, meth, initializer)
|
42
|
-
self
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def define_multi_override
|
47
|
-
klass.send :define_method, :with_dependencies do |overrides|
|
48
|
-
overrides.each { |meth, value| send "with_#{meth}", value }
|
49
|
-
self
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
class Dependency < Struct.new(:instance, :dependency, :initializer)
|
56
|
-
attr_accessor :result
|
57
|
-
|
58
|
-
def invoke
|
59
|
-
validate_initializer!
|
60
|
-
memoized_result
|
61
|
-
end
|
62
|
-
|
63
|
-
def validate_initializer!
|
64
|
-
return if initializer
|
65
|
-
raise UninitializedDependency, "#{dependency} invoked before being defined"
|
66
|
-
end
|
67
|
-
|
68
|
-
def memoized_result
|
69
|
-
memoize! unless memoized?
|
70
|
-
result
|
71
|
-
end
|
72
|
-
|
73
|
-
def memoized?
|
74
|
-
@memoized
|
75
|
-
end
|
76
|
-
|
77
|
-
def memoize!
|
78
|
-
@memoized = true
|
79
|
-
self.result = instance.instance_eval &initializer
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|