Lap
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.
Usage
$ lap sig/file.rbs # outputs to stdout
$ lap sig/file.rbs > lib/file.rb # output into a fileExample
- Plan your project/module/class by writing some blueprints:
# sig/lib/bank/account.rbs
module Bank
class Account
attr_reader interest_rate: Float
attr_reader owner: Bank::Customer
attr_reader balance: Float
def initialize: (Bank::Customer owner, Float interest_rate, ?Float balance) -> void
type date_or_dt = Date | DateTime
# can optionally specify when the transaction should take place
def deposit: (Float amount, ?when: date_or_dt) -> Float
# can optionally specify when the transaction should take place
def withdraw: (Float amount, ?when: date_or_dt) -> Float
# must filter results by specifying `to` and `from` params
def transactions: (from: date_or_dt, to: date_or_dt) -> Array[Bank::Transaction]
end
end- Generate your ruby templates
$ lap sig/lib/bank/account.rbs > lib/bank/account.rb(Generates lib/bank/account.rb)
module Bank
class Account
attr_reader :interest_rate
attr_reader :owner
attr_reader :balance
def initialize(owner, interest_rate, balance = nil)
# returns void
end
# can optionally specify when the transaction should take place
def deposit(amount, when: nil)
# TODO: return Float
end
# can optionally specify when the transaction should take place
def withdraw(amount, when: nil)
# TODO: return Float
end
# must filter results by specifying `to` and `from` params
def transactions(to:, from:)
# TODO: return Array
end
end
end- Fill in your business logic!
module Bank
class Account
attr_reader :interest_rate
attr_reader :owner
attr_reader :balance
def initialize(owner, interest_rate, balance = 0)
@owner = owner
@interest_rate = interest_rate
@balance = balance
end
# can optionally specify when the transaction should take place
def deposit(amount, when: nil)
@balance += amount
end
# can optionally specify when the transaction should take place
def withdraw(amount, when: nil)
@balance -= amount
end
# must filter results by specifying `to` and `from` params
def transactions(to:, from:)
Transaction.where("created_at BETWEEN ? AND ?", from, to)
end
end
endFrom here, you now have some ruby code which you can type check!
Experimental:
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
# @!end
def withdraw(Float amount) -> FloatThis would produce:
# take some moeny out of the customers account
def withdraw(amount)
@balance -= amount
endInstallation
Add this line to your application's Gemfile:
gem 'lap'And then execute:
$ bundle install
Or install it yourself as:
$ gem install lap
Configuration
You can specify preferences in a .lap.yml file in your project directory. Example
indent: 4 # default is 2
frozen_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 guarantee
preferred_line_length: 80Coverage
Currently 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 | ⚠️ |
Development
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.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/johansenja/lap.
License
The gem is available as open source under the terms of the MIT License.