This document describes rbs subtract.
You can use rbs subtract
from command line.
rbs subtract
focuses on conbining auto-generated RBSs and hand-written RBSs (or two kinds auto-generated RBSs).
There are several RBS generators. For example, rbs prototype
, RBS Rails, and so on. They are useful, but the RBSs generated by them is not complete, for example, they include untyped
.
So we want to override the generated RBSs with hand-written RBSs. But we had no good way to override them.
To solve this problem, we need to remove C#m
definition from the generated RBS. But modifing a generated file by the hand introduces hard maintainability sooner or later.
rbs subtract
solves this problem. It removes duplicated definitions from the generated RBS automatically. Then we can maintain the generated RBSs.
The rbs subtract
's goal is modifying generated RBSs to make it valid with the other RBSs. So, after rbs subtract a.rbs b.rbs > c.rbs
, the environment including b.rbs
and c.rbs
has to be valid.
We can use this command with the following workflow on a Rails application.
Then the sig directory contains a complete RBS files as an environment. It means rbs -Isig validate
passes (if there is no missing classes and so on).
See the test file.
The main implementation is RBS::Subtractor
. It subtracts an environment from declarations.
It uses RBS::Environment
as the subtrahend.
It needs to merge several class declarations for the same class, so RBS::Declarations
is not appropriate for this purpose.
The subtrahend RBSs is probably incomplete RBS, for example, it may depend on the minuend RBS. RBS::DefinitionBuilder
does not work in this case, so it is inappropriate also.
rbs subtract
is not aware of interfaces mixins. For example
x
method remains in the subtracted. Because it is actually defined by _I
, but not C
.
It causes duplicated method definition error, so I'd like to improve this situation.
class C
from subtracted if the subtrahend incldues interface mixins.
The subtracted RBS doesn't work with the subtrahend if the subtrahend contains a class/module with type parameters.
Currently rbs subtract
command removes attr_accessor
if the subtrahend contains one of the methods that attr_accessor
defines. For example
In this case, rbs subtract a.rbs b.rbs
prints nothing. It removes C#a=
unexpectedly.
We can fix this problem more easily than other problems. We can convert attr_accessor
to a attr_{reader,writer}
in this case.
This section describes alternative approaches that I considered.
rbs subtract
treat the last argument as a subtrahend by default. But you can also specify multiple subtrahends by --subtrahend
option. For example:
Specifying multiple subtrahends is useful on the following situaion.
In this case, rbs subtract
executes (sig/prototype + sig/rbs_rails) - (sig/app + sig/lib)
, which takes two directories as the subtrahends.
I considered the following solutions too.