facets 1.8.0 → 1.8.8

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.
@@ -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