Don't write your code, and rbs types! Write the rbs types first, then generate a template to fill in with business logic.
A lapidary (or lapidist) is someone who cuts, polishes, or engraves precious stones.
$ lap sig/file.rbs # outputs to stdout
$ lap sig/file.rbs > lib/file.rb # output into a file- Plan your project/module/class by writing some blueprints:
# sig/lib/bank/account.rbsmoduleBankclassAccountattr_readerinterest_rate: Floatattr_readerowner: Bank::Customerattr_readerbalance: Floatdefinitialize: (Bank::Customerowner,Floatinterest_rate, ?Floatbalance) -> voidtypedate_or_dt=Date | DateTime# can optionally specify when the transaction should take placedefdeposit: (Floatamount, ?when: date_or_dt) -> Float# can optionally specify when the transaction should take placedefwithdraw: (Floatamount, ?when: date_or_dt) -> Float# must filter results by specifying `to` and `from` paramsdeftransactions: (from: date_or_dt,to: date_or_dt)->Array[Bank::Transaction]endend- Generate your ruby templates
$ lap sig/lib/bank/account.rbs > lib/bank/account.rb(Generates lib/bank/account.rb)
moduleBankclassAccountattr_reader:interest_rateattr_reader:ownerattr_reader:balancedefinitialize(owner,interest_rate,balance=nil)# returns voidend# can optionally specify when the transaction should take placedefdeposit(amount,when: nil)# TODO: return Floatend# can optionally specify when the transaction should take placedefwithdraw(amount,when: nil)# TODO: return Floatend# must filter results by specifying `to` and `from` paramsdeftransactions(to:,from:)# TODO: return Arrayendendend- Fill in your business logic!
moduleBankclassAccountattr_reader:interest_rateattr_reader:ownerattr_reader:balancedefinitialize(owner,interest_rate,balance=0)@owner=owner@interest_rate=interest_rate@balance=balanceend# can optionally specify when the transaction should take placedefdeposit(amount,when: nil)@balance += amountend# can optionally specify when the transaction should take placedefwithdraw(amount,when: nil)@balance -= amountend# must filter results by specifying `to` and `from` paramsdeftransactions(to:,from:)Transaction.where("created_at BETWEEN ? AND ?",from,to)endendendFrom here, you now have some ruby code which you can type check!
There is an experimental feature which allows you to specify some ruby logic within your rbs files
for your methods. You specify it between @!begin and @!end, eg.:
# take some moeny out of the customers account# @!begin# @balance -= amount# @!enddefwithdraw(Floatamount)->FloatThis would produce:
# take some moeny out of the customers accountdefwithdraw(amount)@balance -= amountendAdd this line to your application's Gemfile:
gem'lap'And then execute:
$ bundle install
Or install it yourself as:
$ gem install lap
You can specify preferences in a .lap.yml file in your project directory. Example
indent: 4# default is 2frozen_string_literals: false # add 'frozen_string_literal: true' to top of file; default is true# preferred line length in characters; default is 100. Note "preferred" - not always a guaranteepreferred_line_length: 80Currently not every feature of RBS is supported - yet! (contributions welcome!)
| Feature | Coverage |
|---|---|
| classes (includes nested) | ✅ |
| modules (includes nested) | ✅ |
| class methods | ✅ |
| instance methods | ✅ |
| required positional arguments | ✅ |
| optional positional arguments | ✅ |
| required keyword arguments | ✅ |
| optional keyword arguments | ✅ |
| method comments | ✅ |
| access modifiers | ✅ |
| attr_reader | ✅ |
| attr_writer | ✅ |
| attr_accessor | ✅ |
| include | ✅ |
| extend | ✅ |
| methods with blocks | ✅ |
| method overloading | |
| procs | |
| constants | |
| interfaces |
After checking out the repo, run bin/setup to install dependencies. Then, run rake spec 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.
Bug reports and pull requests are welcome on GitHub at https://github.com/johansenja/lap.
The gem is available as open source under the terms of the MIT License.