rubybreaker 0.0.5 → 0.0.6

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 (90) hide show
  1. data/ABOUT.md +20 -0
  2. data/NEWS +5 -0
  3. data/README.md +16 -352
  4. data/Rakefile +30 -16
  5. data/TOPICS.md +55 -0
  6. data/TUTORIAL.md +291 -0
  7. data/VERSION +1 -1
  8. data/bin/rubybreaker +32 -14
  9. data/lib/rubybreaker/runtime/monitor.rb +1 -1
  10. data/lib/rubybreaker/runtime.rb +41 -21
  11. data/lib/rubybreaker/task.rb +15 -9
  12. data/lib/rubybreaker/test/rspec.rb +3 -3
  13. data/lib/rubybreaker/test/testcase.rb +3 -3
  14. data/lib/rubybreaker.rb +31 -16
  15. data/test/integrated/{tc_both_broken_breakable.rb → tc_both_documented_and_undocumented.rb} +3 -4
  16. data/test/integrated/tc_class_methods.rb +1 -1
  17. data/test/integrated/tc_inherit_broken.rb +1 -1
  18. data/test/integrated/tc_method_missing.rb +1 -1
  19. data/test/integrated/tc_namespace.rb +1 -1
  20. data/test/integrated/tc_simple1.rb +1 -1
  21. data/test/testtask/tc_testtask.rb +2 -2
  22. data/test/ts_integrated.rb +1 -1
  23. data/test/ts_rspec.rb +1 -1
  24. data/webpage/about.html +50 -0
  25. data/webpage/footer.html +6 -1
  26. data/webpage/header.html +9 -3
  27. data/webpage/images/logo.png +0 -0
  28. data/webpage/images/title.png +0 -0
  29. data/webpage/index.html +31 -367
  30. data/webpage/rdoc/Object.html +3 -103
  31. data/webpage/rdoc/Rake/RubyBreakerTestTask.html +80 -18
  32. data/webpage/rdoc/Rake.html +3 -7
  33. data/webpage/rdoc/RubyBreaker/Breakable.html +4 -8
  34. data/webpage/rdoc/RubyBreaker/Broken.html +4 -8
  35. data/webpage/rdoc/RubyBreaker/Context.html +3 -7
  36. data/webpage/rdoc/RubyBreaker/Errors/InternalError.html +3 -7
  37. data/webpage/rdoc/RubyBreaker/Errors/InvalidSubtypeCheck.html +3 -7
  38. data/webpage/rdoc/RubyBreaker/Errors/InvalidTypeConstruction.html +3 -7
  39. data/webpage/rdoc/RubyBreaker/Errors/SubtypeFailure.html +3 -7
  40. data/webpage/rdoc/RubyBreaker/Errors/TypeError.html +3 -7
  41. data/webpage/rdoc/RubyBreaker/Errors/UserError.html +3 -7
  42. data/webpage/rdoc/RubyBreaker/Errors.html +3 -7
  43. data/webpage/rdoc/RubyBreaker/ObjectPosition.html +3 -7
  44. data/webpage/rdoc/RubyBreaker/Position.html +3 -7
  45. data/webpage/rdoc/RubyBreaker/RDocSupport.html +3 -7
  46. data/webpage/rdoc/RubyBreaker/RubyTypeUtils.html +3 -7
  47. data/webpage/rdoc/RubyBreaker/Runtime/Inspector.html +3 -7
  48. data/webpage/rdoc/RubyBreaker/Runtime/MethodInfo.html +3 -7
  49. data/webpage/rdoc/RubyBreaker/Runtime/Monitor.html +3 -7
  50. data/webpage/rdoc/RubyBreaker/Runtime/MonitorInstaller.html +10 -14
  51. data/webpage/rdoc/RubyBreaker/Runtime/MonitorSwitch.html +3 -7
  52. data/webpage/rdoc/RubyBreaker/Runtime/MonitorUtils.html +3 -7
  53. data/webpage/rdoc/RubyBreaker/Runtime/ObjectWrapper.html +3 -7
  54. data/webpage/rdoc/RubyBreaker/Runtime/Pluggable.html +3 -7
  55. data/webpage/rdoc/RubyBreaker/Runtime/TypeSigParser.html +3 -7
  56. data/webpage/rdoc/RubyBreaker/Runtime/TypeSigUnparser.html +3 -7
  57. data/webpage/rdoc/RubyBreaker/Runtime/TypeSystem.html +3 -7
  58. data/webpage/rdoc/RubyBreaker/Runtime.html +42 -39
  59. data/webpage/rdoc/RubyBreaker/TypeComparer.html +3 -7
  60. data/webpage/rdoc/RubyBreaker/TypeDefs/AnyType.html +3 -7
  61. data/webpage/rdoc/RubyBreaker/TypeDefs/BlockType.html +3 -7
  62. data/webpage/rdoc/RubyBreaker/TypeDefs/DuckType.html +3 -7
  63. data/webpage/rdoc/RubyBreaker/TypeDefs/FusionType.html +3 -7
  64. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodListType.html +3 -7
  65. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodType.html +3 -7
  66. data/webpage/rdoc/RubyBreaker/TypeDefs/NilType.html +3 -7
  67. data/webpage/rdoc/RubyBreaker/TypeDefs/NominalType.html +3 -7
  68. data/webpage/rdoc/RubyBreaker/TypeDefs/OptionalType.html +3 -7
  69. data/webpage/rdoc/RubyBreaker/TypeDefs/OrType.html +3 -7
  70. data/webpage/rdoc/RubyBreaker/TypeDefs/SelfType.html +3 -7
  71. data/webpage/rdoc/RubyBreaker/TypeDefs/Type.html +3 -7
  72. data/webpage/rdoc/RubyBreaker/TypeDefs/VarLengthType.html +3 -7
  73. data/webpage/rdoc/RubyBreaker/TypeDefs.html +3 -7
  74. data/webpage/rdoc/RubyBreaker/TypeUnparser.html +3 -7
  75. data/webpage/rdoc/RubyBreaker/Typing.html +3 -7
  76. data/webpage/rdoc/RubyBreaker/Util.html +3 -7
  77. data/webpage/rdoc/RubyBreaker.html +48 -15
  78. data/webpage/rdoc/Test/Unit.html +3 -7
  79. data/webpage/rdoc/Test.html +3 -7
  80. data/webpage/rdoc/created.rid +18 -17
  81. data/webpage/rdoc/index.html +3 -7
  82. data/webpage/rdoc/js/search_index.js +1 -1
  83. data/webpage/rdoc/table_of_contents.html +28 -36
  84. data/webpage/rubybreaker.css +8 -6
  85. data/webpage/topics.html +85 -0
  86. data/webpage/tutorial.html +331 -0
  87. metadata +14 -8
  88. data/lib/rubybreaker/doc.rb +0 -3
  89. data/webpage/rdoc/Kernel.html +0 -286
  90. data/webpage/rdoc/Test/Unit/TestCase.html +0 -309
@@ -16,7 +16,7 @@ class IntegratedClassMethodsTest < Test::Unit::TestCase
16
16
  end
17
17
 
18
18
  def setup()
19
- RubyBreaker.breakable(A, B)
19
+ RubyBreaker.break(A, B)
20
20
  end
21
21
 
22
22
  def test_class_methods
@@ -14,7 +14,7 @@ class IntegratedInheritBrokenTest < Test::Unit::TestCase
14
14
  end
15
15
 
16
16
  def setup()
17
- RubyBreaker.breakable(B)
17
+ RubyBreaker.break(B)
18
18
  end
19
19
 
20
20
  def test_both
@@ -12,7 +12,7 @@ class IntegratedMethodMissingTest < Test::Unit::TestCase
12
12
  end
13
13
 
14
14
  def setup()
15
- RubyBreaker.breakable(A)
15
+ RubyBreaker.break(A)
16
16
  end
17
17
 
18
18
  # TODO: This must be fixed once variable length argument type is supported
@@ -22,7 +22,7 @@ class IntegratedNamespaceTest < Test::Unit::TestCase
22
22
  end
23
23
 
24
24
  def setup()
25
- RubyBreaker.breakable(B)
25
+ RubyBreaker.break(B)
26
26
  end
27
27
 
28
28
  def test_namspace_b_foo
@@ -37,7 +37,7 @@ class IntegratedSimpleTest < Test::Unit::TestCase
37
37
  end
38
38
 
39
39
  def setup()
40
- RubyBreaker.breakable(A)
40
+ RubyBreaker.break(A)
41
41
  end
42
42
 
43
43
  def test_simple1_a_foo
@@ -8,14 +8,14 @@ end
8
8
 
9
9
  class RubyBreakerTestTaskTest < Test::Unit::TestCase
10
10
 
11
- def test_breakable()
11
+ def test_break()
12
12
  SampleClassA.new.foo(2)
13
13
  t = RubyBreaker::Runtime::Inspector.inspect_meth(SampleClassA, :foo)
14
14
  str = t.unparse()
15
15
  assert_equal("foo(fixnum[to_s]) -> string", str)
16
16
  end
17
17
 
18
- def test_broken()
18
+ def test_documented()
19
19
  t = RubyBreaker::Runtime::Inspector.inspect_meth(SampleClassB, :foo)
20
20
  str = t.unparse()
21
21
  assert_equal("foo(fixnum[to_s]) -> string", str)
@@ -4,5 +4,5 @@ require_relative "integrated/tc_method_missing"
4
4
  require_relative "integrated/tc_simple1"
5
5
  require_relative "integrated/tc_inherit_broken"
6
6
  require_relative "integrated/tc_class_methods"
7
- require_relative "integrated/tc_both_broken_breakable"
7
+ require_relative "integrated/tc_both_documented_and_undocumented"
8
8
  require_relative "integrated/tc_namespace"
data/test/ts_rspec.rb CHANGED
@@ -12,7 +12,7 @@ end
12
12
  describe "RSpec Test" do
13
13
 
14
14
  before do
15
- RubyBreaker.breakable(RSpecTestA)
15
+ RubyBreaker.break(RSpecTestA)
16
16
  end
17
17
 
18
18
  describe RSpecTestA do
@@ -0,0 +1,50 @@
1
+ <html>
2
+ <head>
3
+ <title>RubyBreaker</title>
4
+ <LINK REL=StyleSheet HREF="rubybreaker.css" TYPE="text/css">
5
+ <script type="text/javascript" src="generated_toc.js"> </script>
6
+ </head>
7
+ <body onLoad="createTOC()">
8
+ <center>
9
+ <div id="content">
10
+ <div id="logo">
11
+ <img src="images/title.png" border="0">
12
+ </div>
13
+ <center>
14
+ <a href="index.html">Introduction</a> |
15
+ <a href="tutorial.html">Tutorial</a> |
16
+ <a href="topics.html">Advanced Topics</a> |
17
+ <a href="about.html">About</a>
18
+ </center>
19
+ <hr />
20
+ <!--<div id="generated-toc"></div>-->
21
+ <h1>About</h1>
22
+
23
+ <p>RubyBreaker has its root in Rubydust (which stands for Ruby Dynamic
24
+ Unraveling of Static Types), an academic research project designed and
25
+ implemented at University of Maryland. However, unlike Rubydust,
26
+ RubyBreaker aims to be a practical documentation tool for Ruby rather than a
27
+ full-scale type inference tool. Although it is certainly possible that
28
+ RubyBreaker evolves into something more solid in its type system, the
29
+ primary goal of this project is to help Ruby programmers practically as much
30
+ as possible.</p>
31
+
32
+ <h2>Acknowledgment</h2>
33
+
34
+ <p>The term, "Fusion Type," is first coined by Professor Michael W. Hicks at
35
+ University of Maryland and represents an object using a structural type with
36
+ respect to a nominal type.</p>
37
+
38
+ <h2>Copyright</h2>
39
+
40
+ <p>Copyright (c) 2012 Jong-hoon (David) An. All Rights Reserved.</p>
41
+ <hr />
42
+ <center style="font-size:smaller; padding:0px;">
43
+ Copyright (C) 2012 Jong-hoon (David) An. All Rights Reserved.<br />
44
+ Contact David An at rockalizer at gmail<br />
45
+ <a href="http://rockalizer.com">rockalizer.com</a>
46
+ </center>
47
+ </div>
48
+ </center>
49
+ </body>
50
+ </html>
data/webpage/footer.html CHANGED
@@ -1,4 +1,9 @@
1
-
1
+ <hr />
2
+ <center style="font-size:smaller; padding:0px;">
3
+ Copyright (C) 2012 Jong-hoon (David) An. All Rights Reserved.<br />
4
+ Contact David An at rockalizer at gmail<br />
5
+ <a href="http://rockalizer.com">rockalizer.com</a>
6
+ </center>
2
7
  </div>
3
8
  </center>
4
9
  </body>
data/webpage/header.html CHANGED
@@ -8,7 +8,13 @@
8
8
  <center>
9
9
  <div id="content">
10
10
  <div id="logo">
11
- <img src="images/logo.png" border="0">
11
+ <img src="images/title.png" border="0">
12
12
  </div>
13
- <hr />
14
- <div id="generated-toc"></div>
13
+ <center>
14
+ <a href="index.html">Introduction</a> |
15
+ <a href="tutorial.html">Tutorial</a> |
16
+ <a href="topics.html">Advanced Topics</a> |
17
+ <a href="about.html">About</a>
18
+ </center>
19
+ <hr />
20
+ <!--<div id="generated-toc"></div>-->
Binary file
Binary file
data/webpage/index.html CHANGED
@@ -8,43 +8,49 @@
8
8
  <center>
9
9
  <div id="content">
10
10
  <div id="logo">
11
- <img src="images/logo.png" border="0">
11
+ <img src="images/title.png" border="0">
12
12
  </div>
13
- <hr />
14
- <div id="generated-toc"></div>
15
- <hr />
16
-
13
+ <center>
14
+ <a href="index.html">Introduction</a> |
15
+ <a href="tutorial.html">Tutorial</a> |
16
+ <a href="topics.html">Advanced Topics</a> |
17
+ <a href="about.html">About</a>
18
+ </center>
19
+ <hr />
20
+ <!--<div id="generated-toc"></div>-->
17
21
  <h1>Introduction</h1>
18
22
 
19
23
  <p>RubyBreaker is a dynamic type documentation tool written in pure Ruby. It
20
24
  provides the framework for dynamically instrumenting a Ruby program to
21
- monitor objects during executions and document the observed type
25
+ monitor objects during the execution and document the observed type
22
26
  information. In other words, RubyBreaker "breaks" Ruby code out of its
23
- obscurity and wildness (as in "code breaking" or "horse
24
- breaking") by auto-documenting type information. The type documentation
25
- generated by RubyBreaker is also an executable Ruby code that can be used as
26
- an input to subsequent analyses.</p>
27
+ obscurity and wildness (as in "code breaking" or "horse breaking") by
28
+ auto-documenting type information. The type documentation generated by
29
+ RubyBreaker is also an executable Ruby code that can be used as an input to
30
+ subsequent analyses.</p>
27
31
 
28
32
  <p>The primary goal of RubyBreaker is to assign a type signature to every
29
33
  method in selected modules and classes. A type signature is written in the
30
34
  RubyBreaker Type Annotation Language which resembles the documentation style
31
- used in Ruby API Doc. Manual code change is <em>not</em> required if used in
32
- Rakefile and is kept minimal if otherwise. Overall, this tool should help
33
- Ruby programmers document their code more rigorously and effectively.</p>
35
+ used in Ruby Core Library Doc. No manual code change is required. Overall,
36
+ this tool should help Ruby programmers document their code more rigorously
37
+ and effectively.</p>
34
38
 
35
- <p>Current limitations are:</p>
39
+ <p>Currently, RubyBreaker <em>cannot</em></p>
36
40
 
37
41
  <ul>
38
- <li>Auto-documentation of block arguments (inherent)</li>
39
- <li>Parametric polymorphic types</li>
40
- <li>RDoc or YARD documentation support</li>
42
+ <li>Auto-document block arguments (inherent)</li>
43
+ <li>Perform early dynamic type checks</li>
44
+ <li>Support parametric polymorphic types</li>
45
+ <li>Support RDoc or YARD output format</li>
41
46
  </ul>
42
47
 
43
48
 
44
49
  <p>To contribute to the project, visit RubyBreaker's
45
50
  <a href="http://github.com/rockalizer/rubybreaker">GitHub page</a> and
46
- <a href="http://rubygems.org/gems/rubybreaker">RubyGems page</a>. RubyBreaker RDoc can
47
- be found in <a href="rdoc/index.html">here</a>.</p>
51
+ <a href="http://rubygems.org/gems/rubybreaker">RubyGems page</a>. The web version of
52
+ this document can be found
53
+ <a href="http://rockalizer.webfactional.com/projects/rubybreaker">here</a>.</p>
48
54
 
49
55
  <h2>Requirements</h2>
50
56
 
@@ -60,354 +66,12 @@ following URL: <a href="http://treetop.rubyforge.org/">TreeTop</a></p>
60
66
 
61
67
  <pre><code>$ gem install rubybreaker
62
68
  </code></pre>
63
-
64
- <hr />
65
-
66
- <h1>Tutorial</h1>
67
-
68
- <p>This tutorial will describe the basic usage of the tool, the RubyBreaker
69
- Type Annotation Language, and the RubyBreaker Type System.</p>
70
-
71
- <h2>Usage</h2>
72
-
73
- <p>RubyBreaker takes advantage of test cases that already come with the source
74
- program. It is recommended that RubyBreaker is run as a Rake task, which
75
- requires a minimum code change in the Rakefile and no code change in the
76
- source program. If not used as a Rake task, it requires a minimum code
77
- change in each test case or the source program but should not affect the
78
- development process much. Let's briefly see how RubyBreaker can be run
79
- directly as a command-line program to understand the general concept of the
80
- tool. We will explain how to use RubyBreaker in a Rakefile later.</p>
81
-
82
- <pre><code>$ rubybreaker -v prog.rb
83
- </code></pre>
84
-
85
- <p>This runs RubyBreaker in verbose mode on <code>prog.rb</code>. Note that RubyBreaker
86
- will actually run <code>prog.rb</code> (by simply <code>require</code>ing the program file).
87
- Somewhere in the program, there has to be a <em>program entry point</em> to
88
- indicate where the <em>monitoring</em> of objects starts. Let's assume <code>prog.rb</code>
89
- as the following:</p>
90
-
91
- <pre><code>require "rubybreaker" # required if using "ruby" instead
92
- class A
93
- def foo(x)
94
- x.to_s
95
- end
96
- end
97
- class B
98
- def bar(y,z)
99
- y.foo(z)
100
- end
101
- end
102
- RubyBreaker.run(A, B)
103
- A.new.foo(1)
104
- </code></pre>
105
-
106
- <p>This example will show how <code>A#foo</code> method is given a type by RubyBreaker.
107
- After running <code>rubybreaker -v prog.rb</code>, the following output will be
108
- generated and saved into <code>prog.rubybreaker.rb</code>.</p>
109
-
110
- <pre><code># This file is auto-generated by RubyBreaker
111
- require "rubybreaker"
112
- class A
113
- typesig("foo(fixnum[to_s]) -&gt; string")
114
- end
115
- </code></pre>
116
-
117
- <p>Here, the <code>typesig</code> method call registers <code>foo</code> as a method type that takes
118
- an object that has <code>Fixnum#to_s</code> method and returns a <code>String</code>. This
119
- method is made available by importing <code>rubybreaker</code>. Now, assume that an
120
- additional code, <code>B.new.bar(A.new,1)</code>, is added at the end of <code>prog.rb</code>. The
121
- subsequent run will generate the following result:</p>
122
-
123
- <pre><code># This file is auto-generated by RubyBreaker
124
- require "rubybreaker"
125
- class A
126
- typesig("foo(fixnum[to_s]) -&gt; string")
127
- end
128
- class B
129
- typesig("bar(a[foo], fixnum[to_s]) -&gt; string")
130
- end
131
- </code></pre>
132
-
133
- <p>Keep in mind that RubyBreaker is designed to gather type information based
134
- on the <em>actual</em> execution of the source program. This means the program
135
- should be equipped with test cases that have a reasonable program path
136
- coverage. Additionally, RubyBreaker assumes that test runs are correct and
137
- the program behaves correctly (for those test runs) as intended by the
138
- programmer. This assumption is not a strong requirement, but is necessary to
139
- obtain precise and accurate type information.</p>
140
-
141
- <h3>Using Ruby Unit Testing Framework</h3>
142
-
143
- <p>Instead of manually inserting the entry point indicator into the program,
144
- you can take advantage of Ruby's built-in testing framework. This is
145
- preferred to modifying the source program directly, especially for the long
146
- term program maintainability. But no worries! This method is as simple as
147
- the previous one.</p>
148
-
149
- <pre><code>require "test/unit"
150
- require "rubybreaker" # This should come after test/unit.
151
- class TestClassA &lt; Test::Unit::TestCase
152
- def setup()
153
- RubyBreaker.breakable(Class1, Class2, ...)
154
- ...
155
- end
156
- # ...tests!...
157
- end
158
- </code></pre>
159
-
160
- <p>That's it! The only requirements are to indicate to RubyBreaker which modules
161
- and classes to "break" and to place <code>require rubybreaker</code> <em>after</em>
162
- <code>require test/unit</code>.</p>
163
-
164
- <h3>Using RSpec</h3>
165
-
166
- <p>The requirement is same for RSpec but use <code>before</code> instead of <code>setup</code> to
167
- specify which modules and classes to "break".</p>
168
-
169
- <pre><code>require "rspec"
170
- require "rubybreaker"
171
-
172
- describe "TestClassA Test"
173
- before { RubyBreaker.breakable(Class1, Class2, ...) }
174
- ...
175
- # ...tests!...
176
- end
177
- </code></pre>
178
-
179
- <h3>Using Rakefile</h3>
180
-
181
- <p>By running RubyBreaker along with the Rakefile, you can avoid modifying the
182
- source program at all. (You no longer need to import <code>rubybreaker</code> in the
183
- test cases neither.) Therefore, this is the recommended way to use
184
- RubyBreaker. The following code snippet describes how it can be done:</p>
185
-
186
- <pre><code>require "rubybreaker/task"
187
- ...
188
- desc "Run RubyBreaker"
189
- Rake::RubyBreakerTestTask.new(:"rubybreaker") do |t|
190
- t.libs &lt;&lt; "lib"
191
- t.test_files = ["test/foo/tc_foo1.rb"]
192
- # ...Other test task options..
193
- t.rubybreaker_opts &lt;&lt; "-v" # run in verbose mode
194
- t.breakable = ["Class1", "Class2", ...] # specify what to monitor
195
- end
196
- </code></pre>
197
-
198
- <p>Note that <code>RubyBrakerTestTask</code> can simply replace your <code>TestTask</code> block in
199
- Rakefile. In fact, the former is a subclass of the latter and includes all
200
- features supported by the latter. The only additional options are
201
- <code>rubybreaker_opts</code> which is RubyBreaker's command-line options and
202
- <code>breakable</code> which specifies which modules and classes to monitor. Since
203
- <code>Class1</code> and <code>Class2</code> are not <em>recognized</em> by this Rakefile, you must use
204
- string literals to specify modules and classes (and with full namespace).</p>
205
-
206
- <p>If this is the route you are taking, there needs no editing of the source
207
- program whatsoever. This task will take care of instrumenting the specified
208
- modules and classes at proper moments.</p>
209
-
210
- <h2>Type Annotation</h2>
211
-
212
- <p>The annotation language used in RubyBreaker resembles the method
213
- documentation used by Ruby Standard Library Doc. Each type signature
214
- defines a method type using the name, argument types, block type, and return
215
- type. But, let us consider a simple case where there is one argument type
216
- and a return type.</p>
217
-
218
- <pre><code>class A
219
- ...
220
- typesig("foo(fixnum) -&gt; string")
221
- end
222
- </code></pre>
223
-
224
- <p>In RubyBreaker, a type signature is recognized by the meta-class level
225
- method <code>typesig</code> which takes a string as an argument. This string is the
226
- actual type signature written in the Ruby Type Annotation Language. This
227
- language is designed to reflect the common documentation practice used by
228
- RubyDoc. It starts with the name of the method. In the above example, <code>foo</code>
229
- is currently being given a type. The rest of the signature takes a typical
230
- method type symbol, <code>(x) -&gt; y</code> where <code>x</code> is the argument type and <code>y</code> is the
231
- return type. In the example shown above, the method takes a <code>Fixnum</code> object
232
- and returns a <code>String</code> object. Note that these types are in lowercase,
233
- indicating they are objects and not modules or classes themselves.</p>
234
-
235
- <p>There are several types that represent an object: nominal, duck, fusion,
236
- nil, 'any', 'or', optional, variable-length, and block. Each type signature
237
- itself represents a method type or a method list type (explained below).</p>
238
-
239
- <h3>Nominal Type</h3>
240
-
241
- <p>This is the simplest and most intuitive way to represent an object. For
242
- instance, <code>fixnum</code> is an object of type <code>Fixnum</code>. Use lower-case letters and
243
- underscores instead of <em>camelized</em> name. <code>MyClass</code>, for example would be
244
- <code>my_class</code> in RubyBreaker type signatures. There is no particular
245
- reason for this convention other than it is the common practice used in
246
- RubyDoc. Use <code>/</code> to indicate the namespace delimiter <code>::</code>. For example,
247
- <code>NamspaceA::ClassB</code> would be represented by <code>namespace_a/class_b</code> in
248
- a RubyBreaker type signature.</p>
249
-
250
- <h3>Self Type</h3>
251
-
252
- <p>This type is similar to the nominal type but is referring to the current
253
- object--that is, the receiver of the method being typed. RubyBreaker will
254
- auto-document the return type as a self type if the return value is the same
255
- as the receiver of that call. It is also recommended to use this type over
256
- a nominal type (if the return value is <code>self</code>) since it depicts more
257
- precise return type.</p>
258
-
259
- <h3>Duck Type</h3>
260
-
261
- <p>This type is inspired by the Ruby Language's duck typing, <em>"if it
262
- walks like a duck and quacks like a duck, it must be a duck."</em> Using this
263
- type, an object can be represented simply by a list of method names. For
264
- example <code>[walks, quacks]</code> is an object that has <code>walks</code> and <code>quacks</code>
265
- methods. Note that these method names do <em>not</em> reveal any type
266
- information for themselves.</p>
267
-
268
- <h3>Fusion Type</h3>
269
-
270
- <p>Duck type is very flexible but can be too lenient when trying to restrict
271
- the type of an object. RubyBreaker provides a type called <em>the fusion type</em>
272
- which lists method names but with respect to a nominal type. For
273
- example, <code>fixnum[to_f, to_s]</code> represents an object that has methods <code>to_f</code>
274
- and <code>to_s</code> whose types are same as those of <code>Fixnum</code>. This is more
275
- restrictive (precise) than <code>[to_f, to_s]</code> because the two methods must have
276
- the same types as <code>to_f</code> and <code>to_s</code> methods, respectively, in <code>Fixnum</code>.</p>
277
-
278
- <h3>Nil Type</h3>
279
-
280
- <p>A nil type represents a value of nil and is denoted by <code>nil</code>.</p>
281
-
282
- <h3>Any Type</h3>
283
-
284
- <p>RubyBreaker also provides a way to represent an object that is compatible with
285
- any type. This type is denoted by <code>?</code>. Use caution with this type because
286
- it should be only used for an object that requires an arbitrary yet most
287
- specific type--that is, <code>?</code> is a subtype of any other type, but any
288
- other type is not a subtype of <code>?</code>. This becomes a bit complicated for
289
- method or block argument types because of their contra-variance
290
- characteristic. Please refer to the section <em>Subtyping</em>.</p>
291
-
292
- <h3>Or Type</h3>
293
-
294
- <p>Any above types can be "or"ed together, using <code>||</code>, to represent an object
295
- that can be either one or the other. It <em>does</em> not represent an object that
296
- has to be both (which is not supported by RubyBreaker).</p>
297
-
298
- <h3>Optional Argument Type and Variable-Length Argument Type</h3>
299
-
300
- <p>Another useful features of Ruby are the optional argument type and the
301
- variable-length argument type. The former represents an argument that has a
302
- default value (and therefore does not have to be provided). The latter
303
- represents zero or more arguments of the same type. These are denoted by
304
- suffices, <code>?</code> and <code>*</code>, respectively.</p>
305
-
306
- <h3>Block Type</h3>
307
-
308
- <p>One of the Ruby's prominent features is the block argument. It allows
309
- the caller to pass in a piece of code to be executed inside the callee. This
310
- code block can be executed by the Ruby construct, <code>yield</code>, or by directly
311
- calling the <code>call</code> method of the block object. In RubyBreaker, this type can
312
- be respresented by curly brackets. For instance, <code>{|fixnum,string| -&gt;
313
- string}</code> represents a block that takes two arguments--one <code>Fixnum</code> and one
314
- <code>String</code>--and returns a <code>String</code>.</p>
315
-
316
- <p>RubyBreaker does supports nested blocks as Ruby 1.9 finally allows them.
317
- However, <em>keep in mind</em> that RubyBreaker <em>cannot</em> automatically document the
318
- block types due to <code>yield</code> being a language construct rather than a method,
319
- which means it cannot be captured by meta-programming!</p>
320
-
321
- <h3>Method Type and Method List Types</h3>
322
-
323
- <p>Method type is similar to the block type, but it represents an actual method
324
- and not a block object. It is the "root" type that the type annotation
325
- language supports, along with method list types. Method <em>list</em> type is a
326
- collection of method types to represent more than one type information for
327
- the given method. Why would this type be needed? Consider the following Ruby
328
- code:</p>
329
-
330
- <pre><code>def foo(x)
331
- case x
332
- when Fixnum
333
- 1
334
- when String
335
- "1"
336
- end
337
- end
338
- </code></pre>
339
-
340
- <p>There is no way to document the type of <code>foo</code> without using a method list
341
- type. Let's try to give a method type to <code>foo</code> without a method list. The
342
- closest we can come up with would be <code>foo(fixnum or string) -&gt; fixnum and
343
- string</code>. But RubyBreaker does not have the "and" type in the type annotation
344
- language because it gives me an headache! (By the way, it needs to be an
345
- "and" type because the caller must handle both <code>Fixnum</code> and <code>String</code> return
346
- values.)</p>
347
-
348
- <p>It is a dilemma because Ruby programmers actually enjoy using this kind of
349
- dynamic type checks in their code. To alleviate this headache, RubyBreaker
350
- supports the method list type to represent different scenarios depending on
351
- the argument types. Thus, the <code>foo</code> method shown above can be given the
352
- following method list type:</p>
353
-
354
- <pre><code>typesig("foo(fixnum) -&gt; fixnum")
355
- typesig("foo(string) -&gt; string")
356
- </code></pre>
357
-
358
- <p>These two type signatures simply tell RubyBreaker that <code>foo</code> has two method
359
- types--one for a <code>Fixnum</code> argument and another for a <code>String</code> argument.
360
- Depending on the argument type, the return type is determined. In this
361
- example, a <code>Fixnum</code> is returned when the argument is also a <code>Fixnum</code> and a
362
- <code>String</code> is returned when the argument is also a <code>String</code>. When
363
- automatically documenting such a type, RubyBreaker looks for the (subtyping)
364
- compatibility between the return types and "promote" the method type to a
365
- method list type by spliting the type signature into two (or more in
366
- subsequent "promotions").</p>
367
-
368
- <h2>Type System</h2>
369
-
370
- <p>RubyBreaker comes with its own type system to auto-document the type
371
- information. Each method in a "breakable" module is dynamically instrumented
372
- to be monitored during runtime. This monitoring code observes the types of
373
- the arguments, block, and return value of each method. Once this information
374
- is gathered, RubyBreaker will compare it to the information gathered so far.
375
- If these two types are "compatiable", RubyBreaker will choose more general
376
- type of the two. Otherwise, RubyBreaker will use the method list type to
377
- accommodate two "incompatible" types.</p>
378
-
379
- <h3>Subtyping and Subclassing</h3>
380
-
381
- <p>RubyBreaker uses subtyping to choose one from the two "compatible" types.
382
- Two types are "compatible" if one is subtype of another. This means that the
383
- <em>subtype</em> can be represented using the <em>supertype</em> instead. This is why
384
- RubyBrekaer chooses the latter to document both types. RubyBreaker relies on
385
- subclassing of Ruby to determine a subtyping relationship between two types.
386
- For example, <code>Fixnum</code> is considered to be subtype of <code>Numeric</code> since the
387
- former is subclass of the latter. (Strictly speaking, <code>Fixnum</code> is not really
388
- subtype of <code>Numeric</code> because some methods are overriden in <code>Fixnum</code> with
389
- method types that are not subtype of the counterparts in <code>Numeric</code>. But,
390
- RubyBreaker is lenient and considers them compatible--that is, <code>Numeric</code> can
391
- represent any <code>Fixnum</code>.</p>
392
-
393
- <h3>Pluggable Type System (Advanced)</h3>
394
-
395
- <p>Yes, RubyBreaker was designed with the replaceable type system in mind. In
396
- other words, anyone can write his own type system and plug it into
397
- RubyBreaker. <em>Technical documentation coming soon...</em></p>
398
-
399
- <hr />
400
-
401
- <h1>Acknowledgment</h1>
402
-
403
- <p>The term, "Fusion Type," is first coined by Professor Michael W. Hicks at
404
- University of Maryland and represents an object using a structural type with
405
- respect to a nominal type.</p>
406
-
407
- <h1>Copyright</h1>
408
-
409
- <p>Copyright (c) 2012 Jong-hoon (David) An. All Rights Reserved.</p>
410
-
69
+ <hr />
70
+ <center style="font-size:smaller; padding:0px;">
71
+ Copyright (C) 2012 Jong-hoon (David) An. All Rights Reserved.<br />
72
+ Contact David An at rockalizer at gmail<br />
73
+ <a href="http://rockalizer.com">rockalizer.com</a>
74
+ </center>
411
75
  </div>
412
76
  </center>
413
77
  </body>