rubybreaker 0.0.5 → 0.0.6

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