rdl 2.0.0.rc5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +4 -1
  3. data/LICENSE +2 -2
  4. data/README.md +21 -0
  5. data/rdl.gemspec +1 -1
  6. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37bb60eb1678b69aca3b6967c386f31c2d0c882f
4
- data.tar.gz: 8824ba76d0daa9d4049df6d4677846386e5c6733
3
+ metadata.gz: 4b6df831f327b7589e40ffedbd3bc38e4e314bf0
4
+ data.tar.gz: 7e540623bf270ff3c2dfa8152aa09b43f501cb92
5
5
  SHA512:
6
- metadata.gz: 593c30a12e453dc79c796b65c8598c345b0bb562978fb4a21fcb903c9a8d0fffcbc0b0534bb0187933ae8399c9dc8022bac689c77601282f442bb687dc79d985
7
- data.tar.gz: 4daaeafc5cc639db5afe714c9b4c71a8f9455dea7d8151741f3dcd914f384ca728389cc9f1931a255e97513be9b2423c7a0773dc09eba8959905fdfc6a568658
6
+ metadata.gz: daf3b07c5d3cb7d4efcc67ffb3306da05eaa63e6ed9175547dc8c42975f4aac967180fea3fca4f195b10375bce8e2d12c4b1c916476cab2634c43b8b3313a03b
7
+ data.tar.gz: 6128fc47b326e48e36632df96268ec76f8fedcecfb0853c85221ac10fdfb77b9f71d59817fd8fda367d09a04a25ec38a5c0f49c6d1f594f1c0344bcfb31a5a85
data/CHANGES.md CHANGED
@@ -1,12 +1,15 @@
1
1
  # Change log!
2
2
 
3
3
  ## [Unreleased]
4
+
5
+ ## [2.0.0] - 2016-08-24
4
6
  ### Added
7
+ - Static type checking!
5
8
  - `wrap: false` optional argument to `type`, `pre`, and `post`
6
9
  - Non-null type annotation (not checked)
7
10
  - Default argument configuration for `type`, `pre`, and `post`
8
11
  - `attr_*_type` methods
9
- - Static type checking!
12
+ - Initial types for Rails
10
13
 
11
14
  ### Changed
12
15
  - Modified `self` type to be any instance of the self's class
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2015, University of Maryland, College Park.
1
+ Copyright (c) 2014-2016, University of Maryland, College Park.
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
@@ -26,4 +26,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
26
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
27
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
28
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md CHANGED
@@ -40,6 +40,7 @@
40
40
  * [Other Features and Limitations](#other-features-and-limitations)
41
41
  * [Assumptions](#assumptions)
42
42
  * [Other RDL Methods](#other-rdl-methods)
43
+ * [Performance](#performance)
43
44
  * [Queries](#queries)
44
45
  * [Configuration](#configuration)
45
46
  * [Bibliography](#bibliography)
@@ -82,6 +83,8 @@ $ ruby file.rb
82
83
 
83
84
  Passing `typecheck: :now` to `type` checks the method body immediately or as soon as it is defined. Passing `typecheck: :call` to `type` statically type checks the method body whenever it is called. Passing `typecheck: sym` for some other symbol statically type checks the method body when `rdl_do_typecheck sym` is called.
84
85
 
86
+ Note that RDL tries to follow the philosophy that you get what you pay for. Methods with type annotations can be checked dynamically or statically; methods without type annotations are unaffected by RDL. See the [performance](#performance) discussion for more detail.
87
+
85
88
  RDL supports many more complex type annotations; see below for a complete discussion and examples.
86
89
 
87
90
  RDL types are stored in memory at run time, so it's also possible for programs to query them. RDL includes lots of contracts and types for the core and standard libraries. Since those methods are generally trustworthy, RDL doesn't actually enforce the contracts (since that would add overhead), but they are available to search, query, and use during type checking. RDL includes a small script `rdl_query` to look up type information from the command line. Note you might need to put the argument in quotes depending on your shell.
@@ -749,6 +752,24 @@ RDL also includes a few other useful methods:
749
752
 
750
753
  * `rdl_do_at(sym, &blk)` invokes `blk.call(sym)` when `rdl_do_typecheck(sym)` is called. Useful when type annotations need to be generated at some later time, e.g., because not all classes are loaded.
751
754
 
755
+ # Performance
756
+
757
+ RDL supports some tradeoffs between safety and performance. There are three main sources of overhead in using RDL:
758
+
759
+ * When a method is wrapped by RDL, invoking it is more expensive because it requires calling the wrapper which then calls the underlying method. This is the most significant run-time cost of using RDL, and it can be eliminated by adding `wrap: false` to an annotation. (But, this only makes sense for types, since those are the only annotations that can be statically checked.)
760
+
761
+ * When type checking is performed, RDL parses the program's source code and type checks method bodies. This source of overhead only happens once per method (unless `typecheck: :call` is used), so the overhead is probably not too bad (though we have not measured it).
762
+
763
+ * RDL adds an implementation of `method_added` and `singleton_method_added` to carry out some of its work, and those are called on every method addition. This source of overhead is again likely not too significant.
764
+
765
+ For uses of `pre` and `post`, there's not a lot of choice: those contracts are enforced at run-time and will incur the costs of wrapped methods. However, note that any methods that are not annotated with `pre` or `post` will not incur the cost of wrapping. (Similarly, methods not annotated with `type` never incur any wrapping cost.)
766
+
767
+ For uses of `type`, there are more choices, which can be split into two main use cases. First, suppose there's a method `m` that we want a type for but don't want to type check (for example, it may come from some external library). So suppose we read the documentation and give `m` type `(Fixnum) -> Fixnum`. We now have to decide whether to wrap `m`. If we don't wrap `m`, then we incur no overhead on calls to `m`, but we are trusting the type. If we do wrap `m`, then on every call to it RDL will check that we call it with a `Fixnum` and it actually returns a `Fixnum`. So if we're not completely sure of `m`'s type, it might be useful to wrap it and then run test cases against it to see if the type annotation is every violated. (For example, the RDL developers did this to test out many of the core library annotations in RDL.)
768
+
769
+ Second, suppose there's a method `m` that we do want to type check, and again `m` has type `(Fixnum) -> Fixnum`. Now RDL will use type checking to ensure that if `m` is given a `Fixnum` then it returns `Fixnum`. But now we again have to decide whether to wrap `m`. If we don't wrap `m`, then we get the most efficiency, since typechecking (assuming we do not do it at calls) will only happen once and calls will incur no overhead. On the other hand, it could be that some non-typechecked code calls `m` with something that's not a `Fixnum`, in which case `m` might do anything, including report a type error. (Notice the type checking of `m` assumed its input was a `Fixnum`, and it doesn't say anything about the case when its argument is not.) To protect against this case, we can wrap `m`. Then if a caller violates `m`'s type, we'll get an error in the caller code when it tries to call `m`.
770
+
771
+ (Side note: If typed methods are wrapped, then their type contracts are checked at run time for *all* callers, including ones that are were statically type checked and hence couldn't call methods at incorrect types. A future version of RDL will fix this, but it will require some significant changes to RDL's implementation strategy.)
772
+
752
773
  # Queries
753
774
 
754
775
  As discussed above, RDL includes a small script, `rdl_query`, to look up type information. (Currently it does not support other pre- and postconditions.) The script takes a single argument, which should be a string. Note that when using the shell script, you may need to use quotes depending on your shell. Currently several queries are supported:
@@ -4,7 +4,7 @@
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'rdl'
7
- s.version = '2.0.0.rc5'
7
+ s.version = '2.0.0'
8
8
  s.date = '2016-08-24'
9
9
  s.summary = 'Ruby type and contract system'
10
10
  s.description = <<-EOF
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdl
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc5
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeffrey S. Foster
@@ -247,9 +247,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
247
247
  version: '0'
248
248
  required_rubygems_version: !ruby/object:Gem::Requirement
249
249
  requirements:
250
- - - ">"
250
+ - - ">="
251
251
  - !ruby/object:Gem::Version
252
- version: 1.3.1
252
+ version: '0'
253
253
  requirements: []
254
254
  rubyforge_project:
255
255
  rubygems_version: 2.5.1