facets 1.8.0 → 1.8.8
Sign up to get free protection for your applications and to get access to all the features.
- data/PROJECT +4 -4
- data/Rakefile +19 -14
- data/VERSION +1 -1
- data/lib/facet/enumerable/cart.rb +1 -0
- data/lib/facet/enumerable/cartesian_product.rb +1 -0
- data/lib/facet/enumerable/self/cart.rb +1 -0
- data/lib/facet/enumerable/self/cartesian_product.rb +1 -0
- data/lib/facets.rb +2 -1
- data/lib/facets/core/dir/self/multiglob_sum.rb +2 -0
- data/lib/facets/core/enumerable/cart.rb +119 -0
- data/lib/facets/core/enumerable/cartesian_product.rb +8 -0
- data/lib/facets/core/enumerable/self/cart.rb +120 -0
- data/lib/facets/core/enumerable/self/cartesian_product.rb +8 -0
- data/lib/facets/core/string/singular.rb +7 -7
- data/lib/facets/more/ann.rb +6 -5
- data/lib/facets/more/ann_attr.rb +11 -14
- data/lib/facets/more/autovivify.rb +2 -2
- data/lib/facets/more/dictionary.rb +63 -69
- data/lib/facets/more/opencascade.rb +3 -3
- data/lib/facets/more/openobject.rb +318 -9
- data/lib/facets/more/times.rb +129 -43
- data/lib/facets/more/uploadutils.rb +248 -43
- data/work/hash_open.rb +23 -0
- data/work/openobject-temp.rb +45 -0
- metadata +13 -9
- data/lib/facet/enumerable/cross.rb +0 -1
- data/lib/facet/enumerable/self/cross.rb +0 -1
- data/lib/facet/openhash.rb +0 -1
- data/lib/facets/core/enumerable/cross.rb +0 -47
- data/lib/facets/core/enumerable/self/cross.rb +0 -85
- data/lib/facets/more/openhash.rb +0 -350
data/work/hash_open.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Hash
|
2
|
+
def open!
|
3
|
+
class << self
|
4
|
+
@_were_public = public_instance_methods - ['close!']
|
5
|
+
@_were_public.each { |m| private m }
|
6
|
+
def method_missing(s,*a)
|
7
|
+
if s.to_s[-1,1] == '='
|
8
|
+
self[s] = a.first
|
9
|
+
else
|
10
|
+
return self[s]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
def close!
|
16
|
+
class << self
|
17
|
+
@_were_public.each { |m| public m }
|
18
|
+
@_were_public = nil
|
19
|
+
remove_method(:method_missing)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# TO BE DEPRECTATED!!!
|
2
|
+
|
3
|
+
require 'facets/more/openhash'
|
4
|
+
|
5
|
+
OpenObject = OpenHash
|
6
|
+
|
7
|
+
# Core Extensions
|
8
|
+
|
9
|
+
class NilClass
|
10
|
+
# Nil converts to an empty OpenHash.
|
11
|
+
|
12
|
+
def to_openobject
|
13
|
+
OpenObject.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Hash
|
18
|
+
# Convert a Hash into an OpenHash.
|
19
|
+
|
20
|
+
def to_openobject
|
21
|
+
OpenObject[self]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Proc
|
26
|
+
# Translates a Proc into an OpenHash. By droping an OpenHash into
|
27
|
+
# the Proc, the resulting assignments incured as the procedure is
|
28
|
+
# evaluated produce the OpenHash. This technique is simlar to that
|
29
|
+
# of MethodProbe.
|
30
|
+
#
|
31
|
+
# p = lambda { |x|
|
32
|
+
# x.word = "Hello"
|
33
|
+
# }
|
34
|
+
# o = p.to_openhash
|
35
|
+
# o.word #=> "Hello"
|
36
|
+
#
|
37
|
+
# NOTE The Proc must have an arity of one --no more and no less.
|
38
|
+
|
39
|
+
def to_openobject
|
40
|
+
raise ArgumentError, 'bad arity for converting Proc to openhash' if arity != 1
|
41
|
+
o = OpenObject.new
|
42
|
+
self.call( o )
|
43
|
+
o
|
44
|
+
end
|
45
|
+
end
|
metadata
CHANGED
@@ -3,15 +3,15 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: facets
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.8.
|
7
|
-
date: 2007-01-
|
6
|
+
version: 1.8.8
|
7
|
+
date: 2007-01-31 00:00:00 -05:00
|
8
8
|
summary: If Godzilla were a Programmer's Library
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: transfire@gmail.com
|
12
12
|
homepage: http://facets.rubyforge.org
|
13
13
|
rubyforge_project: facets
|
14
|
-
description:
|
14
|
+
description: Facets is a large collection of core extension methods and module additions for the Ruby programming language. The core extensions are unique by virtue of thier atomicity. Methods are stored in their own files, allowing for highly granular control of requirements. The modules include a variety of useful classes, mixins and microframeworks, from the Functor to a full-blown SI Units system.
|
15
15
|
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
@@ -37,6 +37,8 @@ files:
|
|
37
37
|
- work/README
|
38
38
|
- work/TODO
|
39
39
|
- work/op_rshift.rb
|
40
|
+
- work/hash_open.rb
|
41
|
+
- work/openobject-temp.rb
|
40
42
|
- work/misc/calibre/ProjectInfo.nilcomparable
|
41
43
|
- work/misc/calibre/ProjectInfo.downloader
|
42
44
|
- work/misc/calibre/ProjectInfo.reference
|
@@ -295,7 +297,6 @@ files:
|
|
295
297
|
- lib/facet/association.rb
|
296
298
|
- lib/facet/filesystem.rb
|
297
299
|
- lib/facet/doublemetaphone.rb
|
298
|
-
- lib/facet/openhash.rb
|
299
300
|
- lib/facet/main_as_module.rb
|
300
301
|
- lib/facet/linkedlist.rb
|
301
302
|
- lib/facet/autovivify.rb
|
@@ -536,11 +537,11 @@ files:
|
|
536
537
|
- lib/facet/enumerable/probability.rb
|
537
538
|
- lib/facet/enumerable/elementwise.rb
|
538
539
|
- lib/facet/enumerable/one.rb
|
540
|
+
- lib/facet/enumerable/cart.rb
|
539
541
|
- lib/facet/enumerable/each_with_counter.rb
|
540
542
|
- lib/facet/enumerable/accumulate.rb
|
541
543
|
- lib/facet/enumerable/cascade.rb
|
542
544
|
- lib/facet/enumerable/compact_map.rb
|
543
|
-
- lib/facet/enumerable/cross.rb
|
544
545
|
- lib/facet/enumerable/to_h.rb
|
545
546
|
- lib/facet/enumerable/every.rb
|
546
547
|
- lib/facet/enumerable/ideal_entropy.rb
|
@@ -578,8 +579,10 @@ files:
|
|
578
579
|
- lib/facet/enumerable/ew.rb
|
579
580
|
- lib/facet/enumerable/permutation.rb
|
580
581
|
- lib/facet/enumerable/injecting.rb
|
582
|
+
- lib/facet/enumerable/cartesian_product.rb
|
583
|
+
- lib/facet/enumerable/self/cart.rb
|
581
584
|
- lib/facet/enumerable/self/combinations.rb
|
582
|
-
- lib/facet/enumerable/self/
|
585
|
+
- lib/facet/enumerable/self/cartesian_product.rb
|
583
586
|
- lib/facet/file/self/open_as_string.rb
|
584
587
|
- lib/facet/file/self/read_binary.rb
|
585
588
|
- lib/facet/file/self/create.rb
|
@@ -956,7 +959,6 @@ files:
|
|
956
959
|
- lib/facets/more/association.rb
|
957
960
|
- lib/facets/more/filesystem.rb
|
958
961
|
- lib/facets/more/doublemetaphone.rb
|
959
|
-
- lib/facets/more/openhash.rb
|
960
962
|
- lib/facets/more/main_as_module.rb
|
961
963
|
- lib/facets/more/linkedlist.rb
|
962
964
|
- lib/facets/more/autovivify.rb
|
@@ -1204,11 +1206,11 @@ files:
|
|
1204
1206
|
- lib/facets/core/enumerable/probability.rb
|
1205
1207
|
- lib/facets/core/enumerable/elementwise.rb
|
1206
1208
|
- lib/facets/core/enumerable/one.rb
|
1209
|
+
- lib/facets/core/enumerable/cart.rb
|
1207
1210
|
- lib/facets/core/enumerable/each_with_counter.rb
|
1208
1211
|
- lib/facets/core/enumerable/accumulate.rb
|
1209
1212
|
- lib/facets/core/enumerable/cascade.rb
|
1210
1213
|
- lib/facets/core/enumerable/compact_map.rb
|
1211
|
-
- lib/facets/core/enumerable/cross.rb
|
1212
1214
|
- lib/facets/core/enumerable/to_h.rb
|
1213
1215
|
- lib/facets/core/enumerable/every.rb
|
1214
1216
|
- lib/facets/core/enumerable/ideal_entropy.rb
|
@@ -1246,8 +1248,10 @@ files:
|
|
1246
1248
|
- lib/facets/core/enumerable/ew.rb
|
1247
1249
|
- lib/facets/core/enumerable/permutation.rb
|
1248
1250
|
- lib/facets/core/enumerable/injecting.rb
|
1251
|
+
- lib/facets/core/enumerable/cartesian_product.rb
|
1252
|
+
- lib/facets/core/enumerable/self/cart.rb
|
1249
1253
|
- lib/facets/core/enumerable/self/combinations.rb
|
1250
|
-
- lib/facets/core/enumerable/self/
|
1254
|
+
- lib/facets/core/enumerable/self/cartesian_product.rb
|
1251
1255
|
- lib/facets/core/file/self/open_as_string.rb
|
1252
1256
|
- lib/facets/core/file/self/read_binary.rb
|
1253
1257
|
- lib/facets/core/file/self/create.rb
|
@@ -1 +0,0 @@
|
|
1
|
-
require 'facets/core/enumerable/cross.rb'
|
@@ -1 +0,0 @@
|
|
1
|
-
require 'facets/core/enumerable/self/cross.rb'
|
data/lib/facet/openhash.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'facets/more/openhash.rb'
|
@@ -1,47 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Cross product adapted from code by Michael Neuman.
|
3
|
-
#++
|
4
|
-
require 'facet/enumerable/self/cross'
|
5
|
-
|
6
|
-
module Enumerable
|
7
|
-
|
8
|
-
# The instance level cross-product method.
|
9
|
-
#
|
10
|
-
# a = []
|
11
|
-
# [1,2].cross([4,5]){|elem| a << elem }
|
12
|
-
# a #=> [[1, 4],[1, 5],[2, 4],[2, 5]]
|
13
|
-
#
|
14
|
-
#--
|
15
|
-
# TODO Make a more efficient version just for Array (?)
|
16
|
-
#++
|
17
|
-
def cross(*enums, &block)
|
18
|
-
Enumerable.cross(self, *enums, &block)
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# _____ _
|
26
|
-
# |_ _|__ ___| |_
|
27
|
-
# | |/ _ \/ __| __|
|
28
|
-
# | | __/\__ \ |_
|
29
|
-
# |_|\___||___/\__|
|
30
|
-
#
|
31
|
-
=begin test
|
32
|
-
|
33
|
-
require 'test/unit'
|
34
|
-
|
35
|
-
class TCEnumerable < Test::Unit::TestCase
|
36
|
-
|
37
|
-
def test_cross
|
38
|
-
a = [1,2,3].cross([4,5,6])
|
39
|
-
assert_equal( [[1, 4],[1, 5],[1, 6],[2, 4],[2, 5],[2, 6],[3, 4],[3, 5],[3, 6]], a )
|
40
|
-
a = []
|
41
|
-
[1,2,3].cross([4,5,6]) {|elem| a << elem }
|
42
|
-
assert_equal( [[1, 4],[1, 5],[1, 6],[2, 4],[2, 5],[2, 6],[3, 4],[3, 5],[3, 6]], a )
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
=end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Cross product adapted from code by Michael Neuman.
|
3
|
-
#++
|
4
|
-
require 'generator'
|
5
|
-
|
6
|
-
module Enumerable
|
7
|
-
|
8
|
-
# Provides the cross-product of two or more Enumerables.
|
9
|
-
# This is the class-level method. The instance method
|
10
|
-
# calls on this.
|
11
|
-
#
|
12
|
-
# Enumerable.cross([1,2], [4], ["apple", "banana"])
|
13
|
-
# #=> [[1, 4, "apple"], [1, 4, "banana"], [2, 4, "apple"], [2, 4, "banana"]]
|
14
|
-
#
|
15
|
-
# Enumerable.cross([1,2], [3,4])
|
16
|
-
# #=> [[1, 3], [1, 4], [2, 3], [2, 4]]
|
17
|
-
#
|
18
|
-
#--
|
19
|
-
# TODO Make a more efficient version just for Array (?)
|
20
|
-
#++
|
21
|
-
def self.cross(*enums, &block)
|
22
|
-
|
23
|
-
raise if enums.empty?
|
24
|
-
gens = enums.map{|e| Generator.new(e)}
|
25
|
-
return [] if gens.any? {|g| g.end?}
|
26
|
-
|
27
|
-
sz = gens.size
|
28
|
-
res = []
|
29
|
-
tuple = Array.new(sz)
|
30
|
-
|
31
|
-
loop do
|
32
|
-
# fill tuple
|
33
|
-
(0 ... sz).each { |i|
|
34
|
-
tuple[i] = gens[i].current
|
35
|
-
}
|
36
|
-
if block.nil?
|
37
|
-
res << tuple.dup
|
38
|
-
else
|
39
|
-
block.call(tuple.dup)
|
40
|
-
end
|
41
|
-
|
42
|
-
# step forward
|
43
|
-
gens[-1].next
|
44
|
-
(sz-1).downto(0) do |i|
|
45
|
-
if gens[i].end?
|
46
|
-
if i > 0
|
47
|
-
gens[i].rewind
|
48
|
-
gens[i-1].next
|
49
|
-
else
|
50
|
-
return res
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end #loop
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
# _____ _
|
63
|
-
# |_ _|__ ___| |_
|
64
|
-
# | |/ _ \/ __| __|
|
65
|
-
# | | __/\__ \ |_
|
66
|
-
# |_|\___||___/\__|
|
67
|
-
#
|
68
|
-
=begin test
|
69
|
-
|
70
|
-
require 'test/unit'
|
71
|
-
|
72
|
-
class TCEnumerable < Test::Unit::TestCase
|
73
|
-
|
74
|
-
def test_cross
|
75
|
-
i = [[1,2], [3,4]]
|
76
|
-
o = [[1, 3], [1, 4], [2, 3], [2, 4]]
|
77
|
-
assert_equal( o, Enumerable.cross(*i) )
|
78
|
-
i = [[1,2], [4], ["apple", "banana"]]
|
79
|
-
o = [[1, 4, "apple"], [1, 4, "banana"], [2, 4, "apple"], [2, 4, "banana"]]
|
80
|
-
assert_equal( o, Enumerable.cross(*i) )
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
=end
|
data/lib/facets/more/openhash.rb
DELETED
@@ -1,350 +0,0 @@
|
|
1
|
-
# = openhash.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
|
18
|
-
|
19
|
-
# Author:: Thomas Sawyer
|
20
|
-
# Copyright:: Copyright (c) 2005 Thomas Sawyer
|
21
|
-
# License:: Ruby License
|
22
|
-
|
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
|
-
#require 'facets/core/hash/symbolize_keys'
|
28
|
-
#require 'facets/more/methodfilter'
|
29
|
-
|
30
|
-
# = OpenHash
|
31
|
-
#
|
32
|
-
# OpenHash is similar to OpenStruct, but differs in a couple ways.
|
33
|
-
#
|
34
|
-
# OpenHash is a subclass of Hash and can do just about everything
|
35
|
-
# a Hash can do, except that most public methods have been made
|
36
|
-
# protected and thus only available internally or via #send.
|
37
|
-
# A small number, like #each are still exposed publically though
|
38
|
-
# b/c of their importance.
|
39
|
-
#
|
40
|
-
# OpenHash will also clobber any method for which a slot is defined.
|
41
|
-
# Even generally very important methods can be clobbered, like
|
42
|
-
# instance_eval. So be careful. OpenHash should be used in highly
|
43
|
-
# controlled scenarios. If you want to pass one off to an "unknown"
|
44
|
-
# rountine, it is best to convert it to a Hash first and convert it
|
45
|
-
# back to an OpenHash when finished. To facilitate this the method
|
46
|
-
# #as_hash! is provided.
|
47
|
-
#
|
48
|
-
# o = OpenHash.new(:a=>1,:b=>2)
|
49
|
-
# o.as_hash!{ |h| h.update(:a=>6) }
|
50
|
-
# o #=> #<OpenHash {:a=>6,:b=>2}>
|
51
|
-
#
|
52
|
-
# Finally, unlike a regular Hash, all OpenHash's keys are symbols and
|
53
|
-
# all keys are converted to such using #to_sym on the fly.
|
54
|
-
|
55
|
-
class OpenHash < Hash
|
56
|
-
|
57
|
-
PUBLIC_METHODS = /(^__|^instance_|^object_|^\W|^as$|^send$|^class$|\?$)/
|
58
|
-
|
59
|
-
protected *public_instance_methods.select{ |m| m !~ PUBLIC_METHODS }
|
60
|
-
|
61
|
-
def self.[](hash=nil)
|
62
|
-
new(hash)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Inititalizer for OpenHash is slightly differnt than that of Hash.
|
66
|
-
# It does not take a default parameter, but an initial priming Hash
|
67
|
-
# as with OpenStruct. The initializer can still take a default block
|
68
|
-
# however. To set the degault value use ++#default!(value)++.
|
69
|
-
#
|
70
|
-
# OpenHash(:a=>1).default!(0)
|
71
|
-
|
72
|
-
def initialize( hash=nil, &yld )
|
73
|
-
super( &yld )
|
74
|
-
hash.each { |k,v| define_slot(k,v) } if hash
|
75
|
-
end
|
76
|
-
|
77
|
-
def initialize_copy( orig )
|
78
|
-
orig.each { |k,v| define_slot(k,v) }
|
79
|
-
end
|
80
|
-
|
81
|
-
# Object inspection. (Careful, this can be clobbered!)
|
82
|
-
|
83
|
-
def inspect
|
84
|
-
"#<#{object_class}:#{object_hexid} #{super}>"
|
85
|
-
end
|
86
|
-
|
87
|
-
# Conversion methods. (Careful, these can be clobbered!)
|
88
|
-
|
89
|
-
def to_a() super end
|
90
|
-
|
91
|
-
def to_h() {}.update(self) end
|
92
|
-
def to_hash() {}.update(self) end
|
93
|
-
|
94
|
-
def to_proc() super end
|
95
|
-
|
96
|
-
def to_openhash() self end
|
97
|
-
|
98
|
-
# Iterate over each key-value pair. (Careful, this can be clobbered!)
|
99
|
-
|
100
|
-
def each(&yld) super(&yld) end
|
101
|
-
|
102
|
-
# Merge one OpenHash with another creating a new OpenHash.
|
103
|
-
|
104
|
-
def merge( other )
|
105
|
-
d = dup
|
106
|
-
d.send(:update, other)
|
107
|
-
d
|
108
|
-
end
|
109
|
-
|
110
|
-
# Update this OpenHash with another.
|
111
|
-
|
112
|
-
def update( other )
|
113
|
-
begin
|
114
|
-
other.each { |k,v| define_slot(k,v) }
|
115
|
-
rescue
|
116
|
-
other = other.to_h
|
117
|
-
retry
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
# Set the default value.
|
122
|
-
|
123
|
-
def default!(default)
|
124
|
-
self.default = default
|
125
|
-
end
|
126
|
-
|
127
|
-
# Preform inplace action on OpenHash as if it were a regular Hash.
|
128
|
-
#--
|
129
|
-
# TODO Not so sure about #as_hash!. For starters if it doesn't return a hash it will fail.
|
130
|
-
# TODO Replace by using #as(Hash). Perhaps as_hash and as_object shortcuts? Why?
|
131
|
-
#++
|
132
|
-
|
133
|
-
def as_hash!(&yld)
|
134
|
-
replace(yld.call(to_hash))
|
135
|
-
end
|
136
|
-
|
137
|
-
# Check equality. (Should equal be true for Hash too?)
|
138
|
-
|
139
|
-
def ==( other )
|
140
|
-
return false unless OpenHash === other
|
141
|
-
super(other) #(other.send(:table))
|
142
|
-
end
|
143
|
-
|
144
|
-
def []=(k,v)
|
145
|
-
protect_slot(k)
|
146
|
-
super(k.to_sym,v)
|
147
|
-
end
|
148
|
-
|
149
|
-
def [](k)
|
150
|
-
super(k.to_sym)
|
151
|
-
end
|
152
|
-
|
153
|
-
protected
|
154
|
-
|
155
|
-
def store(k,v)
|
156
|
-
super(k.to_sym,v)
|
157
|
-
define_slot(k)
|
158
|
-
end
|
159
|
-
|
160
|
-
def fetch(k,*d,&b)
|
161
|
-
super(k.to_sym,*d,&b)
|
162
|
-
end
|
163
|
-
|
164
|
-
def define_slot( key, value=nil )
|
165
|
-
protect_slot( key )
|
166
|
-
self[key.to_sym] = value
|
167
|
-
end
|
168
|
-
|
169
|
-
def protect_slot( key )
|
170
|
-
(class << self; self; end).class_eval {
|
171
|
-
protected key rescue nil
|
172
|
-
}
|
173
|
-
end
|
174
|
-
|
175
|
-
def method_missing( sym, arg=nil, &blk)
|
176
|
-
type = sym.to_s[-1,1]
|
177
|
-
key = sym.to_s.sub(/[=?!]$/,'').to_sym
|
178
|
-
if type == '='
|
179
|
-
define_slot(key,arg)
|
180
|
-
elsif type == '!'
|
181
|
-
define_slot(key,arg)
|
182
|
-
self
|
183
|
-
else
|
184
|
-
self[key]
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
end
|
189
|
-
|
190
|
-
# Core Extensions
|
191
|
-
|
192
|
-
class NilClass
|
193
|
-
# Nil converts to an empty OpenHash.
|
194
|
-
|
195
|
-
def to_openhash
|
196
|
-
OpenHash.new
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
class Hash
|
201
|
-
# Convert a Hash into an OpenHash.
|
202
|
-
|
203
|
-
def to_openhash
|
204
|
-
OpenHash[self]
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
class Proc
|
209
|
-
# Translates a Proc into an OpenHash. By droping an OpenHash into
|
210
|
-
# the Proc, the resulting assignments incured as the procedure is
|
211
|
-
# evaluated produce the OpenHash. This technique is simlar to that
|
212
|
-
# of MethodProbe.
|
213
|
-
#
|
214
|
-
# p = lambda { |x|
|
215
|
-
# x.word = "Hello"
|
216
|
-
# }
|
217
|
-
# o = p.to_openhash
|
218
|
-
# o.word #=> "Hello"
|
219
|
-
#
|
220
|
-
# NOTE The Proc must have an arity of one --no more and no less.
|
221
|
-
|
222
|
-
def to_openhash
|
223
|
-
raise ArgumentError, 'bad arity for converting Proc to openhash' if arity != 1
|
224
|
-
o = OpenHash.new
|
225
|
-
self.call( o )
|
226
|
-
o
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
|
231
|
-
# _____ _
|
232
|
-
# |_ _|__ ___| |_
|
233
|
-
# | |/ _ \/ __| __|
|
234
|
-
# | | __/\__ \ |_
|
235
|
-
# |_|\___||___/\__|
|
236
|
-
#
|
237
|
-
|
238
|
-
=begin testing
|
239
|
-
|
240
|
-
require 'test/unit'
|
241
|
-
|
242
|
-
class TestOpenHash1 < Test::Unit::TestCase
|
243
|
-
|
244
|
-
def test_1_01
|
245
|
-
o = OpenHash.new
|
246
|
-
assert( o.respond_to?(:key?) )
|
247
|
-
end
|
248
|
-
|
249
|
-
def test_1_02
|
250
|
-
assert_instance_of( OpenHash, OpenHash[{}] )
|
251
|
-
end
|
252
|
-
|
253
|
-
def test_1_03
|
254
|
-
f0 = OpenHash.new
|
255
|
-
f0[:a] = 1
|
256
|
-
#assert_equal( [1], f0.to_a )
|
257
|
-
assert_equal( {:a=>1}, f0.to_h )
|
258
|
-
end
|
259
|
-
|
260
|
-
def test_1_04
|
261
|
-
f0 = OpenHash[:a=>1]
|
262
|
-
f0[:b] = 2
|
263
|
-
assert_equal( {:a=>1,:b=>2}, f0.to_h )
|
264
|
-
end
|
265
|
-
|
266
|
-
def test_1_05
|
267
|
-
f0 = OpenHash[:class=>1]
|
268
|
-
assert_equal( 1, f0.class )
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
class TestOpenHash2 < Test::Unit::TestCase
|
273
|
-
|
274
|
-
def test_2_01
|
275
|
-
f0 = OpenHash[:f0=>"f0"]
|
276
|
-
h0 = { :h0=>"h0" }
|
277
|
-
assert_equal( OpenHash[:f0=>"f0", :h0=>"h0"], f0.send(:merge,h0) )
|
278
|
-
assert_equal( {:f0=>"f0", :h0=>"h0"}, h0.merge( f0 ) )
|
279
|
-
end
|
280
|
-
|
281
|
-
def test_2_02
|
282
|
-
f1 = OpenHash[:f1=>"f1"]
|
283
|
-
h1 = { :h1=>"h1" }
|
284
|
-
f1.send(:update,h1)
|
285
|
-
h1.update( f1 )
|
286
|
-
assert_equal( OpenHash[:f1=>"f1", :h1=>"h1"], f1 )
|
287
|
-
assert_equal( {:f1=>"f1", :h1=>"h1"}, h1 )
|
288
|
-
end
|
289
|
-
|
290
|
-
def test_2_03
|
291
|
-
o = OpenHash[:a=>1,:b=>{:x=>9}]
|
292
|
-
assert_equal( 9, o[:b][:x] )
|
293
|
-
assert_equal( 9, o.b[:x] )
|
294
|
-
end
|
295
|
-
|
296
|
-
def test_2_04
|
297
|
-
o = OpenHash["a"=>1,"b"=>{:x=>9}]
|
298
|
-
assert_equal( 1, o["a"] )
|
299
|
-
assert_equal( 1, o[:a] )
|
300
|
-
assert_equal( {:x=>9}, o["b"] )
|
301
|
-
assert_equal( {:x=>9}, o[:b] )
|
302
|
-
assert_equal( 9, o["b"][:x] )
|
303
|
-
assert_equal( nil, o[:b]["x"] )
|
304
|
-
end
|
305
|
-
|
306
|
-
end
|
307
|
-
|
308
|
-
class TestOpenHash3 < Test::Unit::TestCase
|
309
|
-
def test_3_01
|
310
|
-
fo = OpenHash.new
|
311
|
-
9.times{ |i| fo.send( "n#{i}=", 1 ) }
|
312
|
-
9.times{ |i|
|
313
|
-
assert_equal( 1, fo.send( "n#{i}" ) )
|
314
|
-
}
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
class TestOpenHash4 < Test::Unit::TestCase
|
319
|
-
|
320
|
-
def test_4_01
|
321
|
-
ho = {}
|
322
|
-
fo = OpenHash.new
|
323
|
-
5.times{ |i| ho["n#{i}".to_sym]=1 }
|
324
|
-
5.times{ |i| fo.send( "n#{i}=", 1 ) }
|
325
|
-
assert_equal(ho, fo.to_h)
|
326
|
-
end
|
327
|
-
|
328
|
-
end
|
329
|
-
|
330
|
-
class TestOpenHash5 < Test::Unit::TestCase
|
331
|
-
|
332
|
-
def test_5_01
|
333
|
-
p = lambda { |x|
|
334
|
-
x.word = "Hello"
|
335
|
-
}
|
336
|
-
o = p.to_openhash
|
337
|
-
assert_equal( "Hello", o.word )
|
338
|
-
end
|
339
|
-
|
340
|
-
def test_5_02
|
341
|
-
p = lambda { |x|
|
342
|
-
x.word = "Hello"
|
343
|
-
}
|
344
|
-
o = OpenHash[:a=>1,:b=>2]
|
345
|
-
assert_instance_of( Proc, o.to_proc )
|
346
|
-
end
|
347
|
-
|
348
|
-
end
|
349
|
-
|
350
|
-
=end
|