# Sake cheat sheet (for Ruby programmers and language models) Sake is Ruby syntax where **every operation names its type**: `String.upcase(s)`, never `s.upcase`. Run: `bin/sake FILE.sake` (`-c` checks only). Exit 0 ok, 1 runtime error, 2 rejected before running. `--strict=N`: 0 names/arity/syntax only; 1 (default) + wrong types and a `rescue` an earlier clause covers (a `rescue` of what is never raised is a warning, item `unused-rescue`); 2 + a maybe-nil value used unchecked (except the nil of a miss: `x[k]`, `Array.first/last/ pop/shift/min/max/minmax/at/slice/dig`, `Hash.dig`, `Set.first/min/max`); 3 + those misses and a non-exhaustive literal `case`; 4 + a `raise` never rescued. Part 1 gives the rules; Part 2 lists every built-in operation (only those exist). ## Part 1. Rules ### Calls - Built-in and user operations: `Type.op(subject, args...)`. Chain form: `T.f(x).U.op(args)` is `U.op(T.f(x), args)`; start a chain with `T.f(x)`. A step without a type continues with the type the chain named last: `T.f(x).op` is `T.f(x).T.op`; name the type where the value's type changes (`String.split(s, " ").Array.sort.join(",")`). A call on a value (`s.strip`, `xs.size`, `3.times`, `1.to_s`, `x.nil?`) is rejected. - Kernel functions are called bare: `puts print p pp format sprintf gets loop raise rand srand sleep exit warn system at_exit Integer(s) Float(s) Rational(..) Complex(..) dup(x) block_given? once ARGV`. `format` is Kernel only (no `String.format`); `"%d-%s" % [a, b]` also works. - Names are Ruby's: `Integer.to_s`, `String.include?`, `Array.each_with_index`. Not every Ruby arity exists: no `Array.min(xs, n)`, `Array.sort` takes no block (use `sort_by`, or `Comparable`), `Array.reduce`/`inject` **require** the initial value. Check Part 2 before using a name. - In-place forms exist (`Array.map!`, `sort!`, `uniq!`, `Hash.merge!`, `String.upcase!`, ...). A container has one element type for the whole program, so `Array.map!(xs) { Integer.to_s(it) }` makes `xs` hold Integer|String; to change the type, use `Array.map` (a new Array). - `Arithmetic.round(x)` (and `floor ceil truncate abs to_f to_i zero?`) accept Integer|Float|Rational; `Float.round(x, 2)` needs a Float. ```ruby s = " Hello World " puts(String.upcase(String.strip(s))) puts(String.strip(s).downcase) puts(String.split("b a c", " ").Array.sort.join(",")) p(Array.reduce(Any[1, 2, 3], 0) { |acc, x| acc + x }) p(format("%05.1f|%-3s|%3d", 3.14159, "a", 7), Integer.to_s(255, 16)) ``` ### Literals (the #1 source of errors) - `[a, b]` is a **Tuple** (fixed length, per-position types). `[]` cannot grow. - `Any[a, b]` / `Any[]` is a growable Array of any values. `T[...]` is an Array of T for every T, checked on every write: `Integer[]`, `String[]`, `Point[]`, `Shape[]` (a module: the types that include it), and `Array[...]` is an Array of Arrays. `Point[1, 2]` is NOT `Point.new`. - `{k: v}` is a **Record** (read with a pattern `r => {k:}`; no field writes). `{}` and `{"a" => 1}` are errors. - `Hash.of("a" => 1)`, `Hash.new`, `Hash.new(0)` make a Hash; `Set.of(1, 2)`, `Set.new(xs)` a Set (`Hash[...]`, `Set[...]` are Arrays of them). `Hash.new { ... }` is rejected. - `Set.of(1, 2)`, `1..5`, `1...n`, `1..`, `:sym`, `/re/i`, `2r`, `"a#{x}"` as in Ruby. `Regexp.new(s, "i")`. - No `%w[]`/`%i[]`, no `<<` on String or Array (use `s += t`, `Array.push(xs, x)`). - No value constants: `LIMIT = 10` is rejected; write `def limit = 10`. Constants hold only `Struct.new`, `Exception.new`, or a type (`Client = A::B`, a type alias). `Math.PI` (also `Math::PI`), `Float.INFINITY`, `ARGV` are operations. ```ruby t = [1, "one"] n, w = t xs = Any[3, 1] Array.push(xs, 2) fs = Float[] Array.push(fs, 1.5) r = {name: "ann", age: 3} r => {name:, age:} h = Hash.of("a" => 1) h["b"] = 2 counts = Hash.new(0) Array.each(String.split("a b a", " ")) { |k| counts[k] += 1 } st = Set.of(1) Set.add(st, 2) p([n, w, xs, fs, name, age, h, counts, Set.include?(st, 2)]) ``` ### Reading input - `gets` returns String or nil (it keeps the newline). There is no `$stdin`, `STDIN`, `ARGF`, `$<`. - Whole stdin: `IO.read(IO.stdin)`; lines: `IO.readlines(IO.stdin)` or `IO.each_line(IO.stdin) { |l| }`. Files: `File.read(path)`, `File.readlines(path)`, `File.open(path, "w") { |io| IO.puts(io, s) }`. - Output: `puts`, `print`, `p` (any number of arguments); `IO.puts(IO.stderr, msg)` or `warn(msg)` for stderr. - Arguments: `ARGV` is an Array of Strings: `Array.fetch(ARGV, 0)`, `Array.first(ARGV)` (nil when absent). Environment: `ENV.fetch("HOME")`, `ENV.get("X")` (nil when unset). ```ruby first = gets n = first ? String.to_i(String.chomp(first)) : 0 while (line = gets) nums = String.split(String.chomp(line), " ").Array.map { |x| String.to_i(x) } p([n, Array.sum(nums)]) end ``` ### Conversions and formatting - `String.to_i(s)`, `String.to_f(s)` (lenient, as Ruby); `Integer(s)`, `Float(s)` (strict, raise ArgumentError). `Integer.to_s(n, [base])`, `Float.to_s(f)`, `Integer.to_f(n)`, `Float.to_i(f)`, `String.to_sym(s)`, `Symbol.to_s(sym)`, `Kernel.to_s(any)`, `Kernel.inspect(any)`. - `7 / 2` is 3 (floors like Ruby); mixing Integer and Float gives Float; `Integer.fdiv(7, 2)` is 3.5. `"a" + 1` is a type error: interpolate (`"n=#{n}"`) or convert. - `format("%.2f %5d %-8s", ...)`, `String.rjust(s, 3, "0")`, `String.ljust`, `String.center`. - `Float.round(f)` gives an Integer; `Float.round(f, 2)` a Float. ```ruby p(Integer("42") + String.to_i("7x")) p(Float("1.5") + Integer.to_f(1)) p(Integer.to_s(255) + "!") p(Float.round(3.14159, 2)) p(String.rjust(Integer.to_s(5), 3, "0")) p(Integer.fdiv(7, 2)) q, r = Integer.divmod(7, 2) p([q, r, 7 / 2, -7 / 2]) ``` ### Blocks - Blocks go only to built-in operations and to your functions that `yield`. They are not values: no `proc`, `lambda`, `->`, `method(:f)`, `&:sym`, no stored blocks, no `Hash.new { }`. `&b` may only pass the function's own block on: `def f(xs, &b) = Array.map(xs, &b)`. - `it` / `_1` name a single parameter. `|a, b|` destructures one Tuple/Array argument; `|(k, v), i|` and `|h, *rest|` work. `next v`, `break v`, and `return` (leaves the enclosing def) as in Ruby. - `Enum` (the prelude) is Enumerable under a short name: `Enum.map(x) { }`, `select`, `reduce(x, init) { }`, `count`, `include?(x, v)`, `first`, `sort_by`, `group_by`, ... dispatch on x's type to Array, Hash, Set or Range (so `Enum.map(xs)` is `Array.map(xs)`); a class joins with `include Enum` and `def each(c) = ... yield(v)`. - Hash blocks receive `[k, v]`: `Hash.each(h) { |k, v| }`. Without a block, `each_with_index`, `each_slice`, `each_cons` return an Array (no Enumerator). `loop { break v }` works. - A function that `yield`s must be called with a block unless it checks `block_given?` (`return x unless block_given?`, or `block_given? && ...`). - No `for`, no `begin ... end while`; use `while`, `until`, `Integer.times`, `Range.each`. ```ruby def each_pair(a) Array.each(a) { |x| yield(x, x * x) } end def maybe(x) return yield(x) if block_given? x end def pass_on(xs, &b) = Array.map(xs, &b) each_pair(Any[1, 2]) { |x, sq| p([x, sq]) } p([maybe(1), maybe(1) { it + 1 }, pass_on(Any[1, 2]) { it * 10 }]) p(Array.each_with_index(Any["a", "b"]).map { |c, i| "#{i}#{c}" }) p(Array.sort_by(Any[[2, "b"], [1, "c"]]) { |num, s| [-num, s] }) Hash.each(Hash.of("x" => 1)) { |k, v| puts("#{k}=#{v}") } p(Array.each(Any[3, 12, 5]) { |x| break x if x > 10 }) ``` ### Functions, classes, fields - `def f(a, b = 1, *rest, k: 2, **opts)`, `def f(x) = expr` (short expressions only); `return a, b` returns a Tuple. Top-level functions cannot see top-level locals. `*rest` is an Array, so its elements share one type; to keep a type per position, pass a Tuple (`f(["AAPL", 120])`). `g(**opts)` passes the function's own `**opts` on to g's keywords, each key keeping its type (only that parameter, not any Hash). - `class C` with `attr_reader x, y` / `attr_accessor n` / `attr_writer w` (names bare, not Symbols; `attr_accessor :next` only for reserved words) declares a type with fields in that order. `private attr_reader x` hides the reader outside the class. No field defaults (`attr_reader a = 1` is rejected); no code in the body. Namespaces nest: `class B` inside `module A` (or `class A::B`) is `A::B`, used as `A::B.f(x)`; inside `A`, a bare `B` means `A::B` when it exists. `Client = A::B` (top level or in a class/module body) is another name for the type, scoped as a Ruby constant. - `C.new(x, y)` takes fields positionally (or by keyword: `C.new(1, y: 2)`; prefer keywords when there are several fields). Without `initialize` every field is required. `def initialize(c)` (exactly one parameter: the new instance, **not** the field values) runs after `new` stored the fields; with it, trailing fields may be left out and are nil until initialize sets them. `def initialize(x) = @x = x` is rejected: it would store the instance in its own field. - Every function in a class is called `C.f(...)`; by convention the first argument is the instance. There is **no `self`**. `@x` means field `x` of the function's **first argument**; `@x = v`, `@x += v`, `@x ||= v` write it. `@x` outside a class function is rejected; no globals (`$x`). - From anywhere: reader `C.x(v)` or `v.C.x`; writer (attr_accessor/attr_writer only) `C.set_x(v, w)` or `v.C.x = w` (also `v.C.x += 1`). `v.x` is rejected. - Fields by name: `C.field_names` (Symbols, in order), `C.read_field(v, :x)`, `C.write_field(v, :x, w)` (Ruby's Struct `members`, `[]`, `[]=`). A literal (or a Symbol narrowed by `case name in :x | :y`) keeps each field's type; any Symbol reads the union of the fields. - `def C.f(c)` outside the class = `def f(c)` inside. `def self.f` is rejected: one name is one function. - `Point = Struct.new(:x, :y)` = `class Point` with `attr_accessor x, y` (no block allowed). - `to_s(c)` / `inspect(c)` in the class are used by `puts`/`"#{}"` and `p`. `==` compares fields. - `class B < A` copies A's fields and functions into B; it is not inheritance (a B is not an A). - For the checker, each `C.new` site is its own type: a `Stack` of Integers made at one place and a `Stack` of Strings made at another do not mix, and a generic wrapper (`Box.new(yield(@v))`) is one type per caller. Messages write such a type as `Stack@L12` only when the type has several sites. ```ruby class Stack attr_reader items attr_accessor limit def initialize(s) @items = Integer[] @limit = 10 if @limit == nil end def push(s, x) Array.push(@items, x) s end def to_s(s) = "Stack(#{Array.join(@items, ",")})" end def Stack.top(s) = Array.last(Stack.items(s)) st = Stack.new Stack.push(st, 1) st.Stack.push(2) Stack.set_limit(st, 5) st.Stack.limit += 1 puts(st) p([Stack.limit(st), Stack.new(Integer[], 3).limit, Stack.new(Integer[], limit: 4).limit]) t = Stack.top(st) p(t + 1) if t Point = Struct.new(:x, :y) pt = Point.new(1, 2) Point.set_x(pt, 5) p(pt) p(Array.map(Point.field_names) { |f| [f, Point.read_field(pt, f)] }) ``` ### Modules, operators for your types - `module M` + `module_function`: plain functions `M.f(x)`. A module without `module_function` is a mixin: `include M` in a class copies its functions (they may call the includer's functions); `M.f(x)` dispatches to `x`'s type. A body of only `raise NotImplementedError` marks a required function. - Operators: `include Comparable` + `def <=>(a, b)` gives `< <= > >= ==` and `Array.sort/min/max`; `include Arithmetic` + `def +(a, b)`; `include Indexable` + `def [](c, k)` / `def []=(c, k, v)`. A built-in on the left (`2 + money`) needs `def coerce(m, other) = [Money.new(other), m]` in Money (Ruby's protocol: the Tuple `[left, right]` is converted first, then the operator runs). - `(A|B).f(x)` calls the `f` of x's type among the listed types (built-in types including `IO`, and classes; no nil). `*rest` is packed per branch; a function taking keywords cannot be listed. ```ruby module Shape def area(s) = raise(NotImplementedError) def describe(s) = "area #{area(s)}" end class Sq attr_reader side include Shape include Comparable def area(q) = @side * @side def <=>(a, b) = @side <=> Sq.side(b) end class Money attr_reader cents include Arithmetic def +(a, b) = Money.new(@cents + Money.cents(b)) def coerce(m, other) = [Money.new(other), m] def to_s(m) = "$#{@cents}" end module Util module_function def twice(x) = x * 2 end class Log attr_reader lines def print(l, *xs) Array.push(@lines, Array.join(Array.map(xs) { Kernel.to_s(it) }, "")) end end def out(io, a, b) = (IO|Log).print(io, a, b) p(Shape.describe(Sq.new(3))) p([Sq.new(2) < Sq.new(3), Array.max(Any[Sq.new(2), Sq.new(5)]), Util.twice(4)]) puts(Money.new(5) + Money.new(3), 3 + Money.new(5)) log = Log.new(String[]) out(IO.stdout, "a", 1) out(log, "b", 2) puts("", Log.lines(log)) ``` ### Pattern matching (instead of `case/when`, `is_a?`) - `case x` with `in Integer | Float then ...`, `in String`, `in nil`, `in :ok`, `in "s"`, `in {name:}`, `in [Integer, String]`, `in [a, b]` (binds), `in [Integer => n, String => s]` (binds what matched), `in Point`, `else`. `case/when` is rejected. No `*rest` in Tuple patterns, no find patterns, pins, guards. - `x in T` is a boolean test (parenthesize as an argument: `p((x in Integer))`). - `x => T` asserts (raises NoMatchingPatternError) and narrows x; also clears nil. ```ruby def kind(x) case x in Integer | Float then "num" in String then "str #{String.size(x)}" in nil then "nil" in {name:} then "rec #{name}" in [Integer, b] then "pair #{b}" in :ok then "ok" else "other" end end p(Array.map(Any[1, "s", nil, {name: "n"}, [1, "x"], :ok, 2.0]) { kind(it) }) v = Array.find(Any[1, 5]) { it > 3 } v => Integer p(v + 1) ``` ### nil (what `--strict=2` rejects) - Operations that may return nil: `gets`, `Array.find/index`, `String.index`, `String.match`, `Hash.delete`, `ENV.get`, a field never written, ... Using such a value in another operation without a check is rejected at level 2. The nil of a *miss* (`x[k]`, `Array.first/last/pop/ shift/min/max/minmax/at/slice/dig`, `Hash.dig`, `Set.first/min/max` on an empty collection) is checked only at level 3. - `Array.sort/min/max/sort_by/min_by/max_by` (and `Set`'s, `Tuple.max/min`) are rejected statically when the element (or key) types cannot all be compared with each other (`Any[1, "a"]`, a nil element). - A **local variable** is narrowed by `if x`, `x ? a : b`, `x != nil`, `return unless x`, `next unless x`, `x && ...`, `x => T`, `case x in`. `x.nil?` is rejected: write `x == nil`. - Defaults: `y = x || 0`, `Hash.fetch(h, k, 0)`, `Array.fetch(a, i, 0)`, `Hash.new(0)`. - A **field read** (`Node.nxt(n)`, `@nxt`) is narrowed until something may change it (a field write, a user function call, a block, an assignment to `n`): `if Node.nxt(n) then Node.v(Node.nxt(n))` is fine, but not with `f(n)` between the two. There, copy to a local first: `m = Node.nxt(n)`. ```ruby Node = Struct.new(:v, :nxt) def second(node) rest = Node.nxt(node) return 0 unless rest Node.v(rest) end n = Node.new(1, Node.new(2, nil)) p(second(n)) m = Node.nxt(Node.new(1, nil)) || Node.new(0, nil) p(Node.v(m)) h = Hash.of("a" => 1) p([Hash.fetch(h, "zz", 0) + 1, (h["a"] || 0) + 1]) i = String.index("abc", "c") p(i + 1) if i != nil ``` ### Exceptions - Declare: `class E < StandardError` (or `< Exception`) with optional `attr_reader` fields after the implicit first field `message`; or `E = Exception.new(:code)`. `rescue A, B => e` catches the listed types (`class B < A` is a copy: `rescue A` does not catch B); `rescue M => e` with a module M catches the types that `include M`; `rescue IndexError` also catches KeyError (Ruby's built-in parents); bare `rescue => e` catches all. - `raise "msg"` (RuntimeError), `raise ArgumentError, "msg"` (only for types without extra fields), `raise E.new("msg", 7)`. Read: `Exception.message(e)`, `E.code(e)`. No `e.message`. `Exception.backtrace(e)` / `Exception.cause(e)` (nil if never raised / no cause). - `expr rescue fallback`, `def ... rescue ... end`, `ensure`, `retry` work. Built-ins: ArgumentError KeyError IndexError ZeroDivisionError RangeError IOError TypeError RuntimeError NoMatchingPatternError StopIteration ... (Part 2 lists them). Their messages are Ruby's. - A `rescue` of a type the body never raises is a warning (`unused-rescue`; an error only when chosen). ```ruby class ParseError < StandardError attr_reader line end Oops = Exception.new(:code) def parse(s) raise ParseError.new("empty", 1) if String.empty?(s) raise ArgumentError, "too long" if String.size(s) > 3 raise Oops.new("neg", 7) if String.start_with?(s, "-") Integer(s) end Array.each(Any["", "1234", "-1", "12"]) do |s| begin p(parse(s)) rescue ParseError => e puts("line #{ParseError.line(e)}: #{Exception.message(e)}") rescue ArgumentError => e puts(Exception.message(e)) rescue Oops => e puts("code #{Oops.code(e)}") end end v = Integer("zz") rescue -1 p(v) ``` ### Libraries - `require "json"` loads `sakelib/json.sake` (or `json.sake` next to the file). Names are Ruby's with the subject first: `JSON.parse(s)`, `JSON.generate(h)`, `StringScanner.scan(ss, /\w+/)`. `require "sql/*"` reads every matching `.sake` file next to the requiring file, in name order. - Ported: json csv yaml toml base64 digest strscan optparse shellwords set-like structures time date fileutils pathname tempfile stringio logger benchmark net_http uri cgi ipaddr webrick monitor timeout bigdecimal matrix prime securerandom erb; gems colorize thor rack httparty redis money jwt kramdown liquid i18n faker concurrent_ruby rspec minitest. Each has `sakelib/notes/NAME.md`. - Tests with minitest: `suite = Minitest.suite("x")`, `Minitest.test(suite, "name") { |t| Minitest.assert_equal(t, want, got) }`, `Minitest.run(suite)`. ```ruby require "json" s = JSON.generate(Hash.of("a" => Any[1, 2])) puts(s) p(JSON.parse(s)) ``` ### Also rejected `self`, `$globals`, `eval`/`send`/`define_method`/`respond_to?`-style reflection, `defined?`, `&.`, `obj.method`, `Data.define`, `Struct.new(...) do`, `attr_reader :x` (Symbol form), `A::B` as a value (a namespace is not a value), `def A::B.f`, `require` of a non-literal, `case/when`, `for`, `%w[]`, writing a Record field, `<<` on String/Array, `f(**opts)`, `Integer.(a + b)`. Only the operations listed in Part 2 exist. ## Part 2. Operations Every built-in operation. `x` is the subject (an argument of the namespace's type), `[T]` an optional argument, `*T` any number of them, `{ }` a required block, `[{ }]` an optional one. Call them as `Namespace.name(...)`; the namespace is the heading. ### Arithmetic `abs(Integer|Float|Rational)` · `ceil(Integer|Float|Rational, [Integer])` · `floor(Integer|Float|Rational, [Integer])` · `round(Integer|Float|Rational, [Integer], [half: Symbol])` · `to_f(Integer|Float|Rational)` · `to_i(Integer|Float|Rational)` · `truncate(Integer|Float|Rational, [Integer])` · `zero?(Integer|Float|Rational)` ### Array `!=(x, Any)` · `*(x, Any)` · `+(x, Any)` · `-(x, Any)` · `<(x, Any)` · `<=(x, Any)` · `<=>(x, Any)` · `==(x, Any)` · `>(x, Any)` · `>=(x, Any)` · `[](x, Any, [Integer])` · `[]=(x, Any, Any)` · `all?(x) { }` · `any?(x) { }` · `append(x, *Any)` · `assoc(x, Any)` · `at(x, Integer)` · `bsearch(x) { }` · `bsearch_index(x) { }` · `chunk_while(x) { }` · `clear(x)` · `collect(x) { }` · `collect!(x) { }` · `combination(x, Integer)` · `compact(x)` · `compact!(x)` · `concat(x, Array)` · `count(x, [Any]) [{ }]` · `cycle(x, Integer) { }` · `delete(x, Any)` · `delete_at(x, Integer)` · `delete_if(x) { }` · `detect(x) { }` · `difference(x, *Array)` · `dig(x, Integer, *Any)` · `drop(x, Integer)` · `drop_while(x) { }` · `dup(x)` · `each(x) { }` · `each_cons(x, Integer) [{ }]` · `each_entry(x) { }` · `each_index(x) { }` · `each_slice(x, Integer) [{ }]` · `each_with_index(x) [{ }]` · `each_with_object(x, Any) { }` · `empty?(x)` · `fetch(x, Integer, [Any])` · `fetch_values(x, *Integer)` · `fill(x, Any)` · `filter(x) { }` · `filter!(x) { }` · `filter_map(x) { }` · `find(x) { }` · `find_all(x) { }` · `find_index(x) { }` · `first(x, [Integer])` · `flat_map(x) { }` · `flatten(x)` · `flatten!(x)` · `group_by(x) { }` · `include?(x, Any)` · `index(x, Any)` · `inject(x, Any) { }` · `insert(x, Integer, *Any)` · `intersect?(x, Array)` · `intersection(x, *Array)` · `join(x, [String])` · `keep_if(x) { }` · `last(x, [Integer])` · `length(x)` · `map(x) { }` · `map!(x) { }` · `max(x)` · `max_by(x) { }` · `min(x)` · `min_by(x) { }` · `minmax(x)` · `minmax_by(x) { }` · `new(Integer, [Any]) [{ }]` · `Array[*Any]` · `none?(x) { }` · `one?(x) { }` · `pack(x, String)` · `partition(x) { }` · `permutation(x, [Integer])` · `pop(x)` · `prepend(x, *Any)` · `product(x, Array)` · `push(x, *Any)` · `rassoc(x, Any)` · `reduce(x, Any) { }` · `reject(x) { }` · `reject!(x) { }` · `repeated_combination(x, Integer)` · `repeated_permutation(x, Integer)` · `replace(x, Array)` · `reverse(x)` · `reverse!(x)` · `reverse_each(x) { }` · `rfind(x) { }` · `rindex(x, Any)` · `rotate(x, [Integer])` · `rotate!(x, [Integer])` · `sample(x)` · `select(x) { }` · `select!(x) { }` · `shift(x, [Integer])` · `shuffle(x)` · `shuffle!(x)` · `size(x)` · `slice(x, Integer|Range, [Integer])` · `slice!(x, Integer|Range, [Integer])` · `slice_when(x) { }` · `sort(x)` · `sort!(x)` · `sort_by(x) { }` · `sort_by!(x) { }` · `sum(x, [Any]) [{ }]` · `take(x, Integer)` · `take_while(x) { }` · `tally(x)` · `to_a(x)` · `to_h(x)` · `to_set(x)` · `transpose(x)` · `union(x, *Array)` · `uniq(x)` · `uniq!(x)` · `unshift(x, *Any)` · `values_at(x, *Integer)` · `zip(x, *Array)` ### Complex `!=(x, Any)` · `*(x, Any)` · `**(x, Any)` · `+(x, Any)` · `-(x, Any)` · `/(x, Any)` · `==(x, Any)` · `abs(x)` · `abs2(x)` · `angle(x)` · `arg(x)` · `conj(x)` · `conjugate(x)` · `denominator(x)` · `fdiv(x, Integer|Float|Rational)` · `finite?(x)` · `imag(x)` · `imaginary(x)` · `infinite?(x)` · `magnitude(x)` · `Complex[*Any]` · `numerator(x)` · `phase(x)` · `polar(x)` · `quo(x, Integer|Float|Rational|Complex)` · `rationalize(x, [Rational])` · `real(x)` · `real?(x)` · `rect(x)` · `rectangular(x)` · `to_c(x)` · `to_f(x)` · `to_i(x)` · `to_r(x)` · `to_s(x)` ### Dir `children(String)` · `each_child(String) { }` · `empty?(String)` · `entries(String)` · `exist?(String)` · `glob(String|Array, [base: String])` · `home([String])` · `mkdir(String, [Integer])` · `mktmpdir([String], [String]) [{ }]` · `pwd()` · `rmdir(String)` · `tmpdir()` · `unlink(String)` ### ENV `delete(String)` · `fetch(String, [String])` · `get(String)` · `key?(String)` · `keys()` · `replace(Hash)` · `set(String, String)` · `to_h()` ### File `absolute_path(String, [String])` · `absolute_path?(String)` · `atime(String)` · `basename(String, [String])` · `chmod(Integer, *String)` · `delete(String)` · `directory?(String)` · `dirname(String, [Integer])` · `empty?(String)` · `executable?(String)` · `exist?(String)` · `expand_path(String, [String])` · `extname(String)` · `file?(String)` · `ftype(String)` · `identical?(String, String)` · `join(*String|Array)` · `link(String, String)` · `mtime(String)` · `open(String, [String], [Integer]) [{ }]` · `read(String)` · `readable?(String)` · `readlines(String)` · `readlink(String)` · `realpath(String, [String])` · `rename(String, String)` · `size(String)` · `split(String)` · `symlink(String, String)` · `symlink?(String)` · `unlink(String, *String)` · `utime(Time|Nil, Time|Nil, *String)` · `writable?(String)` · `write(String, String)` · `zero?(String)` ### Float `!=(x, Any)` · `%(x, Any)` · `*(x, Any)` · `**(x, Any)` · `+(x, Any)` · `-(x, Any)` · `/(x, Any)` · `<(x, Any)` · `<=(x, Any)` · `<=>(x, Any)` · `==(x, Any)` · `>(x, Any)` · `>=(x, Any)` · `EPSILON()` · `INFINITY()` · `MAX()` · `MIN()` · `NAN()` · `abs(x)` · `angle(x)` · `arg(x)` · `between?(x, Float, Float)` · `ceil(x)` · `clamp(x, Float, Float)` · `denominator(x)` · `divmod(x, Any)` · `fdiv(x, Integer|Float|Rational)` · `finite?(x)` · `floor(x)` · `infinite?(x)` · `magnitude(x)` · `modulo(x, Integer|Float|Rational)` · `nan?(x)` · `negative?(x)` · `Float[*Any]` · `next_float(x)` · `numerator(x)` · `phase(x)` · `positive?(x)` · `prev_float(x)` · `quo(x, Integer|Float|Rational)` · `rationalize(x)` · `round(x, [Integer], [half: Symbol])` · `to_f(x)` · `to_i(x)` · `to_int(x)` · `to_r(x)` · `to_s(x)` · `truncate(x)` · `zero?(x)` ### Hash `!=(x, Any)` · `==(x, Any)` · `[](x, Any)` · `[]=(x, Any, Any)` · `all?(x) { }` · `any?(x) { }` · `assoc(x, Any)` · `clear(x)` · `compact(x)` · `compact!(x)` · `count(x) [{ }]` · `default(x)` · `delete(x, Any)` · `delete_if(x) { }` · `detect(x) { }` · `dig(x, Any, *Any)` · `drop(x, Integer)` · `dup(x)` · `each(x) { }` · `each_key(x) { }` · `each_pair(x) { }` · `each_value(x) { }` · `each_with_object(x, Any) { }` · `empty?(x)` · `except(x, *Any)` · `fetch(x, Any, [Any])` · `fetch_values(x, *Any)` · `filter(x) { }` · `filter!(x) { }` · `filter_map(x) { }` · `find(x) { }` · `first(x)` · `flat_map(x) { }` · `flatten(x)` · `group_by(x) { }` · `has_key?(x, Any)` · `has_value?(x, Any)` · `include?(x, Any)` · `inject(x, Any) { }` · `invert(x)` · `keep_if(x) { }` · `key(x, Any)` · `key?(x, Any)` · `keys(x)` · `length(x)` · `map(x) { }` · `max_by(x) { }` · `member?(x, Any)` · `merge(x, Hash)` · `merge!(x, Hash)` · `min_by(x) { }` · `new([Any])` · `Hash[*Any]` · `none?(x) { }` · `of(*Any)` · `one?(x) { }` · `partition(x) { }` · `rassoc(x, Any)` · `reduce(x, Any) { }` · `reject(x) { }` · `reject!(x) { }` · `replace(x, Hash)` · `select(x) { }` · `select!(x) { }` · `set_default(x, Any)` · `shift(x)` · `size(x)` · `slice(x, *Any)` · `sort_by(x) { }` · `store(x, Any, Any)` · `sum(x, [Integer|Float|Rational|Complex]) { }` · `take(x, Integer)` · `to_a(x)` · `to_h(x)` · `transform_keys(x) { }` · `transform_keys!(x) { }` · `transform_values(x) { }` · `transform_values!(x) { }` · `update(x, Hash)` · `value?(x, Any)` · `values(x)` · `values_at(x, *Any)` ### IO `!=(x, Any)` · `==(x, Any)` · `close(x)` · `closed?(x)` · `each_line(x) { }` · `eof?(x)` · `flush(x)` · `getc(x)` · `getch(x)` · `gets(x)` · `noecho(x) { }` · `pos(x)` · `print(x, *Any)` · `puts(x, *Any)` · `raw(x) { }` · `read(x, [Integer])` · `readlines(x)` · `rewind(x)` · `seek(x, Integer, [Integer|Symbol])` · `size(x)` · `stderr()` · `stdin()` · `stdout()` · `truncate(x, Integer)` · `tty?(x)` · `winsize(x)` · `write(x, String)` ### Integer `!=(x, Any)` · `%(x, Any)` · `&(x, Any)` · `*(x, Any)` · `**(x, Any)` · `+(x, Any)` · `-(x, Any)` · `/(x, Any)` · `<(x, Any)` · `<<(x, Any)` · `<=(x, Any)` · `<=>(x, Any)` · `==(x, Any)` · `>(x, Any)` · `>=(x, Any)` · `>>(x, Any)` · `^(x, Any)` · `abs(x)` · `allbits?(x, Integer)` · `anybits?(x, Integer)` · `between?(x, Integer, Integer)` · `bit_length(x)` · `ceil(x, [Integer])` · `ceildiv(x, Integer)` · `chr(x)` · `clamp(x, Integer, Integer)` · `denominator(x)` · `digits(x)` · `div(x, Integer|Float|Rational)` · `divmod(x, Integer)` · `downto(x, Integer) { }` · `even?(x)` · `fdiv(x, Integer)` · `floor(x, [Integer])` · `gcd(x, Integer)` · `gcdlcm(x, Integer)` · `integer?(x)` · `lcm(x, Integer)` · `magnitude(x)` · `modulo(x, Integer)` · `negative?(x)` · `Integer[*Any]` · `next(x)` · `nobits?(x, Integer)` · `numerator(x)` · `odd?(x)` · `ord(x)` · `positive?(x)` · `pow(x, Integer, [Integer])` · `pred(x)` · `rationalize(x, [Integer|Float|Rational])` · `remainder(x, Integer)` · `round(x, [Integer])` · `size(x)` · `sqrt(x)` · `step(x, Integer, Integer) { }` · `succ(x)` · `times(x) { }` · `to_f(x)` · `to_i(x)` · `to_int(x)` · `to_r(x)` · `to_s(x, [Integer])` · `truncate(x, [Integer])` · `upto(x, Integer) { }` · `zero?(x)` · `|(x, Any)` ### Kernel `ARGV()` · `Complex(Integer|Float|Rational, [Integer|Float|Rational])` · `Float(String|Integer|Float)` · `Integer(String|Integer|Float)` · `PROGRAM_NAME()` · `Rational(Integer|Float|Rational|String, [Integer|Rational])` · `at_exit() { }` · `block_given?()` · `dup(Any)` · `equal?(Any, Any)` · `exit([Integer|Boolean])` · `format(String, *Any)` · `gets()` · `inspect(Any)` · `loop() { }` · `Kernel[*Any]` · `once() { }` · `p(*Any)` · `pp(Any)` · `print(*Any)` · `puts(*Any)` · `rand([Integer|Float])` · `sleep([Integer|Float|Rational])` · `sprintf(String, *Any)` · `srand([Integer])` · `system(String, *String)` · `to_s(Any)` · `warn(*Any)` ### MatchData `[](x, Any)` · `begin(x, Integer)` · `bytebegin(x, Integer)` · `byteend(x, Integer)` · `byteoffset(x, Integer)` · `captures(x)` · `end(x, Integer)` · `length(x)` · `match(x, Integer)` · `match_length(x, Integer)` · `named_captures(x)` · `names(x)` · `offset(x, Integer)` · `post_match(x)` · `pre_match(x)` · `regexp(x)` · `size(x)` · `string(x)` · `to_a(x)` · `to_s(x)` · `values_at(x, *Integer)` ### Math `E()` · `PI()` · `acos(Integer|Float|Rational)` · `acosh(Integer|Float|Rational)` · `asin(Integer|Float|Rational)` · `asinh(Integer|Float|Rational)` · `atan(Integer|Float|Rational)` · `atan2(Integer|Float, Integer|Float)` · `atanh(Integer|Float|Rational)` · `cbrt(Integer|Float|Rational)` · `cos(Integer|Float|Rational)` · `cosh(Integer|Float|Rational)` · `erf(Integer|Float|Rational)` · `erfc(Integer|Float|Rational)` · `exp(Integer|Float|Rational)` · `frexp(Integer|Float|Rational)` · `gamma(Integer|Float|Rational)` · `hypot(Integer|Float, Integer|Float)` · `ldexp(Integer|Float|Rational, Integer)` · `lgamma(Integer|Float|Rational)` · `log(Integer|Float|Rational, [Integer|Float])` · `log10(Integer|Float|Rational)` · `log2(Integer|Float|Rational)` · `sin(Integer|Float|Rational)` · `sinh(Integer|Float|Rational)` · `sqrt(Integer|Float|Rational)` · `tan(Integer|Float|Rational)` · `tanh(Integer|Float|Rational)` ### Mutex `!=(x, Any)` · `==(x, Any)` · `lock(x)` · `locked?(x)` · `new()` · `owned?(x)` · `synchronize(x) { }` · `try_lock(x)` · `unlock(x)` ### Open3 `capture2(String, *String)` · `capture2e(String, *String)` · `capture3(String, *String)` ### Process `CLOCK_MONOTONIC()` · `CLOCK_PROCESS_CPUTIME_ID()` · `CLOCK_REALTIME()` · `clock_gettime(Integer, [Symbol])` · `pid()` ### Queue `!=(x, Any)` · `==(x, Any)` · `close(x)` · `closed?(x)` · `empty?(x)` · `new()` · `pop(x, [Integer|Float|Rational])` · `push(x, Any)` · `size(x)` ### Range `!=(x, Any)` · `==(x, Any)` · `all?(x) { }` · `any?(x) { }` · `begin(x)` · `bsearch(x) { }` · `chunk_while(x) { }` · `collect(x) { }` · `collect_concat(x) { }` · `compact(x)` · `count(x) [{ }]` · `cover?(x, Any)` · `cycle(x, Integer) { }` · `detect(x) { }` · `drop(x, Integer)` · `drop_while(x) { }` · `each(x) { }` · `each_cons(x, Integer) { }` · `each_entry(x) { }` · `each_slice(x, Integer) { }` · `each_with_index(x) { }` · `each_with_object(x, Any) { }` · `end(x)` · `entries(x)` · `exclude_end?(x)` · `filter(x) { }` · `filter_map(x) { }` · `find(x) { }` · `find_all(x) { }` · `find_index(x) { }` · `first(x, [Integer])` · `flat_map(x) { }` · `group_by(x) { }` · `include?(x, Any)` · `inject(x, Any) { }` · `last(x, [Integer])` · `map(x) { }` · `max(x)` · `max_by(x) { }` · `member?(x, Any)` · `min(x)` · `min_by(x) { }` · `minmax(x)` · `minmax_by(x) { }` · `none?(x) { }` · `one?(x) { }` · `overlap?(x, Range)` · `partition(x) { }` · `reduce(x, Any) { }` · `reject(x) { }` · `reverse_each(x) { }` · `select(x) { }` · `size(x)` · `slice_after(x) { }` · `slice_before(x) { }` · `slice_when(x) { }` · `sort(x)` · `sort_by(x) { }` · `step(x, Integer) { }` · `sum(x, [Integer|Float|Rational|Complex]) [{ }]` · `take(x, Integer)` · `take_while(x) { }` · `tally(x)` · `to_a(x)` · `to_set(x)` · `uniq(x)` · `zip(x, *Array)` ### Rational `!=(x, Any)` · `%(x, Any)` · `*(x, Any)` · `**(x, Any)` · `+(x, Any)` · `-(x, Any)` · `/(x, Any)` · `<(x, Any)` · `<=(x, Any)` · `<=>(x, Any)` · `==(x, Any)` · `>(x, Any)` · `>=(x, Any)` · `abs(x)` · `ceil(x)` · `denominator(x)` · `fdiv(x, Integer|Float|Rational)` · `floor(x)` · `magnitude(x)` · `negative?(x)` · `Rational[*Any]` · `numerator(x)` · `positive?(x)` · `quo(x, Integer|Rational)` · `rationalize(x, [Rational])` · `round(x)` · `to_f(x)` · `to_i(x)` · `to_r(x)` · `to_s(x)` · `truncate(x)` · `zero?(x)` ### Record `keys(Any)` · `to_h(Any)` · `values(Any)` ### Regexp `!=(x, Any)` · `==(x, Any)` · `=~(x, Any)` · `casefold?(x)` · `encoding(x)` · `escape(String)` · `fixed_encoding?(x)` · `match(x, String, [Integer])` · `match?(x, String, [Integer])` · `named_captures(x)` · `names(x)` · `new(String, [String])` · `options(x)` · `source(x)` · `timeout(x)` · `union(*String|Regexp|Array)` ### Set `!=(x, Any)` · `&(x, Any)` · `-(x, Any)` · `==(x, Any)` · `add(x, Any)` · `add?(x, Any)` · `all?(x) { }` · `any?(x) { }` · `chunk_while(x) { }` · `classify(x) { }` · `clear(x)` · `collect(x) { }` · `collect!(x) { }` · `collect_concat(x) { }` · `compact(x)` · `count(x) [{ }]` · `cycle(x, Integer) { }` · `delete(x, Any)` · `delete?(x, Any)` · `delete_if(x) { }` · `detect(x) { }` · `difference(x, Set)` · `disjoint?(x, Set)` · `drop(x, Integer)` · `drop_while(x) { }` · `each(x) { }` · `each_cons(x, Integer) { }` · `each_entry(x) { }` · `each_slice(x, Integer) { }` · `each_with_index(x) { }` · `each_with_object(x, Any) { }` · `empty?(x)` · `entries(x)` · `filter(x) { }` · `filter!(x) { }` · `filter_map(x) { }` · `find(x) { }` · `find_all(x) { }` · `find_index(x) { }` · `first(x)` · `flat_map(x) { }` · `flatten(x)` · `group_by(x) { }` · `include?(x, Any)` · `inject(x, Any) { }` · `intersect?(x, Set)` · `intersection(x, Set)` · `join(x, [String])` · `keep_if(x) { }` · `length(x)` · `map(x) { }` · `map!(x) { }` · `max(x)` · `max_by(x) { }` · `member?(x, Any)` · `merge(x, Set)` · `min(x)` · `min_by(x) { }` · `minmax(x)` · `minmax_by(x) { }` · `new([Array])` · `Set[*Any]` · `none?(x) { }` · `of(*Any)` · `one?(x) { }` · `partition(x) { }` · `proper_subset?(x, Set)` · `proper_superset?(x, Set)` · `reduce(x, Any) { }` · `reject(x) { }` · `reject!(x) { }` · `replace(x, Set)` · `reverse_each(x) { }` · `select(x) { }` · `select!(x) { }` · `size(x)` · `slice_after(x) { }` · `slice_before(x) { }` · `slice_when(x) { }` · `sort(x)` · `sort_by(x) { }` · `subset?(x, Set)` · `subtract(x, Any)` · `sum(x, [Integer|Float|Rational|Complex])` · `superset?(x, Set)` · `take(x, Integer)` · `take_while(x) { }` · `tally(x)` · `to_a(x)` · `to_set(x)` · `union(x, Set)` · `uniq(x)` · `zip(x, *Array)` · `|(x, Any)` ### Socket `!=(x, Any)` · `==(x, Any)` · `close(x)` · `close_write(x)` · `connect(String, Integer, [Integer|Float|Rational])` · `connect_ssl(String, Integer, [Integer|Float|Rational])` · `gets(x)` · `read(x, Integer)` · `set_timeout(x, Integer|Float|Rational|Nil)` · `write(x, String)` ### String `!=(x, Any)` · `!~(x, Any)` · `%(x, Any)` · `*(x, Integer)` · `+(x, Any)` · `<(x, Any)` · `<=(x, Any)` · `<=>(x, Any)` · `==(x, Any)` · `=~(x, Any)` · `>(x, Any)` · `>=(x, Any)` · `[](x, Any, [Integer])` · `append_as_bytes(x, *String|Integer)` · `ascii_only?(x)` · `b(x)` · `between?(x, String, String)` · `byteindex(x, String|Regexp, [Integer])` · `byterindex(x, String|Regexp, [Integer])` · `bytes(x)` · `bytesize(x)` · `byteslice(x, Integer|Range, [Integer])` · `bytesplice(x, Integer, Integer, String)` · `capitalize(x)` · `capitalize!(x)` · `casecmp(x, String)` · `casecmp?(x, String)` · `center(x, Integer, [String])` · `chars(x)` · `chomp(x, [String])` · `chomp!(x, [String])` · `chop(x)` · `chop!(x)` · `chr(x)` · `clamp(x, String, String)` · `clear(x)` · `codepoints(x)` · `concat(x, *String|Integer)` · `count(x, String)` · `crypt(x, String)` · `delete(x, String, *String)` · `delete!(x, String, *String)` · `delete_prefix(x, String)` · `delete_prefix!(x, String)` · `delete_suffix(x, String)` · `delete_suffix!(x, String)` · `downcase(x)` · `downcase!(x)` · `dump(x)` · `each_byte(x) { }` · `each_char(x) { }` · `each_codepoint(x) { }` · `each_grapheme_cluster(x) { }` · `each_line(x) { }` · `empty?(x)` · `encode(x, String, [String])` · `encoding(x)` · `end_with?(x, String)` · `force_encoding(x, String)` · `getbyte(x, Integer)` · `grapheme_clusters(x)` · `gsub(x, String|Regexp, [String|Hash]) [{ }]` · `gsub!(x, String|Regexp, [String|Hash]) [{ }]` · `hex(x)` · `include?(x, String)` · `index(x, String|Regexp, [Integer])` · `insert(x, Integer, String)` · `intern(x)` · `length(x)` · `lines(x)` · `ljust(x, Integer, [String])` · `lstrip(x)` · `lstrip!(x)` · `match(x, String|Regexp, [Integer])` · `match?(x, String|Regexp, [Integer])` · `String[*Any]` · `next(x)` · `next!(x)` · `oct(x)` · `ord(x)` · `partition(x, String|Regexp)` · `prepend(x, *String)` · `replace(x, String)` · `reverse(x)` · `reverse!(x)` · `rindex(x, String|Regexp, [Integer])` · `rjust(x, Integer, [String])` · `rpartition(x, String|Regexp)` · `rstrip(x)` · `rstrip!(x)` · `scan(x, String|Regexp)` · `scrub(x, [String])` · `scrub!(x, [String])` · `setbyte(x, Integer, Integer)` · `size(x)` · `slice(x, Integer|Range|String|Regexp, [Integer])` · `slice!(x, Integer|Range|String|Regexp, [Integer])` · `split(x, [String|Regexp], [Integer])` · `squeeze(x, *String)` · `squeeze!(x, *String)` · `start_with?(x, String)` · `strip(x)` · `strip!(x)` · `sub(x, String|Regexp, [String|Hash]) [{ }]` · `sub!(x, String|Regexp, [String|Hash]) [{ }]` · `succ(x)` · `succ!(x)` · `sum(x, [Integer])` · `swapcase(x)` · `swapcase!(x)` · `to_c(x)` · `to_f(x)` · `to_i(x, [Integer])` · `to_r(x)` · `to_s(x)` · `to_sym(x)` · `tr(x, String, String)` · `tr!(x, String, String)` · `tr_s(x, String, String)` · `tr_s!(x, String, String)` · `undump(x)` · `unicode_normalize(x, [Symbol])` · `unicode_normalize!(x, [Symbol])` · `unicode_normalized?(x, [Symbol])` · `unpack(x, String)` · `unpack1(x, String)` · `upcase(x)` · `upcase!(x)` · `upto(x, String) { }` · `valid_encoding?(x)` ### Symbol `!=(x, Any)` · `<(x, Any)` · `<=(x, Any)` · `<=>(x, Any)` · `==(x, Any)` · `>(x, Any)` · `>=(x, Any)` · `capitalize(x)` · `casecmp(x, Symbol)` · `casecmp?(x, Symbol)` · `downcase(x)` · `empty?(x)` · `encoding(x)` · `end_with?(x, String)` · `id2name(x)` · `intern(x)` · `length(x)` · `match(x, Regexp|String)` · `match?(x, Regexp|String)` · `name(x)` · `Symbol[*Any]` · `next(x)` · `size(x)` · `slice(x, Integer, [Integer])` · `start_with?(x, String)` · `succ(x)` · `swapcase(x)` · `to_s(x)` · `to_sym(x)` · `upcase(x)` ### TCPServer `!=(x, Any)` · `==(x, Any)` · `accept(x)` · `close(x)` · `new(String, Integer)` · `port(x)` ### Thread `!=(x, Any)` · `==(x, Any)` · `alive?(x)` · `current()` · `join(x, [Integer|Float|Rational])` · `kill(x)` · `new() { }` · `raise(x, String)` · `value(x)` ### Time `!=(x, Any)` · `+(x, Any)` · `-(x, Any)` · `<(x, Any)` · `<=(x, Any)` · `<=>(x, Any)` · `==(x, Any)` · `>(x, Any)` · `>=(x, Any)` · `asctime(x)` · `at(Integer|Float|Rational|Time, [in: String|Integer])` · `ceil(x, [Integer])` · `ctime(x)` · `day(x)` · `dst?(x)` · `floor(x, [Integer])` · `friday?(x)` · `getgm(x)` · `getlocal(x, [String|Integer])` · `getutc(x)` · `gm(Integer, [Integer], [Integer], [Integer], [Integer], [Integer|Float|Rational])` · `gmt?(x)` · `gmt_offset(x)` · `gmtime(x)` · `gmtoff(x)` · `hour(x)` · `isdst(x)` · `iso8601(x, [Integer])` · `localtime(x, [String|Integer])` · `mday(x)` · `min(x)` · `mon(x)` · `monday?(x)` · `month(x)` · `new(Integer, [Integer], [Integer], [Integer], [Integer], [Integer|Float|Rational], [String|Integer], [in: String|Integer])` · `now([in: String|Integer])` · `nsec(x)` · `round(x, [Integer])` · `saturday?(x)` · `sec(x)` · `strftime(x, String)` · `subsec(x)` · `sunday?(x)` · `thursday?(x)` · `to_a(x)` · `to_f(x)` · `to_i(x)` · `to_r(x)` · `to_s(x)` · `tuesday?(x)` · `tv_nsec(x)` · `tv_sec(x)` · `tv_usec(x)` · `usec(x)` · `utc(Time|Integer, [Integer], [Integer], [Integer], [Integer], [Integer|Float|Rational])` · `utc?(x)` · `utc_offset(x)` · `wday(x)` · `wednesday?(x)` · `yday(x)` · `year(x)` · `zone(x)` ### Tuple `!=(x, Any)` · `<(x, Any)` · `<=(x, Any)` · `<=>(x, Any)` · `==(x, Any)` · `>(x, Any)` · `>=(x, Any)` · `[](x, Any)` · `[]=(x, Any, Any)` · `length(x)` · `max(x)` · `min(x)` · `minmax(x)` · `Tuple[*Any]` · `size(x)` · `to_a(x)` ### Zlib `deflate(String)` · `gunzip(String)` · `gzip(String)` · `inflate(String)` ### Exception types `RuntimeError` · `ArgumentError` · `KeyError` · `IndexError` · `ZeroDivisionError` · `RangeError` · `IOError` · `EncodingError` · `RegexpError` · `FloatDomainError` · `NoMatchingPatternError` · `TypeError` · `EOFError` · `ThreadError`: each has `T.new(message)`, `T.message(x)`, `T.set_message(x, v)`; `Exception.message(e)` reads any. Only in `rescue`: `Math::DomainError`.