facets 1.8.0 → 1.8.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- # = annattr.rb
1
+ # = ann_attr.rb
2
2
  #
3
3
  # == Copyright (c) 2005 Thomas Sawyer
4
4
  #
@@ -14,6 +14,7 @@
14
14
  # == Authors & Contributors
15
15
  #
16
16
  # * Thomas Sawyer
17
+ # * George Moschovitis
17
18
 
18
19
  # Author:: Thomas Sawyer
19
20
  # Copyright:: Copyright (c) 2005 Thomas Sawyer
@@ -86,8 +87,9 @@ class ::Module
86
87
  }
87
88
  attributes!.concat( args ) #merge!
88
89
 
89
- if klass and klass.respond_to?(:included_as_property)
90
- klass.included_as_property(self, args)
90
+ # Use this callback to customize for your needs.
91
+ if respond_to?(:attr_callback)
92
+ attr_callback(self, args, harg)
91
93
  end
92
94
 
93
95
  # return the names of the attributes created
@@ -100,31 +102,26 @@ class ::Module
100
102
 
101
103
  class_eval( code )
102
104
 
105
+ # TODO Should attribute alias be kept?
103
106
  alias_method :attribute, :attr_accessor
104
- alias_method :property, :attr_accessor # for nitro
105
107
 
106
- # Return the serializable attributes of this class.
107
- # Serializable are attributes with the class annotation that
108
- # are not marked as :serializable => false.
108
+ # Return list of attributes that have a :class annotation.
109
109
  #
110
110
  # class MyClass
111
111
  # attr_accessor :test
112
112
  # attr_accessor :name, String, :doc => 'Hello'
113
113
  # attr_accessor :age, Fixnum
114
- # attr_accessor :body, String, :serialize => false
115
114
  # end
116
115
  #
117
116
  # MyClass.attributes # => [:test, :name, :age, :body]
118
- # MyClass.serializable_attributes # => [:name, :age]
117
+ # MyClass.classified_attributes # => [:name, :age]
119
118
 
120
- def serializable_attributes
121
- attributes.find_all do |a|
122
- anno = self.ann(a)
123
- anno.class? and (anno.serialize != false)
119
+ def classified_attributes
120
+ attributes.find_all do |a|
121
+ self.ann(a, :class)
124
122
  end
125
123
  end
126
124
 
127
-
128
125
  end
129
126
 
130
127
 
@@ -1,12 +1,12 @@
1
1
  # autovivify.rb
2
2
 
3
- require 'facets/more/openhash.rb'
3
+ require 'facets/more/openobject.rb'
4
4
 
5
5
  # AutoVivify module houses the +method_missing+ defintion.
6
6
 
7
7
  module AutoVivify
8
8
  def method_missing( name, *args, &block )
9
- oo = OpenHash.new
9
+ oo = OpenObject.new
10
10
  (class << self; self; end).send( :define_method, name ) { oo }
11
11
  end
12
12
  end
@@ -18,13 +18,13 @@
18
18
  # Thanks to Andrew Johnson for his suggestions and fixes of Hash[],
19
19
  # merge, to_a, inspect and shift.
20
20
  #
21
- # == Authors and Contributors
21
+ # == Authors & Contributors
22
22
  #
23
23
  # * Jan Molic
24
24
  # * Thomas Sawyer
25
25
 
26
- # Author:: Jan Molic, Thomas Sawyer
27
- # Copyright:: Copyright (c) 2006 Jan Molic, Thomas Sawyer
26
+ # Author:: Jan Molic
27
+ # Copyright:: Copyright (c) 2006 Jan Molic
28
28
  # License:: Ruby License
29
29
 
30
30
  # = Dictionary
@@ -77,10 +77,11 @@ class Dictionary < Hash
77
77
  #--
78
78
  # TODO is this needed? Doesn't the super class do this?
79
79
  #++
80
+
80
81
  def []( *args )
81
82
  hsh = new
82
83
  if Hash === args[0]
83
- hsh.replace( args[0] )
84
+ hsh.replace(args[0])
84
85
  elsif (args.size % 2) != 0
85
86
  raise ArgumentError, "odd number of elements for Hash"
86
87
  else
@@ -110,7 +111,7 @@ class Dictionary < Hash
110
111
  # Dictionary.new.order_by { |key,value| key }
111
112
 
112
113
  def alpha( *args, &block )
113
- new( *args, &block ).by_key
114
+ new( *args, &block ).order_by_key
114
115
  end
115
116
 
116
117
  # Alternate to #new which auto-creates sub-dictionaries as needed.
@@ -118,32 +119,17 @@ class Dictionary < Hash
118
119
  # d = Dictionary.auto
119
120
  # d["a"]["b"]["c"] = "abc" #=> { "a"=>{"b"=>{"c"=>"abc"}}}
120
121
  #
121
- #def auto( *args )
122
- # AutoDictionary.new(*args)
123
- # #leet = lambda { |hsh, key| hsh[key] = new( &leet ) }
124
- # #new(*args, &leet)
125
- #end
126
-
127
- # Alternate to #new which auto-creates sub-dictionaries as needed.
128
- #
129
- # d = Dictionary.autokey
130
- # d["a"]["b"]["c"] = "abc" #=> { "a"=>{"b"=>{"c"=>"abc"}}}
131
- #
132
- #def auto_alpha(*args)
133
- # auto(*args).order_by{ |k,v| k }
134
- # #AutoDictionary.new(*args).order_by{ |k,v| k }
135
- # #leet = lambda { |hsh, key| hsh[key] = new( &leet ) }
136
- # #new(*args, &leet).order_by{ |k,v| k }
137
- #end
138
-
122
+ def auto( *args )
123
+ #AutoDictionary.new(*args)
124
+ leet = lambda { |hsh, key| hsh[key] = new( &leet ) }
125
+ new(*args, &leet)
126
+ end
139
127
  end
140
128
 
141
- attr_accessor :order
142
-
143
129
  def initialize( *args, &blk )
144
130
  @order = []
145
131
  @order_by = nil
146
- super
132
+ @hash = Hash.new( *args, &blk )
147
133
  end
148
134
 
149
135
  def order
@@ -151,7 +137,7 @@ class Dictionary < Hash
151
137
  @order
152
138
  end
153
139
 
154
- # Keep dictionary sorted by sepcifiec sort order.
140
+ # Keep dictionary sorted by a specific sort order.
155
141
 
156
142
  def order_by( &block )
157
143
  @order_by = block
@@ -161,7 +147,7 @@ class Dictionary < Hash
161
147
 
162
148
  # Keep dictionary sorted by key.
163
149
  #
164
- # d = Dictionary.new.by_key
150
+ # d = Dictionary.new.order_by_key
165
151
  # d["z"] = 1
166
152
  # d["y"] = 2
167
153
  # d["x"] = 3
@@ -173,7 +159,7 @@ class Dictionary < Hash
173
159
  #
174
160
  # The initializer Dictionary#alpha also provides this.
175
161
 
176
- def by_key
162
+ def order_by_key
177
163
  @order_by = lambda { |k,v| k }
178
164
  order
179
165
  self
@@ -181,7 +167,7 @@ class Dictionary < Hash
181
167
 
182
168
  # Keep dictionary sorted by value.
183
169
  #
184
- # d = Dictionary.by_value
170
+ # d = Dictionary.new.order_by_value
185
171
  # d["z"] = 1
186
172
  # d["y"] = 2
187
173
  # d["x"] = 3
@@ -191,7 +177,7 @@ class Dictionary < Hash
191
177
  #
192
178
  # Dictionary.new.order_by { |key,value| value }
193
179
 
194
- def by_value
180
+ def order_by_value
195
181
  @order_by = lambda { |k,v| v }
196
182
  order
197
183
  self
@@ -201,31 +187,32 @@ class Dictionary < Hash
201
187
 
202
188
  def reorder
203
189
  if @order_by
204
- assoc = @order.collect{ |k| [k,self[k]] }.sort_by( &@order_by )
190
+ assoc = @order.collect{ |k| [k,@hash[k]] }.sort_by( &@order_by )
205
191
  @order = assoc.collect{ |k,v| k }
206
192
  end
207
193
  @order
208
194
  end
209
195
 
210
- #def store_only( a,b )
211
- # store( a,b )
196
+ #def ==( hsh2 )
197
+ # return false if @order != hsh2.order
198
+ # super hsh2
212
199
  #end
213
- #alias_method :store_only, :store
214
-
215
- alias_method :orig_store, :store
216
- protected :orig_store
217
200
 
218
- def insert( i,k,v )
219
- @order.insert(i,k)
220
- orig_store(k,v)
201
+ def ==( hsh2 )
202
+ if hsh2.is_a?( Dictionary )
203
+ @order == hsh2.order &&
204
+ @hash == hsh2.instance_variable_get("@hash")
205
+ else
206
+ false
207
+ end
221
208
  end
222
209
 
223
- #alias_method :unordered_store, :store
224
- #private :unordered_store
210
+ def [] k
211
+ @hash[ k ]
212
+ end
225
213
 
226
- def store( a,b )
227
- @order.push( a ) unless has_key? a
228
- super( a,b )
214
+ def fetch( k )
215
+ @hash.fetch( k )
229
216
  end
230
217
 
231
218
  # Store operator.
@@ -244,21 +231,24 @@ class Dictionary < Hash
244
231
  end
245
232
  end
246
233
 
247
- #
234
+ def insert( i,k,v )
235
+ @order.insert( i,k )
236
+ @hash.store( k,v )
237
+ end
248
238
 
249
- def ==( hsh2 )
250
- return false if @order != hsh2.order
251
- super hsh2
239
+ def store( a,b )
240
+ @order.push( a ) unless @hash.has_key?( a )
241
+ @hash.store( a,b )
252
242
  end
253
243
 
254
244
  def clear
255
245
  @order = []
256
- super
246
+ @hash.clear
257
247
  end
258
248
 
259
249
  def delete( key )
260
- @order.delete key
261
- super
250
+ @order.delete( key )
251
+ @hash.delete( key )
262
252
  end
263
253
 
264
254
  def each_key
@@ -267,14 +257,12 @@ class Dictionary < Hash
267
257
  end
268
258
 
269
259
  def each_value
270
- order.each { |k| yield( self[k] ) }
260
+ order.each { |k| yield( @hash[k] ) }
271
261
  self
272
262
  end
273
263
 
274
- #alias_method :unordered_each, :each
275
-
276
264
  def each
277
- order.each { |k| yield( k,self[k] ) }
265
+ order.each { |k| yield( k,@hash[k] ) }
278
266
  self
279
267
  end
280
268
  alias each_pair each
@@ -286,7 +274,7 @@ class Dictionary < Hash
286
274
 
287
275
  def values
288
276
  ary = []
289
- order.each { |k| ary.push self[k] }
277
+ order.each { |k| ary.push @hash[k] }
290
278
  ary
291
279
  end
292
280
 
@@ -296,7 +284,7 @@ class Dictionary < Hash
296
284
 
297
285
  def invert
298
286
  hsh2 = self.class.new
299
- order.each { |k| hsh2[self[k]] = k }
287
+ order.each { |k| hsh2[@hash[k]] = k }
300
288
  hsh2
301
289
  end
302
290
 
@@ -310,8 +298,8 @@ class Dictionary < Hash
310
298
  end
311
299
 
312
300
  def replace( hsh2 )
313
- @order = hsh2.keys
314
- super hsh2
301
+ @order = hsh2.order
302
+ @hash = hsh2.hash
315
303
  end
316
304
 
317
305
  def shift
@@ -320,9 +308,9 @@ class Dictionary < Hash
320
308
  end
321
309
 
322
310
  def unshift( k,v )
323
- unless self.include? k
324
- @order.unshift k
325
- orig_store(k,v)
311
+ unless @hash.include?( k )
312
+ @order.unshift( k )
313
+ @hash.store( k,v )
326
314
  true
327
315
  else
328
316
  false
@@ -334,9 +322,9 @@ class Dictionary < Hash
334
322
  end
335
323
 
336
324
  def push( k,v )
337
- unless self.include? k
338
- @order.push k
339
- orig_store(k,v)
325
+ unless @hash.include?( k )
326
+ @order.push( k )
327
+ @hash.store( k,v )
340
328
  true
341
329
  else
342
330
  false
@@ -386,16 +374,22 @@ class Dictionary < Hash
386
374
  end
387
375
 
388
376
  def first
389
- self[order.first]
377
+ @hash[order.first]
390
378
  end
391
379
 
392
380
  def last
393
- self[order.last]
381
+ @hash[order.last]
394
382
  end
395
383
 
384
+ def length
385
+ @order.length
386
+ end
387
+ alias :size :length
388
+
396
389
  end
397
390
 
398
391
 
392
+
399
393
  # _____ _
400
394
  # |_ _|__ ___| |_
401
395
  # | |/ _ \/ __| __|
@@ -33,12 +33,12 @@
33
33
  # License:: Ruby License
34
34
 
35
35
  require 'facets/core/kernel/bool.rb'
36
- require 'facets/more/openhash.rb'
36
+ require 'facets/more/openobject.rb'
37
37
  #require 'facets/more/nullclass'
38
38
 
39
39
  # = OpenCascade
40
40
  #
41
- # OpenCascade is subclass of OpenHash. It differs in a few
41
+ # OpenCascade is subclass of OpenObject. It differs in a few
42
42
  # significant ways.
43
43
  #
44
44
  # The main reason this class is labeled "cascade", every internal
@@ -65,7 +65,7 @@ require 'facets/more/openhash.rb'
65
65
  # So be sure to take that into account.
66
66
  #++
67
67
 
68
- class OpenCascade < OpenHash
68
+ class OpenCascade < OpenObject
69
69
 
70
70
  def method_missing( sym, arg=nil )
71
71
  type = sym.to_s[-1,1]
@@ -1,13 +1,200 @@
1
- # TO BE DEPRECTATED!!!
1
+ # = openobject.rb
2
+ #
3
+ # == Copyright (c) 2005,2006 Thomas Sawyer
4
+ #
5
+ # Ruby License
6
+ #
7
+ # This module is free software. You may use, modify, and/or redistribute this
8
+ # software under the same terms as Ruby.
9
+ #
10
+ # This program is distributed in the hope that it will be useful, but WITHOUT
11
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
+ # FOR A PARTICULAR PURPOSE.
13
+ #
14
+ # == Authors and Contributors
15
+ #
16
+ # * Thomas Sawyer
17
+ # * George Moschovitis
2
18
 
3
- require 'facets/more/openhash'
19
+ # Author:: Thomas Sawyer
20
+ # Copyright:: Copyright (c) 2005 Thomas Sawyer
21
+ # License:: Ruby License
4
22
 
5
- OpenObject = OpenHash
23
+ require 'facets/core/hash/to_h'
24
+ require 'facets/core/hash/to_proc'
25
+ require 'facets/core/kernel/object_class'
26
+ require 'facets/core/kernel/object_hexid'
27
+
28
+ # = OpenObject
29
+ #
30
+ # OpenObject is similar to OpenStruct, but differs in a couple ways.
31
+ #
32
+ # OpenObject is a subclass of Hash and can do just about everything
33
+ # a Hash can do, except that most public methods have been made
34
+ # protected and thus only available internally or via #send.
35
+ # A small number, like #each are still exposed publically though
36
+ # b/c of their importance.
37
+ #
38
+ # OpenObject will also clobber any method for which a slot is defined.
39
+ # Even generally very important methods can be clobbered, like
40
+ # instance_eval. So be careful. OpenObject should be used in highly
41
+ # controlled scenarios. If you want to pass one off to an "unknown"
42
+ # rountine, it is best to convert it to a Hash first and convert it
43
+ # back to an OpenObject when finished. To facilitate this the method
44
+ # #as_hash! is provided.
45
+ #
46
+ # o = OpenObject.new(:a=>1,:b=>2)
47
+ # o.as_hash!{ |h| h.update(:a=>6) }
48
+ # o #=> #<OpenObject {:a=>6,:b=>2}>
49
+ #
50
+ # Finally, unlike a regular Hash, all OpenObject's keys are symbols and
51
+ # all keys are converted to such using #to_sym on the fly.
52
+
53
+ class OpenObject < Hash
54
+
55
+ PUBLIC_METHODS = /(^__|^instance_|^object_|^\W|^as$|^send$|^class$|\?$)/
56
+
57
+ protected *public_instance_methods.select{ |m| m !~ PUBLIC_METHODS }
58
+
59
+ def self.[](hash=nil)
60
+ new(hash)
61
+ end
62
+
63
+ # Inititalizer for OpenObject is slightly differnt than that of Hash.
64
+ # It does not take a default parameter, but an initial priming Hash
65
+ # as with OpenStruct. The initializer can still take a default block
66
+ # however. To set the degault value use ++#default!(value)++.
67
+ #
68
+ # OpenObject(:a=>1).default!(0)
69
+
70
+ def initialize( hash=nil, &yld )
71
+ super( &yld )
72
+ hash.each { |k,v| define_slot(k,v) } if hash
73
+ end
74
+
75
+ def initialize_copy( orig )
76
+ orig.each { |k,v| define_slot(k,v) }
77
+ end
78
+
79
+ # Object inspection. (Careful, this can be clobbered!)
80
+
81
+ def inspect
82
+ "#<#{object_class}:#{object_hexid} #{super}>"
83
+ end
84
+
85
+ # Conversion methods. (Careful, these can be clobbered!)
86
+
87
+ def to_a() super end
88
+
89
+ def to_h() {}.update(self) end
90
+ def to_hash() {}.update(self) end
91
+
92
+ def to_proc() super end
93
+
94
+ def to_openobject() self end
95
+
96
+ # Iterate over each key-value pair. (Careful, this can be clobbered!)
97
+
98
+ def each(&yld) super(&yld) end
99
+
100
+ # Merge one OpenObject with another creating a new OpenObject.
101
+
102
+ def merge( other )
103
+ d = dup
104
+ d.send(:update, other)
105
+ d
106
+ end
107
+
108
+ # Update this OpenObject with another.
109
+
110
+ def update( other )
111
+ begin
112
+ other.each { |k,v| define_slot(k,v) }
113
+ rescue
114
+ other = other.to_h
115
+ retry
116
+ end
117
+ end
118
+
119
+ #
120
+
121
+ def delete(key)
122
+ super(key.to_sym)
123
+ end
124
+
125
+ # Set the default value.
126
+
127
+ def default!(default)
128
+ self.default = default
129
+ end
130
+
131
+ # Preform inplace action on OpenObject as if it were a regular Hash.
132
+ #--
133
+ # TODO Not so sure about #as_hash!. For starters if it doesn't return a hash it will fail.
134
+ # TODO Replace by using #as(Hash). Perhaps as_hash and as_object shortcuts? Why?
135
+ #++
136
+
137
+ def as_hash!(&yld)
138
+ replace(yld.call(to_hash))
139
+ end
140
+
141
+ # Check equality. (Should equal be true for Hash too?)
142
+
143
+ def ==( other )
144
+ return false unless OpenObject === other
145
+ super(other) #(other.send(:table))
146
+ end
147
+
148
+ def []=(k,v)
149
+ protect_slot(k)
150
+ super(k.to_sym,v)
151
+ end
152
+
153
+ def [](k)
154
+ super(k.to_sym)
155
+ end
156
+
157
+ protected
158
+
159
+ def store(k,v)
160
+ super(k.to_sym,v)
161
+ define_slot(k)
162
+ end
163
+
164
+ def fetch(k,*d,&b)
165
+ super(k.to_sym,*d,&b)
166
+ end
167
+
168
+ def define_slot( key, value=nil )
169
+ protect_slot( key )
170
+ self[key.to_sym] = value
171
+ end
172
+
173
+ def protect_slot( key )
174
+ (class << self; self; end).class_eval {
175
+ protected key rescue nil
176
+ }
177
+ end
178
+
179
+ def method_missing( sym, arg=nil, &blk)
180
+ type = sym.to_s[-1,1]
181
+ key = sym.to_s.sub(/[=?!]$/,'').to_sym
182
+ if type == '='
183
+ define_slot(key,arg)
184
+ elsif type == '!'
185
+ define_slot(key,arg)
186
+ self
187
+ else
188
+ self[key]
189
+ end
190
+ end
191
+
192
+ end
6
193
 
7
194
  # Core Extensions
8
195
 
9
196
  class NilClass
10
- # Nil converts to an empty OpenHash.
197
+ # Nil converts to an empty OpenObject.
11
198
 
12
199
  def to_openobject
13
200
  OpenObject.new
@@ -15,7 +202,7 @@ class NilClass
15
202
  end
16
203
 
17
204
  class Hash
18
- # Convert a Hash into an OpenHash.
205
+ # Convert a Hash into an OpenObject.
19
206
 
20
207
  def to_openobject
21
208
  OpenObject[self]
@@ -23,23 +210,145 @@ class Hash
23
210
  end
24
211
 
25
212
  class Proc
26
- # Translates a Proc into an OpenHash. By droping an OpenHash into
213
+ # Translates a Proc into an OpenObject. By droping an OpenObject into
27
214
  # the Proc, the resulting assignments incured as the procedure is
28
- # evaluated produce the OpenHash. This technique is simlar to that
215
+ # evaluated produce the OpenObject. This technique is simlar to that
29
216
  # of MethodProbe.
30
217
  #
31
218
  # p = lambda { |x|
32
219
  # x.word = "Hello"
33
220
  # }
34
- # o = p.to_openhash
221
+ # o = p.to_openobject
35
222
  # o.word #=> "Hello"
36
223
  #
37
224
  # NOTE The Proc must have an arity of one --no more and no less.
38
225
 
39
226
  def to_openobject
40
- raise ArgumentError, 'bad arity for converting Proc to openhash' if arity != 1
227
+ raise ArgumentError, 'bad arity for converting Proc to openobject' if arity != 1
41
228
  o = OpenObject.new
42
229
  self.call( o )
43
230
  o
44
231
  end
45
232
  end
233
+
234
+
235
+ # _____ _
236
+ # |_ _|__ ___| |_
237
+ # | |/ _ \/ __| __|
238
+ # | | __/\__ \ |_
239
+ # |_|\___||___/\__|
240
+ #
241
+
242
+ =begin testing
243
+
244
+ require 'test/unit'
245
+
246
+ class TestOpenObject1 < Test::Unit::TestCase
247
+
248
+ def test_1_01
249
+ o = OpenObject.new
250
+ assert( o.respond_to?(:key?) )
251
+ end
252
+
253
+ def test_1_02
254
+ assert_instance_of( OpenObject, OpenObject[{}] )
255
+ end
256
+
257
+ def test_1_03
258
+ f0 = OpenObject.new
259
+ f0[:a] = 1
260
+ #assert_equal( [1], f0.to_a )
261
+ assert_equal( {:a=>1}, f0.to_h )
262
+ end
263
+
264
+ def test_1_04
265
+ f0 = OpenObject[:a=>1]
266
+ f0[:b] = 2
267
+ assert_equal( {:a=>1,:b=>2}, f0.to_h )
268
+ end
269
+
270
+ def test_1_05
271
+ f0 = OpenObject[:class=>1]
272
+ assert_equal( 1, f0.class )
273
+ end
274
+ end
275
+
276
+ class TestOpenObject2 < Test::Unit::TestCase
277
+
278
+ def test_2_01
279
+ f0 = OpenObject[:f0=>"f0"]
280
+ h0 = { :h0=>"h0" }
281
+ assert_equal( OpenObject[:f0=>"f0", :h0=>"h0"], f0.send(:merge,h0) )
282
+ assert_equal( {:f0=>"f0", :h0=>"h0"}, h0.merge( f0 ) )
283
+ end
284
+
285
+ def test_2_02
286
+ f1 = OpenObject[:f1=>"f1"]
287
+ h1 = { :h1=>"h1" }
288
+ f1.send(:update,h1)
289
+ h1.update( f1 )
290
+ assert_equal( OpenObject[:f1=>"f1", :h1=>"h1"], f1 )
291
+ assert_equal( {:f1=>"f1", :h1=>"h1"}, h1 )
292
+ end
293
+
294
+ def test_2_03
295
+ o = OpenObject[:a=>1,:b=>{:x=>9}]
296
+ assert_equal( 9, o[:b][:x] )
297
+ assert_equal( 9, o.b[:x] )
298
+ end
299
+
300
+ def test_2_04
301
+ o = OpenObject["a"=>1,"b"=>{:x=>9}]
302
+ assert_equal( 1, o["a"] )
303
+ assert_equal( 1, o[:a] )
304
+ assert_equal( {:x=>9}, o["b"] )
305
+ assert_equal( {:x=>9}, o[:b] )
306
+ assert_equal( 9, o["b"][:x] )
307
+ assert_equal( nil, o[:b]["x"] )
308
+ end
309
+
310
+ end
311
+
312
+ class TestOpenObject3 < Test::Unit::TestCase
313
+ def test_3_01
314
+ fo = OpenObject.new
315
+ 9.times{ |i| fo.send( "n#{i}=", 1 ) }
316
+ 9.times{ |i|
317
+ assert_equal( 1, fo.send( "n#{i}" ) )
318
+ }
319
+ end
320
+ end
321
+
322
+ class TestOpenObject4 < Test::Unit::TestCase
323
+
324
+ def test_4_01
325
+ ho = {}
326
+ fo = OpenObject.new
327
+ 5.times{ |i| ho["n#{i}".to_sym]=1 }
328
+ 5.times{ |i| fo.send( "n#{i}=", 1 ) }
329
+ assert_equal(ho, fo.to_h)
330
+ end
331
+
332
+ end
333
+
334
+ class TestOpenObject5 < Test::Unit::TestCase
335
+
336
+ def test_5_01
337
+ p = lambda { |x|
338
+ x.word = "Hello"
339
+ }
340
+ o = p.to_openobjrct
341
+ assert_equal( "Hello", o.word )
342
+ end
343
+
344
+ def test_5_02
345
+ p = lambda { |x|
346
+ x.word = "Hello"
347
+ }
348
+ o = OpenObject[:a=>1,:b=>2]
349
+ assert_instance_of( Proc, o.to_proc )
350
+ end
351
+
352
+ end
353
+
354
+ =end