eymiha_util 0.1.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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