dynamic_variable 1.0.0 → 1.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/ChangeLog.md +9 -0
- data/README.md +33 -0
- data/Rakefile +1 -2
- data/VERSION +1 -1
- data/doc/readme_code/03mixin.rb +28 -0
- data/doc/readme_code/{03simple_with.rb → 04simple_with.rb} +1 -1
- data/dynamic_variable.gemspec +7 -4
- data/lib/dynamic_variable.rb +93 -20
- data/spec/dynamic_variable_spec.rb +194 -23
- metadata +8 -5
data/ChangeLog.md
ADDED
data/README.md
CHANGED
@@ -4,6 +4,12 @@ Occasionally a method's behavior should depend on the context in which it is cal
|
|
4
4
|
|
5
5
|
DynamicVariable is similar to [dynamic scope](http://c2.com/cgi/wiki?DynamicScoping), [fluid-let](http://www.megasolutions.net/scheme/fluid-binding-25366.aspx), [SRFI 39 parameters](http://srfi.schemers.org/srfi-39/srfi-39.html), [cflow pointcuts](http://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html#d0e5410), even [Scala has its own DynamicVariable](http://www.scala-lang.org/api/current/scala/util/DynamicVariable.html).
|
6
6
|
|
7
|
+
# Install
|
8
|
+
|
9
|
+
Nothing fancy:
|
10
|
+
|
11
|
+
> sudo gem install dynamic_variable
|
12
|
+
|
7
13
|
# Example: Context Dependent Debugging
|
8
14
|
|
9
15
|
Suppose we have a method which is `frequently_called`. It works fine except when called from `source_of_the_trouble`. Suppose further that `source_of_the_trouble` doesn't directly invoke `frequently_called` instead there's a method `in_the_middle`. Our setup looks like this:
|
@@ -75,6 +81,33 @@ A DynamicVariable storing one `:value` and then `:another`:
|
|
75
81
|
dv.value.should == 2
|
76
82
|
end
|
77
83
|
|
84
|
+
# DynamicVariable::Mixin
|
85
|
+
|
86
|
+
The Mixin module adds a dynamic variable quality to any class:
|
87
|
+
|
88
|
+
class MixinExample
|
89
|
+
include DynamicVariable::Mixin
|
90
|
+
|
91
|
+
attr_accessor :x
|
92
|
+
|
93
|
+
def try
|
94
|
+
self.x = 4
|
95
|
+
x.should == 4
|
96
|
+
with(:x, 3) do
|
97
|
+
x.should == 3
|
98
|
+
self.x = 2
|
99
|
+
x.should == 2
|
100
|
+
with(:x, 1) do
|
101
|
+
x.should == 1
|
102
|
+
end
|
103
|
+
x.should == 2
|
104
|
+
end
|
105
|
+
x.should == 4
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
MixinExample.new.try
|
110
|
+
|
78
111
|
# Why have a library?
|
79
112
|
|
80
113
|
Isn't it easy to set and reset a flag as the context changes? Sure, just watch out for raise, throw, and nesting:
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.0
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../../lib/dynamic_variable'
|
2
|
+
|
3
|
+
describe 'DynamicVariable::Mixin' do it "should behave" do
|
4
|
+
|
5
|
+
class MixinExample
|
6
|
+
include DynamicVariable::Mixin
|
7
|
+
|
8
|
+
attr_accessor :x
|
9
|
+
|
10
|
+
def try
|
11
|
+
self.x = 4
|
12
|
+
x.should == 4
|
13
|
+
with(:x, 3) do
|
14
|
+
x.should == 3
|
15
|
+
self.x = 2
|
16
|
+
x.should == 2
|
17
|
+
with(:x, 1) do
|
18
|
+
x.should == 1
|
19
|
+
end
|
20
|
+
x.should == 2
|
21
|
+
end
|
22
|
+
x.should == 4
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
MixinExample.new.try
|
27
|
+
|
28
|
+
end end
|
data/dynamic_variable.gemspec
CHANGED
@@ -5,24 +5,27 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dynamic_variable}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["William Taysom"]
|
12
|
-
s.date = %q{2010-09-
|
12
|
+
s.date = %q{2010-09-12}
|
13
13
|
s.description = %q{Occasionally a method's behavior should depend on the context in which it is called. What is happening above me on the stack? DynamicVariable helps you in these context dependent situations.}
|
14
14
|
s.email = %q{wtaysom@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
|
-
"
|
16
|
+
"ChangeLog.md",
|
17
|
+
"README.md"
|
17
18
|
]
|
18
19
|
s.files = [
|
19
20
|
".gitignore",
|
21
|
+
"ChangeLog.md",
|
20
22
|
"README.md",
|
21
23
|
"Rakefile",
|
22
24
|
"VERSION",
|
23
25
|
"doc/readme_code/01example_at_start.rb",
|
24
26
|
"doc/readme_code/02example_with_debug.rb",
|
25
|
-
"doc/readme_code/
|
27
|
+
"doc/readme_code/03mixin.rb",
|
28
|
+
"doc/readme_code/04simple_with.rb",
|
26
29
|
"dynamic_variable.gemspec",
|
27
30
|
"lib/dynamic_variable.rb",
|
28
31
|
"spec/dynamic_variable_spec.rb"
|
data/lib/dynamic_variable.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
class DynamicVariable
|
2
|
-
|
2
|
+
attr_accessor :default_variable
|
3
3
|
|
4
4
|
def initialize(*pairs, &block)
|
5
|
+
self.default_variable = :value
|
5
6
|
@bindings = []
|
6
7
|
if block_given?
|
7
8
|
with(*pairs, &block)
|
@@ -23,38 +24,29 @@ class DynamicVariable
|
|
23
24
|
|
24
25
|
##
|
25
26
|
# with {}
|
26
|
-
# varible defaults to
|
27
|
+
# varible defaults to default_variable
|
27
28
|
# value defaults to nil
|
28
29
|
#
|
29
30
|
# with(value) { block }
|
30
|
-
# variable defaults to
|
31
|
+
# variable defaults to default_variable
|
31
32
|
#
|
32
33
|
# with(variable, value) { block }
|
33
34
|
#
|
34
35
|
# with(variable_1, value_1, ..., variable_n_1, value_n_1, value_n) { block }
|
35
|
-
# variable_n defaults to
|
36
|
+
# variable_n defaults to default_variable
|
36
37
|
#
|
37
38
|
# with(variable_1, value_1, ..., variable_n, value_n) { block }
|
38
39
|
#
|
39
40
|
def with(*pairs)
|
40
41
|
pairs = [nil] if pairs.empty?
|
41
|
-
push_pairs(pairs)
|
42
42
|
begin
|
43
|
+
push_pairs(pairs)
|
43
44
|
yield(self)
|
44
45
|
ensure
|
45
46
|
pop_pairs(pairs)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
|
-
def with_module
|
50
|
-
this = self
|
51
|
-
mod = Module.new
|
52
|
-
mod.send(:define_method, :with) do |*args, &block|
|
53
|
-
this.with(*args, &block)
|
54
|
-
end
|
55
|
-
mod
|
56
|
-
end
|
57
|
-
|
58
50
|
def [](variable)
|
59
51
|
find_binding(variable)[1]
|
60
52
|
end
|
@@ -70,7 +62,8 @@ class DynamicVariable
|
|
70
62
|
else
|
71
63
|
writer = variable
|
72
64
|
unless args.size == 1 and writer.to_s =~ /(.*)=/
|
73
|
-
raise NoMethodError,
|
65
|
+
raise NoMethodError,
|
66
|
+
"undefined method `#{writer}' for #{self.inspect}"
|
74
67
|
end
|
75
68
|
variable = $1.to_sym
|
76
69
|
self[variable] = args[0]
|
@@ -89,8 +82,8 @@ class DynamicVariable
|
|
89
82
|
variables.each{|variable, value| self[variable] = value}
|
90
83
|
end
|
91
84
|
|
92
|
-
def bindings(variable =
|
93
|
-
if
|
85
|
+
def bindings(variable = (un = true))
|
86
|
+
if un
|
94
87
|
@bindings.map{|pair| pair.clone}
|
95
88
|
else
|
96
89
|
@bindings.select{|var, value| var == variable}.map!{|var, value| value}
|
@@ -101,8 +94,8 @@ class DynamicVariable
|
|
101
94
|
set_bindings(bindings)
|
102
95
|
end
|
103
96
|
|
104
|
-
def set_bindings(variable, bindings =
|
105
|
-
if
|
97
|
+
def set_bindings(variable, bindings = (un = true))
|
98
|
+
if un
|
106
99
|
bindings = variable
|
107
100
|
@bindings = bindings.map do |pair|
|
108
101
|
unless pair.is_a? Array and pair.size == 2
|
@@ -138,6 +131,86 @@ class DynamicVariable
|
|
138
131
|
bindings
|
139
132
|
end
|
140
133
|
|
134
|
+
module Mixin
|
135
|
+
class MixedDynamicVariable < DynamicVariable
|
136
|
+
def initialize(mix)
|
137
|
+
super()
|
138
|
+
@mix = mix
|
139
|
+
end
|
140
|
+
|
141
|
+
def push(variable, value)
|
142
|
+
old_value = @mix.send(variable)
|
143
|
+
begin
|
144
|
+
pair = begin
|
145
|
+
find_binding(variable)
|
146
|
+
rescue ArgumentError
|
147
|
+
super
|
148
|
+
end
|
149
|
+
pair[1] = old_value
|
150
|
+
|
151
|
+
@mix.send(variable.to_s+"=", value)
|
152
|
+
super
|
153
|
+
rescue Exception
|
154
|
+
@bindings.pop
|
155
|
+
raise
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def pop(variable)
|
160
|
+
value = super
|
161
|
+
begin
|
162
|
+
old_value = find_binding(variable)[1]
|
163
|
+
rescue ArgumentError
|
164
|
+
return value
|
165
|
+
end
|
166
|
+
@mix.send(variable.to_s+"=", old_value)
|
167
|
+
value
|
168
|
+
ensure
|
169
|
+
if @bindings.count{|var, value| var == variable} == 1
|
170
|
+
super
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def [](variable)
|
175
|
+
find_binding(variable)[1] = @mix.send(variable)
|
176
|
+
end
|
177
|
+
|
178
|
+
def []=(variable, value)
|
179
|
+
@mix.send(variable.to_s+"=", super)
|
180
|
+
end
|
181
|
+
|
182
|
+
alias original_variables variables
|
183
|
+
private :original_variables
|
184
|
+
|
185
|
+
def variables
|
186
|
+
variables = super
|
187
|
+
variables.each_key do |variable|
|
188
|
+
variables[variable] = self[variable]
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def bindings(*args)
|
193
|
+
variables
|
194
|
+
super
|
195
|
+
end
|
196
|
+
|
197
|
+
def set_bindings(*args)
|
198
|
+
bindings = super
|
199
|
+
self.variables = original_variables
|
200
|
+
bindings
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def dynamic_variable
|
205
|
+
@dynamic_variable_mixin__dynamic_variable ||=
|
206
|
+
MixedDynamicVariable.new(self)
|
207
|
+
end
|
208
|
+
|
209
|
+
def with(*pairs, &block)
|
210
|
+
dynamic_variable.with(*pairs, &block)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
141
214
|
private
|
142
215
|
|
143
216
|
def find_binding(variable)
|
@@ -153,7 +226,7 @@ private
|
|
153
226
|
end
|
154
227
|
|
155
228
|
def push_pairs(pairs)
|
156
|
-
pairs.insert(-2,
|
229
|
+
pairs.insert(-2, default_variable) if pairs.size.odd?
|
157
230
|
each_pair(pairs) {|variable, value| push(variable, value)}
|
158
231
|
end
|
159
232
|
|
@@ -3,10 +3,6 @@ require 'dynamic_variable'
|
|
3
3
|
describe DynamicVariable do
|
4
4
|
subject { DynamicVariable.new }
|
5
5
|
|
6
|
-
before do
|
7
|
-
extend subject.with_module
|
8
|
-
end
|
9
|
-
|
10
6
|
### Utilities ###
|
11
7
|
|
12
8
|
def x_and_y_bindings
|
@@ -195,27 +191,28 @@ describe DynamicVariable do
|
|
195
191
|
|
196
192
|
describe '#with' do
|
197
193
|
it "should make bindings and clean up when done" do
|
198
|
-
with(:key, :value) do
|
194
|
+
subject.with(:key, :value) do
|
199
195
|
subject.bindings.should == [[:key, :value]]
|
200
196
|
end
|
201
197
|
bindings_should_be_empty
|
202
198
|
end
|
203
199
|
|
204
200
|
it "should yield self to the block" do
|
205
|
-
with do |dv|
|
201
|
+
subject.with do |dv|
|
206
202
|
dv.should == subject
|
207
203
|
end
|
208
204
|
end
|
209
205
|
|
210
206
|
it "should return the result of its block" do
|
211
|
-
with{:result}.should == :result
|
207
|
+
subject.with{:result}.should == :result
|
212
208
|
end
|
213
209
|
|
214
210
|
it "should nest nicely" do
|
215
|
-
with(:value) do
|
211
|
+
subject.with(:value) do
|
216
212
|
subject.bindings.should == [[:value, :value]]
|
217
|
-
with(:second_value) do
|
218
|
-
subject.bindings.should == [[:value, :value],
|
213
|
+
subject.with(:second_value) do
|
214
|
+
subject.bindings.should == [[:value, :value],
|
215
|
+
[:value, :second_value]]
|
219
216
|
end
|
220
217
|
subject.bindings.should == [[:value, :value]]
|
221
218
|
end
|
@@ -224,7 +221,7 @@ describe DynamicVariable do
|
|
224
221
|
|
225
222
|
it "should be exception safe" do
|
226
223
|
expect do
|
227
|
-
with(:value) do
|
224
|
+
subject.with(:value) do
|
228
225
|
subject.bindings.should == [[:value, :value]]
|
229
226
|
raise
|
230
227
|
end
|
@@ -235,7 +232,7 @@ describe DynamicVariable do
|
|
235
232
|
context "when called" do
|
236
233
|
context "with no arguments" do
|
237
234
|
it "should bind :value to nil" do
|
238
|
-
with do
|
235
|
+
subject.with do
|
239
236
|
subject.bindings.should == [[:value, nil]]
|
240
237
|
end
|
241
238
|
end
|
@@ -243,7 +240,7 @@ describe DynamicVariable do
|
|
243
240
|
|
244
241
|
context "with one argument" do
|
245
242
|
it "should bind :value to argument" do
|
246
|
-
with(:argument) do
|
243
|
+
subject.with(:argument) do
|
247
244
|
subject.bindings.should == [[:value, :argument]]
|
248
245
|
end
|
249
246
|
end
|
@@ -251,7 +248,7 @@ describe DynamicVariable do
|
|
251
248
|
|
252
249
|
context "with two arguments" do
|
253
250
|
it "should bind the first to the second" do
|
254
|
-
with(:first, :second) do
|
251
|
+
subject.with(:first, :second) do
|
255
252
|
subject.bindings.should == [[:first, :second]]
|
256
253
|
end
|
257
254
|
end
|
@@ -259,7 +256,7 @@ describe DynamicVariable do
|
|
259
256
|
|
260
257
|
context "with an odd number of arguments" do
|
261
258
|
it "should bind :value to the second to last" do
|
262
|
-
with(:first, :second, :last) do
|
259
|
+
subject.with(:first, :second, :last) do
|
263
260
|
subject.bindings.should == [[:first, :second], [:value, :last]]
|
264
261
|
end
|
265
262
|
end
|
@@ -267,7 +264,7 @@ describe DynamicVariable do
|
|
267
264
|
|
268
265
|
context "with an even number of arguments" do
|
269
266
|
it "should bind variable, value pairs" do
|
270
|
-
with(:var1, :val1, :var2, :val2, :var3, :val3) do
|
267
|
+
subject.with(:var1, :val1, :var2, :val2, :var3, :val3) do
|
271
268
|
subject.bindings.should ==
|
272
269
|
[[:var1, :val1], [:var2, :val2], [:var3, :val3]]
|
273
270
|
end
|
@@ -276,7 +273,7 @@ describe DynamicVariable do
|
|
276
273
|
|
277
274
|
context "with a variable repeated more than once" do
|
278
275
|
it "should bind the variable twice and unbind when done" do
|
279
|
-
with(:var, 1, :var, 2) do
|
276
|
+
subject.with(:var, 1, :var, 2) do
|
280
277
|
subject.bindings.should == [[:var, 1], [:var, 2]]
|
281
278
|
end
|
282
279
|
subject.bindings.should == []
|
@@ -294,12 +291,25 @@ describe DynamicVariable do
|
|
294
291
|
end
|
295
292
|
end
|
296
293
|
|
297
|
-
describe '#
|
298
|
-
it
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
294
|
+
describe '#default_variable' do
|
295
|
+
it 'should default to :value' do
|
296
|
+
subject.default_variable.should == :value
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
describe '#default_variable=' do
|
301
|
+
context 'when #with is called' do
|
302
|
+
it 'should use default_variable for 0 and odd numbers of bindings' do
|
303
|
+
subject.default_variable = :v
|
304
|
+
subject.with do
|
305
|
+
subject.with(1) do
|
306
|
+
subject.with(:v, 2, 3) do
|
307
|
+
subject.bindings.should ==
|
308
|
+
[[:v, nil], [:v, 1], [:v, 2], [:v, 3]]
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
303
313
|
end
|
304
314
|
end
|
305
315
|
|
@@ -577,4 +587,165 @@ describe DynamicVariable do
|
|
577
587
|
end
|
578
588
|
end
|
579
589
|
end
|
590
|
+
|
591
|
+
describe DynamicVariable::Mixin do
|
592
|
+
class MixinExample
|
593
|
+
include DynamicVariable::Mixin
|
594
|
+
|
595
|
+
attr_accessor :x, :y
|
596
|
+
end
|
597
|
+
|
598
|
+
subject { MixinExample.new }
|
599
|
+
|
600
|
+
describe '#with' do
|
601
|
+
it "should bind attributes dynamically" do
|
602
|
+
subject.x = 5
|
603
|
+
subject.with(:x, 4, :y, 3) do
|
604
|
+
subject.x.should == 4
|
605
|
+
subject.y.should == 3
|
606
|
+
subject.y = 2
|
607
|
+
subject.y.should == 2
|
608
|
+
subject.with(:x, 1, :y, 0) do
|
609
|
+
subject.x.should == 1
|
610
|
+
subject.y.should == 0
|
611
|
+
end
|
612
|
+
subject.x.should == 4
|
613
|
+
subject.y.should == 2
|
614
|
+
end
|
615
|
+
subject.x.should == 5
|
616
|
+
subject.y.should == nil
|
617
|
+
end
|
618
|
+
|
619
|
+
context "when readers and writers raise errors" do
|
620
|
+
context "when reader raises during push" do
|
621
|
+
it "should unbind bound variables" do
|
622
|
+
subject.x = 5
|
623
|
+
|
624
|
+
class <<subject
|
625
|
+
def y
|
626
|
+
raise "oops"
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
did_call_block = false
|
631
|
+
expect do
|
632
|
+
subject.with(:x, 4, :y, 3) do
|
633
|
+
did_call_block = true
|
634
|
+
end
|
635
|
+
end.should raise_error("oops")
|
636
|
+
|
637
|
+
subject.x.should == 5
|
638
|
+
subject.dynamic_variable.bindings.should == []
|
639
|
+
did_call_block.should be_false
|
640
|
+
end
|
641
|
+
end
|
642
|
+
|
643
|
+
context "when writer raises during push" do
|
644
|
+
it "should unbind bound variables" do
|
645
|
+
subject.x = 5
|
646
|
+
|
647
|
+
class <<subject
|
648
|
+
def x=(x)
|
649
|
+
raise "oops"
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
did_call_block = false
|
654
|
+
expect do
|
655
|
+
subject.with(:x, 4, :y, 3) do
|
656
|
+
did_call_block = true
|
657
|
+
end
|
658
|
+
end.should raise_error("oops")
|
659
|
+
|
660
|
+
subject.x.should == 5
|
661
|
+
subject.dynamic_variable.bindings.should == []
|
662
|
+
did_call_block.should be_false
|
663
|
+
end
|
664
|
+
end
|
665
|
+
|
666
|
+
context "when writer raises during pop" do
|
667
|
+
it "should unbind bound variables" do
|
668
|
+
subject.x = 5
|
669
|
+
|
670
|
+
did_call_block = false
|
671
|
+
expect do
|
672
|
+
subject.with(:x, 4, :y, 3) do
|
673
|
+
did_call_block = true
|
674
|
+
|
675
|
+
class <<subject
|
676
|
+
def y=(y)
|
677
|
+
raise "oops"
|
678
|
+
end
|
679
|
+
end
|
680
|
+
end
|
681
|
+
end.should raise_error("oops")
|
682
|
+
|
683
|
+
subject.x.should == 5
|
684
|
+
subject.dynamic_variable.bindings.should == []
|
685
|
+
did_call_block.should be_true
|
686
|
+
end
|
687
|
+
end
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
691
|
+
describe '#dynamic_variable' do
|
692
|
+
context "when reading a variable through" do
|
693
|
+
def self.it_should_be_up_to_date
|
694
|
+
it "should be up to date" do
|
695
|
+
subject.with(:x, 4, :y, 3) do
|
696
|
+
subject.x = 2
|
697
|
+
subject.y = 1
|
698
|
+
|
699
|
+
yield(subject.dynamic_variable)
|
700
|
+
end
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
context "#[]" do
|
705
|
+
it_should_be_up_to_date do |dv|
|
706
|
+
dv.x.should == 2
|
707
|
+
end
|
708
|
+
end
|
709
|
+
|
710
|
+
context "#variables" do
|
711
|
+
it_should_be_up_to_date do |dv|
|
712
|
+
dv.variables.should == {:x => 2, :y => 1}
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
context "#bindings" do
|
717
|
+
it_should_be_up_to_date do |dv|
|
718
|
+
dv.bindings.should == [[:x, nil], [:x, 2], [:y, nil], [:y, 1]]
|
719
|
+
end
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
context "when writing variable through" do
|
724
|
+
def self.it_should_be_updated
|
725
|
+
it "should be updated" do
|
726
|
+
subject.with(:x, 4, :y, 3) do
|
727
|
+
yield(subject, subject.dynamic_variable)
|
728
|
+
end
|
729
|
+
end
|
730
|
+
end
|
731
|
+
|
732
|
+
context "#[]=" do
|
733
|
+
it_should_be_updated do |subject, dv|
|
734
|
+
dv.x = 2
|
735
|
+
subject.x.should == 2
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
context "#bindings=" do
|
740
|
+
it_should_be_updated do |subject, dv|
|
741
|
+
dv.bindings.should == [[:x, nil], [:x, 4], [:y, nil], [:y, 3]]
|
742
|
+
|
743
|
+
dv.bindings = [[:x, nil], [:x, 2], [:y, nil], [:y, 1]]
|
744
|
+
subject.x.should == 2
|
745
|
+
subject.y.should == 1
|
746
|
+
end
|
747
|
+
end
|
748
|
+
end
|
749
|
+
end
|
750
|
+
end
|
580
751
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamic_variable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- William Taysom
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-12 00:00:00 +08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -26,15 +26,18 @@ executables: []
|
|
26
26
|
extensions: []
|
27
27
|
|
28
28
|
extra_rdoc_files:
|
29
|
+
- ChangeLog.md
|
29
30
|
- README.md
|
30
31
|
files:
|
31
32
|
- .gitignore
|
33
|
+
- ChangeLog.md
|
32
34
|
- README.md
|
33
35
|
- Rakefile
|
34
36
|
- VERSION
|
35
37
|
- doc/readme_code/01example_at_start.rb
|
36
38
|
- doc/readme_code/02example_with_debug.rb
|
37
|
-
- doc/readme_code/
|
39
|
+
- doc/readme_code/03mixin.rb
|
40
|
+
- doc/readme_code/04simple_with.rb
|
38
41
|
- dynamic_variable.gemspec
|
39
42
|
- lib/dynamic_variable.rb
|
40
43
|
- spec/dynamic_variable_spec.rb
|