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 lap
idary (or lap
idist) 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 file
Example
- 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
end
From 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) -> Float
This would produce:
# take some moeny out of the customers account
def withdraw(amount)
@balance -= amount
end
Installation
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: 80
Coverage
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.