rigortype 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +215 -134
- data/data/builtins/ruby_core/comparable.yml +87 -0
- data/data/builtins/ruby_core/complex.yml +505 -0
- data/data/builtins/ruby_core/date.yml +1737 -0
- data/data/builtins/ruby_core/enumerable.yml +557 -0
- data/data/builtins/ruby_core/file.yml +9 -0
- data/data/builtins/ruby_core/rational.yml +365 -0
- data/data/builtins/ruby_core/string.yml +9 -0
- data/data/builtins/ruby_core/time.yml +6 -4
- data/lib/rigor/cli.rb +1 -1
- data/lib/rigor/inference/builtins/comparable_catalog.rb +27 -0
- data/lib/rigor/inference/builtins/complex_catalog.rb +41 -0
- data/lib/rigor/inference/builtins/date_catalog.rb +98 -0
- data/lib/rigor/inference/builtins/enumerable_catalog.rb +27 -0
- data/lib/rigor/inference/builtins/rational_catalog.rb +38 -0
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +126 -12
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +99 -0
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +95 -0
- data/lib/rigor/inference/method_dispatcher.rb +3 -1
- data/lib/rigor/inference/narrowing.rb +210 -1
- data/lib/rigor/inference/scope_indexer.rb +87 -11
- data/lib/rigor/inference/statement_evaluator.rb +5 -1
- data/lib/rigor/rbs_extended.rb +11 -6
- data/lib/rigor/type/integer_range.rb +4 -2
- data/lib/rigor/version.rb +1 -1
- data/sig/rigor/environment.rbs +4 -6
- data/sig/rigor/inference.rbs +2 -1
- data/sig/rigor/type.rbs +41 -41
- metadata +12 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3b0e7446849097317ae0f4a26114036f41c4ad321abfcc492d25ac67995150b6
|
|
4
|
+
data.tar.gz: 95736bd636be7ba8698d4bf9a4cbdcbf870eaaf5a9117207f238f7429e064e94
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b16976fea05e9c4f9d9f9247e5858817e9938eff6329ce7e091f7c9196051170f3a36c528e6f6cb0386f4762c8b17302a6bb3a9df239e9385ec375a2c1b3a6ca
|
|
7
|
+
data.tar.gz: c8ac86259a502f4bfac5ef51464cf5eea45d599bdd3f9d164798b5b66a8257a8a117ea4e54b2314c27da9845a3723fa3fca61fe2f259988f2e19eb9b79c9df6d
|
data/README.md
CHANGED
|
@@ -1,169 +1,250 @@
|
|
|
1
1
|
# Rigor
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
[](https://badge.fury.io/rb/rigortype)
|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
**Inference-first static analysis for Ruby.** Add Rigor to your
|
|
7
|
+
Gemfile and run `rigor check` over your code — no annotations,
|
|
8
|
+
no runtime dependency on the analyzer, no DSL.
|
|
9
|
+
|
|
10
|
+
Rigor parses Ruby with [Prism](https://github.com/ruby/prism),
|
|
11
|
+
runs a flow-sensitive type-inference engine over each file,
|
|
12
|
+
consults RBS signatures and the project's own `sig/` directory
|
|
13
|
+
for any class it can find, and reports a small but trustworthy
|
|
14
|
+
catalogue of bugs (undefined methods on typed receivers, wrong
|
|
15
|
+
positional arity, provable `Integer / 0`, …).
|
|
16
|
+
|
|
17
|
+
When you want tighter types than RBS expresses, refine them
|
|
18
|
+
through the
|
|
19
|
+
[`RBS::Extended`](docs/type-specification/rbs-extended.md)
|
|
20
|
+
annotation surface — `rigor:v1:return:` /
|
|
21
|
+
`rigor:v1:param:` / `rigor:v1:assert` directives accept the
|
|
22
|
+
imported-built-in refinement names (`non-empty-string`,
|
|
23
|
+
`positive-int`, `non-empty-array[Integer]`, `int<5, 10>`, …)
|
|
24
|
+
without changing the underlying RBS.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Add the gem to your application's Gemfile (development group is
|
|
29
|
+
typical — Rigor is a static analyzer, not a runtime dependency):
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
group :development do
|
|
33
|
+
gem "rigortype", require: false
|
|
34
|
+
end
|
|
35
|
+
```
|
|
14
36
|
|
|
15
|
-
|
|
16
|
-
recognises the bulk of canonical Ruby surface — local variables,
|
|
17
|
-
ivars / cvars / globals (intra- and cross-method), self typing,
|
|
18
|
-
lexical constant lookup, predicate narrowing
|
|
19
|
-
(`is_a?` / `==` / `===` / `case`-`when`), block parameter binding,
|
|
20
|
-
closure escape, Tuple / HashShape carriers — plus the v0.0.3
|
|
21
|
-
constant-folding surface and the v0.0.4 refinement-carrier
|
|
22
|
-
catalogue (`Type::Difference` / `Type::Refined` / `Type::Intersection`,
|
|
23
|
-
14 imported built-in refinement names through
|
|
24
|
-
`Builtins::ImportedRefinements`, and the symmetric
|
|
25
|
-
`rigor:v1:return:` / `rigor:v1:param:` / `rigor:v1:assert:`
|
|
26
|
-
RBS::Extended directive routes). See [CHANGELOG.md](CHANGELOG.md)
|
|
27
|
-
for the per-release surface and
|
|
28
|
-
[docs/CURRENT_WORK.md](docs/CURRENT_WORK.md) for the live slice
|
|
29
|
-
trail.
|
|
30
|
-
|
|
31
|
-
## Requirements
|
|
32
|
-
|
|
33
|
-
- Nix with the `nix-command` and `flakes` features available.
|
|
34
|
-
- Ruby 4.0.x and Bundler 4.x, provided by the Flake development
|
|
35
|
-
shell.
|
|
36
|
-
|
|
37
|
-
## Setup
|
|
37
|
+
Install:
|
|
38
38
|
|
|
39
39
|
```sh
|
|
40
|
-
|
|
41
|
-
nix --extra-experimental-features 'nix-command flakes' develop --command bundle exec rake
|
|
40
|
+
bundle install
|
|
42
41
|
```
|
|
43
42
|
|
|
44
|
-
|
|
43
|
+
Or, for a one-off install outside Bundler:
|
|
45
44
|
|
|
46
45
|
```sh
|
|
47
|
-
|
|
46
|
+
gem install rigortype
|
|
48
47
|
```
|
|
49
48
|
|
|
50
|
-
|
|
49
|
+
The gem ships an executable named `rigor` (gem name is
|
|
50
|
+
`rigortype` because `rigor` was already taken on RubyGems).
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
**Ruby version.** The gemspec requires `>= 4.0.0, < 4.1`.
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
## First analysis
|
|
55
|
+
|
|
56
|
+
Drop into your project root and run the canonical commands:
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
```sh
|
|
59
|
+
# Diagnose unknown methods, wrong-arity calls, and other
|
|
60
|
+
# rule-driven bugs across `lib/`.
|
|
61
|
+
bundle exec rigor check lib
|
|
60
62
|
|
|
61
|
-
#
|
|
62
|
-
bundle exec
|
|
63
|
+
# Print the inferred type at a precise FILE:LINE:COL position.
|
|
64
|
+
bundle exec rigor type-of lib/foo.rb:10:5
|
|
63
65
|
|
|
64
|
-
#
|
|
65
|
-
|
|
66
|
+
# Report Scope#type_of coverage across a tree (handy when
|
|
67
|
+
# diagnosing why a particular call site reads as `untyped`).
|
|
68
|
+
bundle exec rigor type-scan lib
|
|
66
69
|
|
|
67
|
-
#
|
|
68
|
-
bundle exec
|
|
70
|
+
# Drop a starter .rigor.yml into the project root.
|
|
71
|
+
bundle exec rigor init
|
|
69
72
|
```
|
|
70
73
|
|
|
71
|
-
###
|
|
72
|
-
|
|
73
|
-
`rigor check` reports the canonical type-check signals it can
|
|
74
|
-
prove against the loaded RBS environment:
|
|
74
|
+
### Sample output
|
|
75
75
|
|
|
76
76
|
```sh
|
|
77
77
|
$ cat /tmp/demo.rb
|
|
78
|
-
"hello".no_such_method #
|
|
79
|
-
[1, 2, 3].rotate(1, 2) #
|
|
78
|
+
"hello".no_such_method # undefined method
|
|
79
|
+
[1, 2, 3].rotate(1, 2) # wrong number of arguments
|
|
80
80
|
|
|
81
|
-
$ bundle exec
|
|
81
|
+
$ bundle exec rigor check /tmp/demo.rb
|
|
82
82
|
/tmp/demo.rb:1:9: error: undefined method `no_such_method' for "hello"
|
|
83
83
|
/tmp/demo.rb:2:11: error: wrong number of arguments to `rotate' on Array (given 2, expected 0..1)
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
The rule catalogue is
|
|
87
|
-
only when the receiver type is statically
|
|
88
|
-
set on that class is enumerable through
|
|
89
|
-
`define_method` discovery. Implicit-
|
|
90
|
-
receivers, and constant-decl alias classes
|
|
91
|
-
are skipped to avoid false positives.
|
|
92
|
-
|
|
93
|
-
##
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
86
|
+
The rule catalogue is **deliberately conservative**: a
|
|
87
|
+
diagnostic fires only when the receiver type is statically
|
|
88
|
+
known and the method set on that class is enumerable through
|
|
89
|
+
RBS or in-source `def` / `define_method` discovery. Implicit-
|
|
90
|
+
self calls, dynamic receivers, and constant-decl alias classes
|
|
91
|
+
(e.g. `YAML` → `Psych`) are skipped to avoid false positives.
|
|
92
|
+
|
|
93
|
+
## How Rigor finds your types
|
|
94
|
+
|
|
95
|
+
Rigor consults, in order:
|
|
96
|
+
|
|
97
|
+
1. **In-source RBS.** If your project has a `sig/` directory,
|
|
98
|
+
Rigor auto-loads it. `rigor init` writes a `.rigor.yml`
|
|
99
|
+
that points at `sig/` by default.
|
|
100
|
+
2. **Bundled RBS core + stdlib.** Pathname, OptParse, JSON,
|
|
101
|
+
YAML, etc. ship with the analyzer.
|
|
102
|
+
3. **Gem RBS.** RBS files vendored with installed gems
|
|
103
|
+
(Prism's own `.rbs`, the `rbs` gem's, …).
|
|
104
|
+
4. **In-source class discovery.** When no RBS is available,
|
|
105
|
+
Rigor walks `def` / `define_method` / `attr_*` so
|
|
106
|
+
user-defined methods on a class are recognised.
|
|
107
|
+
|
|
108
|
+
If a type cannot be proved, the engine returns `Dynamic[Top]`
|
|
109
|
+
(Rigor's gradual carrier) and stays silent — Rigor never invents
|
|
110
|
+
diagnostics it cannot prove.
|
|
111
|
+
|
|
112
|
+
## Refining types through `RBS::Extended`
|
|
113
|
+
|
|
114
|
+
When the RBS-declared type is too wide, attach a
|
|
115
|
+
`%a{rigor:v1:…}` annotation to the relevant method in your
|
|
116
|
+
`sig/` file. The annotation is a no-op for ordinary RBS tools
|
|
117
|
+
and a tightening signal for Rigor.
|
|
118
|
+
|
|
119
|
+
```rbs
|
|
120
|
+
class Slug
|
|
121
|
+
# The runtime always returns a non-empty string. The override
|
|
122
|
+
# tightens the call-site result to non-empty-string and tells
|
|
123
|
+
# the body's `assert_type` that `id` cannot be "".
|
|
124
|
+
%a{rigor:v1:return: non-empty-string}
|
|
125
|
+
%a{rigor:v1:param: id is non-empty-string}
|
|
126
|
+
def normalise: (::String id) -> ::String
|
|
127
|
+
end
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Right-hand side accepts:
|
|
131
|
+
|
|
132
|
+
- **RBS class names** — `String`, `::Foo::Bar` (with optional
|
|
133
|
+
`~T` negation for `assert` / `predicate-if-*`).
|
|
134
|
+
- **Imported-built-in refinement names** (kebab-case):
|
|
135
|
+
- Point-removal — `non-empty-string`, `non-zero-int`,
|
|
136
|
+
`non-empty-array[T]`, `non-empty-hash[K, V]`.
|
|
137
|
+
- IntegerRange aliases — `positive-int`, `non-negative-int`,
|
|
138
|
+
`negative-int`, `non-positive-int`, `int<min, max>`.
|
|
139
|
+
- Predicate refinements — `lowercase-string`,
|
|
140
|
+
`uppercase-string`, `numeric-string`, `decimal-int-string`,
|
|
141
|
+
`octal-int-string`, `hex-int-string`.
|
|
142
|
+
- Composed shapes — `non-empty-lowercase-string`,
|
|
143
|
+
`non-empty-uppercase-string`.
|
|
144
|
+
|
|
145
|
+
The full directive table is in
|
|
146
|
+
[`docs/type-specification/rbs-extended.md`](docs/type-specification/rbs-extended.md);
|
|
147
|
+
the catalogue of refinement names is in
|
|
148
|
+
[`docs/type-specification/imported-built-in-types.md`](docs/type-specification/imported-built-in-types.md).
|
|
149
|
+
|
|
150
|
+
### Example: argument-type-mismatch caught at the call site
|
|
151
|
+
|
|
152
|
+
```rbs
|
|
153
|
+
# sig/normaliser.rbs
|
|
154
|
+
class Normaliser
|
|
155
|
+
%a{rigor:v1:param: id is non-empty-string}
|
|
156
|
+
def normalise: (::String id) -> ::String
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
# app/normaliser.rb
|
|
162
|
+
class Normaliser
|
|
163
|
+
def normalise(id)
|
|
164
|
+
id.upcase
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
n = Normaliser.new
|
|
169
|
+
n.normalise("hello") # OK
|
|
170
|
+
n.normalise("") # rigor flags: argument type mismatch
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`rigor check` reports the second call as an
|
|
174
|
+
`argument-type-mismatch` because the literal `""` does not
|
|
175
|
+
satisfy `non-empty-string`. Inside the method body, Rigor also
|
|
176
|
+
sees `id` as `non-empty-string` (so `id.empty?` reduces to
|
|
177
|
+
`Constant[false]` and `id.size` reduces to `positive-int`).
|
|
178
|
+
|
|
179
|
+
## What rigor sees today
|
|
180
|
+
|
|
181
|
+
- **Local / instance / class / global variables** —
|
|
182
|
+
intra-method bindings, cross-method ivar / cvar
|
|
183
|
+
accumulators, program-wide globals, and compound writes
|
|
184
|
+
(`||=`, `&&=`, `+=`).
|
|
185
|
+
- **`self` typing and constant lookup** — class and method
|
|
186
|
+
body boundaries inject `Singleton[T]` / `Nominal[T]`;
|
|
187
|
+
lexical constant resolution walks RBS-core, common stdlib,
|
|
188
|
+
in-source class discovery, and in-source constant-value
|
|
189
|
+
tracking (`BUCKETS = [:a, :b]; BUCKETS.first` →
|
|
190
|
+
`Constant[:a]`).
|
|
111
191
|
- **Predicate narrowing** — truthiness, `nil?`, `is_a?` /
|
|
112
192
|
`kind_of?` / `instance_of?`, finite-literal equality,
|
|
113
193
|
case-equality (`===`) for Class / Module / Range / Regexp,
|
|
114
194
|
`case` / `when` integration.
|
|
115
|
-
- **Blocks** — parameter binding (incl. destructuring + numbered
|
|
116
|
-
parameters), block-return-type uplift through generic methods
|
|
117
|
-
(`Array#map { |n| n.to_s }` → `Array[String]`), closure escape
|
|
118
|
-
classification, captured-local invalidation on escaping blocks.
|
|
119
195
|
- **Tuple / HashShape carriers** — shape-aware element access,
|
|
120
|
-
range / start-length slices, closed / open / required /
|
|
121
|
-
policies
|
|
122
|
-
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
196
|
+
range / start-length slices, closed / open / required /
|
|
197
|
+
optional policies.
|
|
198
|
+
- **Constant folding** — aggressive arithmetic / string /
|
|
199
|
+
Symbol / Tuple-shaped `divmod` folding, cartesian fold over
|
|
200
|
+
`Union[Constant…]`, integer-range arithmetic
|
|
201
|
+
(`positive-int + 1` → `int<2, max>`), branch elision on
|
|
202
|
+
provably-truthy / falsey predicates.
|
|
203
|
+
- **Built-in catalogues** — Numeric, String, Symbol, Array,
|
|
204
|
+
IO, File, Hash, Range, Set, Time. Each catalog drives the
|
|
205
|
+
fold dispatcher with per-class blocklists for indirect
|
|
206
|
+
mutators.
|
|
207
|
+
- **Refinement carriers** — `Type::Difference`,
|
|
208
|
+
`Type::Refined`, `Type::Intersection` provide the
|
|
209
|
+
imported-built-in catalogue end-to-end through
|
|
210
|
+
`Builtins::ImportedRefinements`.
|
|
211
|
+
- **`RBS::Extended` directive routes** — `return:`, `param:`
|
|
212
|
+
(call-site + body-side), `assert:` /
|
|
213
|
+
`predicate-if-(true|false)` accept refinement payloads.
|
|
214
|
+
|
|
215
|
+
The full per-release surface lives in
|
|
216
|
+
[`CHANGELOG.md`](CHANGELOG.md). The internal contracts the
|
|
217
|
+
analyzer guarantees live under
|
|
218
|
+
[`docs/internal-spec/`](docs/internal-spec/).
|
|
219
|
+
|
|
220
|
+
## Configuration
|
|
221
|
+
|
|
222
|
+
`rigor init` writes a starter `.rigor.yml`:
|
|
223
|
+
|
|
224
|
+
```sh
|
|
225
|
+
bundle exec rigor init # fails if .rigor.yml exists
|
|
226
|
+
bundle exec rigor init --force # overwrite
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The configuration is intentionally small in v0.0.x; see the
|
|
230
|
+
generated file for the available knobs.
|
|
231
|
+
|
|
232
|
+
## Status
|
|
233
|
+
|
|
234
|
+
Current release: **`v0.0.4`** (the fourth preview). The
|
|
235
|
+
analyzer is usable on real Ruby code today but the rule
|
|
236
|
+
catalogue is deliberately narrow — Rigor's stance is to surface
|
|
237
|
+
zero false positives while the inference surface stabilises.
|
|
238
|
+
The roadmap is tracked in
|
|
239
|
+
[`docs/MILESTONES.md`](docs/MILESTONES.md); release-by-release
|
|
240
|
+
detail lives in [`CHANGELOG.md`](CHANGELOG.md).
|
|
241
|
+
|
|
242
|
+
## Contributing
|
|
243
|
+
|
|
244
|
+
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the minimal
|
|
245
|
+
`git clone` → green-tests path and a map of the spec / ADR /
|
|
246
|
+
skill documentation contributors should know about.
|
|
165
247
|
|
|
166
248
|
## License
|
|
167
249
|
|
|
168
|
-
|
|
169
|
-
See [LICENSE](LICENSE).
|
|
250
|
+
Mozilla Public License Version 2.0. See [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# DO NOT EDIT — generated by tool/extract_builtin_catalog.rb
|
|
2
|
+
---
|
|
3
|
+
schema_version: 1
|
|
4
|
+
generated_from:
|
|
5
|
+
ruby_init_c: references/ruby/compar.c
|
|
6
|
+
ruby_prelude:
|
|
7
|
+
rbs:
|
|
8
|
+
- references/rbs/core/comparable.rbs
|
|
9
|
+
purity_levels:
|
|
10
|
+
leaf: Prelude :leaf marker (VM-enforced) or C body uses no dispatch/yield/mutation.
|
|
11
|
+
trivial: Prelude method body is a literal return (self/true/false/nil/Integer).
|
|
12
|
+
leaf_when_numeric: C body falls through to rb_num_coerce_* only when an operand
|
|
13
|
+
is non-numeric; safe to fold when every argument is a concrete numeric.
|
|
14
|
+
inline_block: Prelude method carries :inline_block or :use_block; block-dependent.
|
|
15
|
+
block_dependent: C body yields or checks rb_block_given_p.
|
|
16
|
+
mutates_self: C body checks rb_check_frozen — typically a prelude to mutation.
|
|
17
|
+
dispatch: C body calls user-redefinable methods (rb_funcall*, rb_equal, rb_Float,
|
|
18
|
+
num_funcall*, etc).
|
|
19
|
+
unknown: C body not located in indexed C files.
|
|
20
|
+
classes:
|
|
21
|
+
Comparable:
|
|
22
|
+
parent: Module
|
|
23
|
+
defined_at: references/ruby/compar.c:324
|
|
24
|
+
includes: []
|
|
25
|
+
constants: {}
|
|
26
|
+
aliases: {}
|
|
27
|
+
instance_methods:
|
|
28
|
+
"==":
|
|
29
|
+
source: c
|
|
30
|
+
cfunc: cmp_equal
|
|
31
|
+
arity: 1
|
|
32
|
+
defined_at: references/ruby/compar.c:325
|
|
33
|
+
c_body_at: references/ruby/compar.c:79
|
|
34
|
+
c_effects:
|
|
35
|
+
- dispatch
|
|
36
|
+
purity: dispatch
|
|
37
|
+
">":
|
|
38
|
+
source: c
|
|
39
|
+
cfunc: cmp_gt
|
|
40
|
+
arity: 1
|
|
41
|
+
defined_at: references/ruby/compar.c:326
|
|
42
|
+
c_body_at: references/ruby/compar.c:105
|
|
43
|
+
c_effects: []
|
|
44
|
+
purity: leaf
|
|
45
|
+
">=":
|
|
46
|
+
source: c
|
|
47
|
+
cfunc: cmp_ge
|
|
48
|
+
arity: 1
|
|
49
|
+
defined_at: references/ruby/compar.c:327
|
|
50
|
+
c_body_at: references/ruby/compar.c:119
|
|
51
|
+
c_effects: []
|
|
52
|
+
purity: leaf
|
|
53
|
+
"<":
|
|
54
|
+
source: c
|
|
55
|
+
cfunc: cmp_lt
|
|
56
|
+
arity: 1
|
|
57
|
+
defined_at: references/ruby/compar.c:328
|
|
58
|
+
c_body_at: references/ruby/compar.c:137
|
|
59
|
+
c_effects: []
|
|
60
|
+
purity: leaf
|
|
61
|
+
"<=":
|
|
62
|
+
source: c
|
|
63
|
+
cfunc: cmp_le
|
|
64
|
+
arity: 1
|
|
65
|
+
defined_at: references/ruby/compar.c:329
|
|
66
|
+
c_body_at: references/ruby/compar.c:156
|
|
67
|
+
c_effects: []
|
|
68
|
+
purity: leaf
|
|
69
|
+
between?:
|
|
70
|
+
source: c
|
|
71
|
+
cfunc: cmp_between
|
|
72
|
+
arity: 2
|
|
73
|
+
defined_at: references/ruby/compar.c:330
|
|
74
|
+
c_body_at: references/ruby/compar.c:177
|
|
75
|
+
c_effects: []
|
|
76
|
+
purity: leaf
|
|
77
|
+
clamp:
|
|
78
|
+
source: c
|
|
79
|
+
cfunc: cmp_clamp
|
|
80
|
+
arity: -1
|
|
81
|
+
defined_at: references/ruby/compar.c:331
|
|
82
|
+
c_body_at: references/ruby/compar.c:231
|
|
83
|
+
c_effects:
|
|
84
|
+
- raises
|
|
85
|
+
purity: leaf
|
|
86
|
+
singleton_methods: {}
|
|
87
|
+
undefined: []
|