eymiha_util 0.1.6 → 1.0.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.
Files changed (106) hide show
  1. data/gem_package.rb +3 -3
  2. data/html/classes/Eymiha.html +144 -0
  3. data/html/classes/{BaseEnvelope.html → Eymiha/BaseEnvelope.html} +21 -21
  4. data/html/classes/Eymiha/BaseEnvelope.src/M000010.html +18 -0
  5. data/html/classes/Eymiha/BaseEnvelope.src/M000011.html +20 -0
  6. data/html/classes/Eymiha/BaseEnvelope.src/M000012.html +18 -0
  7. data/html/classes/{Enum.html → Eymiha/Enum.html} +5 -27
  8. data/html/classes/{Envelope.html → Eymiha/Envelope.html} +52 -52
  9. data/html/classes/Eymiha/Envelope.src/M000025.html +19 -0
  10. data/html/classes/Eymiha/Envelope.src/M000026.html +19 -0
  11. data/html/classes/Eymiha/Envelope.src/M000027.html +35 -0
  12. data/html/classes/Eymiha/Envelope.src/M000028.html +19 -0
  13. data/html/classes/Eymiha/Envelope.src/M000029.html +19 -0
  14. data/html/classes/Eymiha/Envelope.src/M000030.html +26 -0
  15. data/html/classes/Eymiha/Envelope.src/M000032.html +18 -0
  16. data/html/classes/{EnvelopeException.html → Eymiha/EnvelopeException.html} +5 -5
  17. data/html/classes/{ForwardReference.html → Eymiha/ForwardReference.html} +16 -16
  18. data/html/classes/Eymiha/ForwardReference.src/M000033.html +21 -0
  19. data/html/classes/Eymiha/ForwardReference.src/M000034.html +18 -0
  20. data/html/classes/{ForwardReferencer.html → Eymiha/ForwardReferencer.html} +12 -5
  21. data/html/classes/{ForwardReferencing.html → Eymiha/ForwardReferencing.html} +51 -51
  22. data/html/classes/Eymiha/ForwardReferencing.src/M000001.html +20 -0
  23. data/html/classes/Eymiha/ForwardReferencing.src/M000002.html +20 -0
  24. data/html/classes/Eymiha/ForwardReferencing.src/M000003.html +20 -0
  25. data/html/classes/Eymiha/ForwardReferencing.src/M000004.html +32 -0
  26. data/html/classes/Eymiha/ForwardReferencing.src/M000005.html +18 -0
  27. data/html/classes/Eymiha/ForwardReferencing.src/M000006.html +25 -0
  28. data/html/classes/Eymiha/ForwardReferencing.src/M000007.html +18 -0
  29. data/html/classes/Eymiha/ForwardReferencing.src/M000008.html +18 -0
  30. data/html/classes/Eymiha/ForwardReferencing.src/M000009.html +18 -0
  31. data/html/classes/{Histogram.html → Eymiha/Histogram.html} +65 -65
  32. data/html/classes/Eymiha/Histogram.src/M000016.html +19 -0
  33. data/html/classes/Eymiha/Histogram.src/M000017.html +21 -0
  34. data/html/classes/Eymiha/Histogram.src/M000018.html +37 -0
  35. data/html/classes/Eymiha/Histogram.src/M000019.html +18 -0
  36. data/html/classes/{Histogram.src/M000015.html → Eymiha/Histogram.src/M000020.html} +5 -9
  37. data/html/classes/Eymiha/Histogram.src/M000021.html +20 -0
  38. data/html/classes/Eymiha/Histogram.src/M000022.html +20 -0
  39. data/html/classes/Eymiha/Histogram.src/M000023.html +20 -0
  40. data/html/classes/Eymiha/Histogram.src/M000024.html +24 -0
  41. data/html/classes/{HistogramException.html → Eymiha/HistogramException.html} +5 -5
  42. data/html/classes/{MethodicHash.html → Eymiha/MethodicHash.html} +22 -22
  43. data/html/classes/Eymiha/MethodicHash.src/M000013.html +22 -0
  44. data/html/classes/Eymiha/MethodicHash.src/M000014.html +23 -0
  45. data/html/classes/Eymiha/MethodicHash.src/M000015.html +23 -0
  46. data/html/created.rid +1 -1
  47. data/html/files/lib/{enum_rb.html → eymiha/util/enum_rb.html} +3 -3
  48. data/html/files/lib/{envelope_rb.html → eymiha/util/envelope_rb.html} +3 -3
  49. data/html/files/lib/{forward_referencing_rb.html → eymiha/util/forward_referencing_rb.html} +6 -8
  50. data/html/files/lib/{histogram_rb.html → eymiha/util/histogram_rb.html} +3 -3
  51. data/html/files/lib/eymiha/util/methodic_hash_rb.html +101 -0
  52. data/html/files/lib/eymiha/util_rb.html +112 -0
  53. data/html/fr_class_index.html +11 -10
  54. data/html/fr_file_index.html +6 -5
  55. data/html/fr_method_index.html +34 -34
  56. data/html/index.html +1 -1
  57. data/lib/eymiha/util.rb +5 -0
  58. data/lib/eymiha/util/enum.rb +59 -0
  59. data/lib/eymiha/util/envelope.rb +130 -0
  60. data/lib/eymiha/util/forward_referencing.rb +161 -0
  61. data/lib/eymiha/util/histogram.rb +112 -0
  62. data/lib/eymiha/util/methodic_hash.rb +70 -0
  63. data/test/tc_enum.rb +1 -1
  64. data/test/tc_envelope.rb +4 -2
  65. data/test/tc_forward_referencing.rb +3 -1
  66. data/test/tc_histogram.rb +3 -1
  67. data/test/tc_methodic_hash.rb +4 -1
  68. metadata +70 -62
  69. data/html/classes/BaseEnvelope.src/M000001.html +0 -18
  70. data/html/classes/BaseEnvelope.src/M000002.html +0 -20
  71. data/html/classes/BaseEnvelope.src/M000003.html +0 -18
  72. data/html/classes/Envelope.src/M000016.html +0 -19
  73. data/html/classes/Envelope.src/M000017.html +0 -19
  74. data/html/classes/Envelope.src/M000018.html +0 -35
  75. data/html/classes/Envelope.src/M000019.html +0 -19
  76. data/html/classes/Envelope.src/M000020.html +0 -19
  77. data/html/classes/Envelope.src/M000021.html +0 -26
  78. data/html/classes/Envelope.src/M000023.html +0 -18
  79. data/html/classes/ForwardReference.src/M000024.html +0 -21
  80. data/html/classes/ForwardReference.src/M000025.html +0 -18
  81. data/html/classes/ForwardReferencing.src/M000026.html +0 -20
  82. data/html/classes/ForwardReferencing.src/M000027.html +0 -20
  83. data/html/classes/ForwardReferencing.src/M000028.html +0 -20
  84. data/html/classes/ForwardReferencing.src/M000029.html +0 -32
  85. data/html/classes/ForwardReferencing.src/M000030.html +0 -18
  86. data/html/classes/ForwardReferencing.src/M000031.html +0 -25
  87. data/html/classes/ForwardReferencing.src/M000032.html +0 -18
  88. data/html/classes/ForwardReferencing.src/M000033.html +0 -18
  89. data/html/classes/ForwardReferencing.src/M000034.html +0 -18
  90. data/html/classes/Histogram.src/M000007.html +0 -19
  91. data/html/classes/Histogram.src/M000008.html +0 -21
  92. data/html/classes/Histogram.src/M000009.html +0 -37
  93. data/html/classes/Histogram.src/M000010.html +0 -18
  94. data/html/classes/Histogram.src/M000011.html +0 -20
  95. data/html/classes/Histogram.src/M000012.html +0 -20
  96. data/html/classes/Histogram.src/M000013.html +0 -20
  97. data/html/classes/Histogram.src/M000014.html +0 -20
  98. data/html/classes/MethodicHash.src/M000004.html +0 -22
  99. data/html/classes/MethodicHash.src/M000005.html +0 -23
  100. data/html/classes/MethodicHash.src/M000006.html +0 -23
  101. data/html/files/lib/methodic_hash_rb.html +0 -140
  102. data/lib/enum.rb +0 -57
  103. data/lib/envelope.rb +0 -126
  104. data/lib/forward_referencing.rb +0 -157
  105. data/lib/histogram.rb +0 -109
  106. data/lib/methodic_hash.rb +0 -66
@@ -1,23 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html>
7
- <head>
8
- <title>delete (MethodicHash)</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
11
- </head>
12
- <body class="standalone-code">
13
- <pre><span class="ruby-comment cmt"># File lib/methodic_hash.rb, line 46</span>
14
- <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">delete</span>(<span class="ruby-identifier">key</span>,<span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
15
- <span class="ruby-identifier">values</span> = [<span class="ruby-identifier">key</span>.<span class="ruby-identifier">to_s</span>, <span class="ruby-identifier">key</span>.<span class="ruby-identifier">to_sym</span>].<span class="ruby-identifier">collect</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span><span class="ruby-operator">|</span> <span class="ruby-keyword kw">super</span>(<span class="ruby-identifier">k</span>){ <span class="ruby-keyword kw">nil</span> } }.<span class="ruby-identifier">compact</span>
16
- <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">values</span>.<span class="ruby-identifier">size</span>
17
- <span class="ruby-keyword kw">when</span> <span class="ruby-value">0</span> <span class="ruby-keyword kw">then</span> <span class="ruby-keyword kw">super</span>(<span class="ruby-identifier">key</span>,<span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
18
- <span class="ruby-keyword kw">when</span> <span class="ruby-value">1</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">values</span>[<span class="ruby-value">0</span>]
19
- <span class="ruby-keyword kw">when</span> <span class="ruby-value">2</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">values</span>
20
- <span class="ruby-keyword kw">end</span>
21
- <span class="ruby-keyword kw">end</span></pre>
22
- </body>
23
- </html>
@@ -1,23 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html>
7
- <head>
8
- <title>method_missing (MethodicHash)</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
11
- </head>
12
- <body class="standalone-code">
13
- <pre><span class="ruby-comment cmt"># File lib/methodic_hash.rb, line 57</span>
14
- <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">method_missing</span>(<span class="ruby-identifier">method</span>,<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
15
- <span class="ruby-identifier">string</span> = <span class="ruby-identifier">method</span>.<span class="ruby-identifier">to_s</span>
16
- <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">string</span>[<span class="ruby-identifier">string</span>.<span class="ruby-identifier">length</span><span class="ruby-operator">-</span><span class="ruby-value">1</span>,<span class="ruby-value">1</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">'='</span>
17
- <span class="ruby-keyword kw">self</span>[<span class="ruby-identifier">string</span>[<span class="ruby-value">0</span>,<span class="ruby-identifier">string</span>.<span class="ruby-identifier">length</span><span class="ruby-operator">-</span><span class="ruby-value">1</span>].<span class="ruby-identifier">to_sym</span>] = <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>]
18
- <span class="ruby-keyword kw">else</span>
19
- <span class="ruby-keyword kw">self</span>[<span class="ruby-identifier">method</span>]
20
- <span class="ruby-keyword kw">end</span>
21
- <span class="ruby-keyword kw">end</span></pre>
22
- </body>
23
- </html>
@@ -1,140 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
- <head>
8
- <title>File: methodic_hash.rb</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
- <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12
- <script type="text/javascript">
13
- // <![CDATA[
14
-
15
- function popupCode( url ) {
16
- window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
- }
18
-
19
- function toggleCode( id ) {
20
- if ( document.getElementById )
21
- elem = document.getElementById( id );
22
- else if ( document.all )
23
- elem = eval( "document.all." + id );
24
- else
25
- return false;
26
-
27
- elemStyle = elem.style;
28
-
29
- if ( elemStyle.display != "block" ) {
30
- elemStyle.display = "block"
31
- } else {
32
- elemStyle.display = "none"
33
- }
34
-
35
- return true;
36
- }
37
-
38
- // Make codeblocks hidden by default
39
- document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
-
41
- // ]]>
42
- </script>
43
-
44
- </head>
45
- <body>
46
-
47
-
48
-
49
- <div id="fileHeader">
50
- <h1>methodic_hash.rb</h1>
51
- <table class="header-table">
52
- <tr class="top-aligned-row">
53
- <td><strong>Path:</strong></td>
54
- <td>lib/methodic_hash.rb
55
- </td>
56
- </tr>
57
- <tr class="top-aligned-row">
58
- <td><strong>Last Update:</strong></td>
59
- <td>Fri Jun 08 10:23:50 -0400 2007</td>
60
- </tr>
61
- </table>
62
- </div>
63
- <!-- banner header -->
64
-
65
- <div id="bodyContent">
66
-
67
-
68
-
69
- <div id="contextContent">
70
-
71
- <div id="description">
72
- <p>
73
- The <a href="../../classes/MethodicHash.html">MethodicHash</a> is some
74
- method_missing magic that uses method names as hash keys, so hash
75
- assignment and lookup appear to be attribute writing and reading. For
76
- instance, if
77
- </p>
78
- <pre>
79
- mh = MethodicHash.new
80
- mh['four'] = 'iv'
81
- mh[:seven] = 'vii'
82
- mh.eighteen = 'xviii'
83
- </pre>
84
- <p>
85
- then
86
- </p>
87
- <pre>
88
- mh['four'] ---&gt; 'iv'
89
- mh[:four] ---&gt; 'iv'
90
- mh.four ---&gt; 'iv'
91
- mh['seven'] ---&gt; 'vii'
92
- mh[:seven] ---&gt; 'vii'
93
- mh.seven ---&gt; 'vii'
94
- mh['eighteen'] ---&gt; 'xviii'
95
- mh[:eighteen] ---&gt; 'xviii'
96
- mh.eighteen ---&gt; 'xviii'
97
- </pre>
98
- <p>
99
- This allows access to simply declared facts to be embedded in Ruby code and
100
- leverages the possibility of hashing procs.
101
- </p>
102
- <p>
103
- Note that if the hash uses anything but strings or symbols as keys, the
104
- magic stands a good chance of failing, raising an error or acting in a
105
- bizarre manner. Note also that methods of the Hash cannot be used as
106
- &#8216;attribute&#8217; names.
107
- </p>
108
-
109
- </div>
110
-
111
-
112
- </div>
113
-
114
-
115
- </div>
116
-
117
-
118
- <!-- if includes -->
119
-
120
- <div id="section">
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
- <!-- if method_list -->
130
-
131
-
132
- </div>
133
-
134
-
135
- <div id="validator-badges">
136
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
137
- </div>
138
-
139
- </body>
140
- </html>
data/lib/enum.rb DELETED
@@ -1,57 +0,0 @@
1
- # Enums are used to build a sets of enumerated values.
2
- #
3
- # Numeric and bitwise enums are provided, and include provisions for assigned
4
- # values and the allowance of gaps.
5
- #
6
- # enum %w(N1 N2 +2 N3 N4 =7 N5 N6 3 N7)
7
- #
8
- # gives N1 = 0, N2 = 1, N3 = 4, N4 = 5, N5 = 7, N6 = 8 and N7 = 3
9
- #
10
- # enum_bitwise %w(B1 B2 +2 B3 B4 =7 B5 B6 3 B7)
11
- #
12
- # gives B1 = 1, B2 = 2, B3 = 16, B4 = 32, B5 = 128, B6 = 256 and B7 = 8
13
- class Enum
14
-
15
- private
16
-
17
- def self.build(arguments = {})
18
- code = <<EOF
19
- def #{arguments[:method]}(*args)
20
- offset = 0
21
- bias = 0
22
- args.flatten.each_with_index do |const,i|
23
- case const
24
- when /^\\+(\\d+)$/
25
- offset = $1.to_i
26
- bias += 1
27
- when /^(\\=)?(\\d+)$/
28
- offset = $2.to_i - i
29
- else
30
- class_eval %(#{arguments[:enum_type]})
31
- end
32
- end
33
- end
34
- EOF
35
- arguments[:object].class_eval(code)
36
- end
37
-
38
- numeric = '#{const} = #{i+offset-bias}'
39
- bitwise = '#{const} = #{2**(i+offset-bias)}'
40
-
41
- Enum.build({ :object => Object,
42
- :method => "self.enum",
43
- :enum_type => numeric })
44
-
45
- Enum.build({ :object => Object,
46
- :method => "self.bitwise_enum",
47
- :enum_type => bitwise })
48
-
49
- Enum.build({ :object => Module,
50
- :method => "enum",
51
- :enum_type => numeric })
52
-
53
- Enum.build({ :object => Module,
54
- :method => "bitwise_enum",
55
- :enum_type => bitwise })
56
-
57
- end
data/lib/envelope.rb DELETED
@@ -1,126 +0,0 @@
1
- # Envelopes are useful when finding the boundaries of a set of instances.
2
- # They expand as new values are added, and keep track of how many items
3
- # have been added to construct them.
4
-
5
- # An EnvelopeException is generally raised when adding an object to an
6
- # instance that it does not know how to interpret, or when requesting
7
- # bounderies before any values have been added.
8
- class EnvelopeException < Exception
9
- end
10
-
11
-
12
- # A BaseEnvelope provides a means to keep and provide a count of objects that
13
- # have been added to an envelope.
14
- class BaseEnvelope
15
-
16
- # Called when requesting envelope bounderies before any values have been
17
- # added.
18
- def raise_no_envelope
19
- raise EnvelopeException, "No values are enveloped"
20
- end
21
-
22
- # Called when the value cannot be compared with the the boundaries of the
23
- # instance.
24
- def raise_no_compare(value=nil)
25
- value = "'#{value}' " unless value == nil
26
- raise EnvelopeException,
27
- "The value #{value}cannot be compared with the envelope"
28
- end
29
-
30
- # count of added values reader.
31
- attr_reader :count
32
-
33
- # Returns a new instance with no values added.
34
- def initialize
35
- @count = 0
36
- end
37
-
38
- end
39
-
40
-
41
- # An Envelope is the minimum envelope that will completely contain a set of
42
- # values. Values may be added to an instance, and it can return the number
43
- # of values considered so far and its high and low boundaries.
44
- #
45
- # Envelopes can be used to generate ranges, however the result may be of
46
- # limited utility if the types of values being enveloped don't play nicely
47
- # with ranges.
48
- class Envelope < BaseEnvelope
49
-
50
- # Creates and returns an instance. If an argument is given, it is passed to
51
- # the set method to initialize the new instance.
52
- def initialize(value=nil)
53
- super()
54
- add(value) unless value == nil
55
- end
56
-
57
- # Returns a string representation of the instance.
58
- def to_s
59
- values = (count > 0)? "\n high #{high}\n low #{low}" : ""
60
- "Envelope: count #{count}#{values}"
61
- end
62
-
63
- # Adds a value to the instance. When
64
- # * x is an Envelope, it is coalesced into the instance.
65
- # * otherwise, the envelope is extened to contain the value.
66
- # * if the value cannot be compared to the boundaries, an EnvelopeException is raised.
67
- # The modified instance is returned.
68
- def add(value)
69
- if value.kind_of? Envelope
70
- count = value.count
71
- if (count > 0)
72
- add value.high
73
- add value.low
74
- @count += (count-2)
75
- end
76
- self
77
- else
78
- begin
79
- @high = value if (@count == 0 || value > @high)
80
- @low = value if (@count == 0 || value < @low)
81
- @count += 1
82
- self
83
- rescue
84
- raise_no_compare value
85
- end
86
- end
87
- end
88
-
89
- # Returns the high boundary of the instance.
90
- # * if there are no boundaries, an EnvelopeException is raised.
91
- def high
92
- raise_no_envelope if @count == 0
93
- @high
94
- end
95
-
96
- # Returns the low boundary of the instance.
97
- # * if there are no boundaries, an EnvelopeException is raised.
98
- def low
99
- raise_no_envelope if @count == 0
100
- @low
101
- end
102
-
103
- # Returns true if the instance completely contains the argument:
104
- # * value is an Envelope, its high and low are contained.
105
- # * otherwise, the value is contained.
106
- # * if the value cannot be compared to the boundaries, an EnvelopeException is raised.
107
- def contains?(value)
108
- if value.kind_of? Envelope
109
- (contains? value.high) && (contains? value.low)
110
- else
111
- begin
112
- (value >= low) && (value <= high)
113
- rescue
114
- raise_no_compare value
115
- end
116
- end
117
- end
118
-
119
- alias === contains?
120
-
121
- # Returns an inclusive range from the low to high boundaries
122
- def to_range
123
- low..high
124
- end
125
-
126
- end
@@ -1,157 +0,0 @@
1
- # Forward referencing is one of those painful problems in programming - if
2
- # you try to use something before it's defined, trouble ensues. Using the
3
- # ForwardReferencing module and the ForwardReference class can let you
4
- # gracefully recover from problems caused by forward references in data and
5
- # processing.
6
-
7
- require 'eymiha'
8
-
9
- # The ForwardReferencing module can be mixed into a class to allow it to
10
- # capture and resolve ForwardReferences.
11
- module ForwardReferencing
12
-
13
- # An array containing the set of unresolved forward references.
14
- attr_reader :forward_references
15
-
16
- # To be called from the initializer of the includer, this sets up the forward
17
- # reference capture and resolution mechanisms.
18
- def start_forward_referencing
19
- forward_references_clear
20
- @had_forward_reference_resolution = false
21
- @forward_reference_resolver = nil
22
- end
23
-
24
- # To be called when a section of code that could contain a forward reference
25
- # is entered. The method returns a newly created ForwardReference with the
26
- # given dependency that can be jumped to during resolution.
27
- def create_forward_reference(dependency=nil,context=nil)
28
- forward_reference = ForwardReference.new(dependency,context)
29
- @forward_references << forward_reference
30
- forward_reference
31
- end
32
-
33
- # To be called when a section of code that could contain a forward reference
34
- # has successfully been reached. It is used to remove the ForwardReference
35
- # that was created at the start of the section, and asserts that a
36
- # resolution was made.
37
- def remove_forward_reference(forward_reference=nil)
38
- @forward_references.delete forward_reference if
39
- (forward_reference.kind_of? ForwardReference)
40
- @had_forward_reference_resolution = true
41
- end
42
-
43
- # To be called to try to resolve any unresolved ForwardReferences by jumping
44
- # to each in turn and retrying the code that caused it. This method repeats
45
- # until nothing more is resolved. At that point unresolved forward reference
46
- # may still exist, to be possibly resolved by another call to this method
47
- # downstream. Prior to continuing to a forward reference, the
48
- # establish_forward_reference context method is called with the context that
49
- # was provided at the time the forward reference was created to give the
50
- # receiver a chance to reset any transcient infromation.
51
- def resolve_forward_references
52
- forward_references = @forward_references
53
- forward_references_clear
54
- @had_forward_reference_resolution = false
55
- if forward_references.size > 0
56
- @forward_reference_resolver ||= callcc {|cont| cont} while
57
- (@forward_reference_resolver == nil)
58
- forward_reference = forward_references.shift
59
- if forward_reference != nil
60
- establish_forward_reference_context(forward_reference.context) if
61
- respond_to?(:establish_forward_reference_context,true)
62
- forward_reference.continuation.call
63
- end
64
- end
65
- @forward_reference_resolver = nil
66
- resolve_forward_references if @had_forward_reference_resolution
67
- end
68
-
69
- # To be called at the end of a section of code that could contain a forward
70
- # reference, it will continue during normal processing and jump back to the
71
- # resolve_forward_references method during resolution.
72
- def continue_forward_reference_resolution
73
- @forward_reference_resolver.call if @forward_reference_resolver
74
- end
75
-
76
- # Returns a hash of dependencies to arrays of the ForwardReferences that
77
- # have them as dependencies.
78
- def forward_reference_dependencies
79
- dependencies = {}
80
- @forward_references.each { |forward_reference|
81
- dependency = forward_reference.dependency || "nil"
82
- forward_references = dependencies[dependency]
83
- dependencies[dependency] = [] if forward_references == nil
84
- dependencies[dependency] << forward_reference
85
- }
86
- dependencies
87
- end
88
-
89
- # Returns a string indicating the current state of ForwardReferencing.
90
- def forward_references_to_s
91
- "#{self_name} #{forward_references_remaining} unresolved"
92
- end
93
-
94
- # Returns the number of unresolved forward references.
95
- def forward_references_remaining
96
- @forward_references.size
97
- end
98
-
99
- # Remove the remaining unresolved forward references.
100
- def forward_references_clear
101
- @forward_references = []
102
- end
103
-
104
- end
105
-
106
-
107
- # A ForwardReferencer is simply a class-wrapper for the ForwardReferencing
108
- # module. method have been shortened there is reduced potential for conflict
109
- # from inheritence than from inclusion or extension.
110
- class ForwardReferencer
111
-
112
- understands ForwardReferencing
113
-
114
- alias initialize start_forward_referencing
115
- alias create create_forward_reference
116
- alias remove remove_forward_reference
117
- alias resolve resolve_forward_references
118
- alias continue continue_forward_reference_resolution
119
- alias dependencies forward_reference_dependencies
120
- alias to_s forward_references_to_s
121
- alias remaining forward_references_remaining
122
- alias clear forward_references_clear
123
-
124
- end
125
-
126
-
127
- # A ForwardReference holds a continuation and a dependency, the where and
128
- # the why of forward referencing.
129
- class ForwardReference
130
-
131
- # Holds the place to jump back to for attempting to resolve a forward
132
- # reference.
133
- attr_reader :continuation
134
-
135
- # Holds an arbitrary object that indicates why the forward reference
136
- # occurred.
137
- attr_accessor :dependency
138
-
139
- # Holds an arbitrary object that holds context that can be re-established
140
- # to help resolve the forward reference.
141
- attr_accessor :context
142
-
143
- # Returns a new instance with a valid continuation, the given dependency
144
- # and contextual information.
145
- def initialize(dependency=nil,context=nil)
146
- @continuation = nil
147
- @continuation = callcc{|cont| cont} while (@continuation == nil)
148
- @dependency = dependency
149
- @context = context
150
- end
151
-
152
- # Returns a string indicating the current state of the ForwardReference.
153
- def to_s
154
- "#{self_name} dependency #{dependency} #{continuation}"
155
- end
156
-
157
- end