https://github.com/markbates/breach
https://github.com/markbates/breach
Last synced: 12 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/markbates/breach
- Owner: markbates
- License: mit
- Created: 2016-05-19T19:43:32.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2016-05-19T22:52:07.000Z (about 10 years ago)
- Last Synced: 2025-02-07T18:51:34.033Z (over 1 year ago)
- Language: Ruby
- Size: 27.3 KB
- Stars: 3
- Watchers: 5
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# breach
breach provides completely-optional method type checking, including support for interfaces, in Ruby, using concise and expressive syntax, allowing you to bring design-by-contract principles to Ruby.
## breach is currently under early development and as such, everything in this doc is aspirational, until it isn't.
## Usage
You can use breach for simple input type-checking:
```ruby
def print_a_string_three_times(str)
puts str * 3
end
type_check :print_a_string_three_times, inputs: [String]
print_a_string_three_times(DateTime.new) # raises Breach::InputTypeCheckFailed
```
So, breach automatically will wrap the `print_a_string_three_times` method and, prior to executing it, check the input to make sure it's a `String`. If not, you'll get a `Breach::InputTypeCheckFailed` exception raised right then and there, instead of running into a much more opaque and potentially misleading error later on.
breach really shines when you want to implement interfaces/abstract classes:
```ruby
module Writer
extend Breach::Interface
defines :write, inputs: [String], returns: [Numeric]
end
class MyWriter
implements Writer
def write(s)
return 1
end
end
mw = MyWriter.new
mw.write("Bingo bongo") # works
mw.write(3) # raises Breach::InputTypeCheckFailed
```
When used with interfaces, breach will also catch return type errors before they propagate out into the rest of your application, providing you a much more useful exception:
```ruby
module Writer
extend Breach::Interface
defines :write, inputs: [String], returns: [Numeric]
end
class MyWriter
implements Writer
def write(s)
return "Flippy floppy" # note: not a Numeric
end
end
mw = MyWriter.new
mw.write("Any string") # raises Breach::ReturnTypeCheckFailed
```
If you need to support multiple potential classes of input (or return types), use an array:
```ruby
module Writer
extend Breach::Interface
defines :write, inputs: [String, [Hash, nil]], returns: [Numeric]
end
class MyWriter
implements Writer
def write(s)
return "Flappy foo"
end
end
mw = MyWriter.new
mw.write("Hi there", {foo: "bar"}) # works
mw.write("Interfaces are cool!", nil) # works
mw.write("A bridge too far!", DateTime.new) # raises Breach::InputTypeCheckFailed
```
* todo: optional args
* todo: splat args
Not only will your run-time errors be more useful, it'll also catch interface implementation problems *at require time*:
```ruby
class NotActuallyAWriter
implements Writer
# no write method
end # raises a Breach::NotImplementedError!
```
Since breach's interface definitions are just regular mix-ins, you can compose them together:
```ruby
module Writer
extend Breach::Interface
defines :write, inputs: [String, [Hash, nil], :optional], returns: [Numberable]
end
module Reader
extend Breach::Interface
defines :read, inputs: [File], returns: [String]
end
module ReadWriter
extend Breach::Interface
include Writer
include Reader
end
```
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'breach'
```
And then execute:
$ bundle
Or install it yourself as:
$ gem install breach
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome [on GitHub](http://github.com/markbates/breach). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).