Files
Yukihiro "Matz" Matsumoto 143959b94b doc: fix prettier formatting in markdown files
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-12 14:33:37 +09:00

431 lines
13 KiB
Markdown

<!-- summary: mruby Language Features and Ruby Compatibility -->
# mruby Language Features
This guide describes the Ruby language features supported by mruby 4.0.
mruby implements a subset of the Ruby language, optimized for embedded use.
For a list of specific behavioral differences, see
[limitations.md](../limitations.md).
**If you are coming from CRuby**, note these major differences upfront:
- No `require` or `load` — all code is linked at build time
- No `defined?` keyword — use `respond_to?`, `const_defined?`, etc.
- No refinements (`refine`, `using`)
- No `Encoding` class — UTF-8 opt-in via `MRB_UTF8_STRING`
- Fibers cannot yield across C function boundaries
- Integer size varies by platform and boxing mode
- Operators cannot be overridden by user code
See [Key Differences from CRuby](#key-differences-from-cruby) for
the full list.
## Syntax
### Keywords
mruby supports the following keywords:
`BEGIN`, `END`, `alias`, `and`, `begin`, `break`, `case`, `class`,
`def`, `do`, `else`, `elsif`, `end`, `ensure`, `false`, `for`, `if`,
`in`, `module`, `next`, `nil`, `not`, `or`, `redo`, `rescue`,
`retry`, `return`, `self`, `super`, `then`, `true`, `undef`,
`unless`, `until`, `when`, `while`, `yield`
Magic variables: `__FILE__`, `__LINE__`, `__ENCODING__`, `__method__`
**Not supported:** `defined?` (use `respond_to?`, `const_defined?`,
etc. instead), `refinements` (`using`, `refine`).
### Classes and Modules
```ruby
class Animal
attr_accessor :name
def initialize(name)
@name = name
end
def speak
"..."
end
end
class Dog < Animal
def speak
"Woof!"
end
end
module Greetable
def greet
"Hello, I'm #{name}"
end
end
class Dog
include Greetable
end
```
All standard class and module features are supported: inheritance,
`include`, `prepend`, `extend`, `attr_reader`/`attr_writer`/
`attr_accessor`, `public`/`private`/`protected` visibility, class
variables (`@@var`), class methods, and `super`.
### Methods
```ruby
# Required, optional, rest, post-rest, keyword, and block arguments
def example(a, b = 1, *rest, last, key:, opt_key: nil, **kwargs, &block)
end
# Endless method definition
def double(x) = x * 2
```
### Blocks and Procs
```ruby
[1, 2, 3].each { |n| puts n }
[1, 2, 3].each do |n|
puts n
end
square = Proc.new { |x| x * x }
square = proc { |x| x * x }
double = lambda { |x| x * 2 }
double = ->(x) { x * 2 }
```
### Control Flow
```ruby
# if/unless (both statement and modifier forms)
if condition
# ...
elsif other
# ...
else
# ...
end
result = value if condition
result = value unless condition
# case/when
case obj
when String then "string"
when Integer then "integer"
else "other"
end
# Loops
while condition
# ...
end
until condition
# ...
end
for item in collection
# ...
end
# Loop control
break # exit loop
next # skip to next iteration
redo # restart current iteration
retry # restart begin/rescue block
```
### Exception Handling
```ruby
begin
risky_operation
rescue ArgumentError => e
handle_arg_error(e)
rescue StandardError => e
handle_error(e)
ensure
cleanup
end
raise "something went wrong"
raise ArgumentError, "bad argument"
```
**Note:** `raise` without arguments in a `rescue` clause does not
re-raise the current exception. Capture and re-raise explicitly:
```ruby
begin
risky_operation
rescue => e
log(e)
raise e # explicit re-raise required
end
```
### Strings
```ruby
"double-quoted with #{interpolation}"
'single-quoted literal'
heredoc = <<~HEREDOC
indented heredoc
with #{interpolation}
HEREDOC
```
### Regular Expressions
Regular expressions require an external gem such as `mruby-regexp-pcre`
or `mruby-onig-regexp`. Without a regexp gem, `Regexp` literals
(`/pattern/`) are not available.
### Pattern Matching (Limited)
Only rightward assignment with simple variable binding is supported:
```ruby
expr => var # assigns expr to var
```
`case/in` syntax, array/hash patterns, guard clauses, pin operator,
find patterns, and alternative patterns are **not** supported.
## Numeric Types
mruby's numeric type sizes depend on the boxing mode and platform.
### Integer
| Configuration | Range |
| -------------------------------------- | ---------------- |
| 64-bit word boxing (default on 64-bit) | roughly +/- 2^62 |
| 32-bit word boxing (default on 32-bit) | roughly +/- 2^30 |
| NaN boxing (64-bit only) | -2^31 to 2^31-1 |
Integer overflow raises a `RangeError` unless the `mruby-bigint` gem
is included, in which case integers automatically promote to
arbitrary precision.
### Float
By default, `Float` uses 64-bit `double`. Compile-time options:
- `MRB_USE_FLOAT32`: use 32-bit `float` instead
- `MRB_NO_FLOAT`: disable floating-point entirely
With word boxing on 64-bit, many float values are stored inline
(without heap allocation) using a rotation encoding.
### Additional Numeric Types (via gems)
- **Rational** (`mruby-rational`): exact rational arithmetic
- **Complex** (`mruby-complex`): complex number support
- **Bigint** (`mruby-bigint`): arbitrary-precision integers
## Core Classes
These classes are always available in mruby (no gem required):
| Class | Notes |
| ------------- | -------------------------------------- |
| Object | Base class for all objects |
| Module | Module definition and mixin |
| Class | Class definition and instantiation |
| NilClass | Singleton `nil` |
| TrueClass | Singleton `true` |
| FalseClass | Singleton `false` |
| Integer | Fixed-precision integer |
| Float | Floating-point (unless `MRB_NO_FLOAT`) |
| Symbol | Interned identifier |
| String | Mutable byte string |
| Array | Ordered collection |
| Hash | Key-value mapping |
| Range | Interval representation |
| Proc | Closure / callable object |
| Exception | Exception hierarchy root |
| StandardError | Common error base |
### Core Modules
| Module | Notes |
| ---------- | ----------------------------------------- |
| Kernel | Core methods (`puts`, `p`, `raise`, etc.) |
| Comparable | Comparison operators via `<=>` |
| Enumerable | Collection iteration methods |
## Standard Library (via gemboxes)
mruby's standard library is organized into gemboxes. The `default`
gembox includes all of the below. Use this table to find which
gembox provides the class or feature you need:
### Classes and Modules
| Class/Module | Gembox | Gem |
| --------------------- | ---------- | ----------------- |
| Fiber | stdlib | mruby-fiber |
| Enumerator | stdlib | mruby-enumerator |
| Enumerator::Lazy | stdlib | mruby-enum-lazy |
| Set | stdlib | mruby-set |
| ObjectSpace | stdlib | mruby-objectspace |
| Time | stdlib-ext | mruby-time |
| Struct | stdlib-ext | mruby-struct |
| Data | stdlib-ext | mruby-data |
| Random | stdlib-ext | mruby-random |
| IO, File | stdlib-io | mruby-io |
| Socket | stdlib-io | mruby-socket |
| Dir | stdlib-io | mruby-dir |
| Errno | stdlib-io | mruby-errno |
| Math | math | mruby-math |
| Rational | math | mruby-rational |
| Complex | math | mruby-complex |
| Bigint | math | mruby-bigint |
| Method, UnboundMethod | metaprog | mruby-method |
### Methods and Features
| Feature | Gembox | Gem |
| ----------------------------- | ---------- | ------------------ |
| `catch`/`throw` | stdlib | mruby-catch |
| `Kernel#sprintf`, `String#%` | stdlib-ext | mruby-sprintf |
| `Array#pack`, `String#unpack` | stdlib-ext | mruby-pack |
| `Kernel#rand` | stdlib-ext | mruby-random |
| `Kernel#eval` | metaprog | mruby-eval |
| `Kernel#binding` | metaprog | mruby-binding |
| `Proc#binding` | metaprog | mruby-proc-binding |
| Runtime compiler | metaprog | mruby-compiler |
### Core Class Extensions
The `stdlib` gembox also extends built-in classes with additional
methods. These are included by default:
| Extension | Examples |
| ----------------------- | ---------------------------------------------- |
| Array extensions | `#dig`, `#union`, `#difference` |
| Hash extensions | `#dig`, `#transform_keys`, `#transform_values` |
| String extensions | `#encode`, `#bytes`, `#chars` |
| Numeric extensions | `Integer#digits`, `Integer#pow` |
| Comparable extensions | `#clamp` |
| Enumerable extensions | `#sort_by`, `#min_by`, `#max_by`, `#tally` |
| Range extensions | `#size`, `#cover?` |
| Proc extensions | `#<<`, `#>>` (composition) |
| Symbol extensions | `#to_proc` |
| Object extensions | `#then`, `#yield_self` |
| Kernel extensions | `#__method__` |
| Class/Module extensions | `Module#name` |
### Gembox Summary
| Gembox | Contents | Notes |
| ------------ | --------------------------------------------- | -------------------------------------------- |
| `stdlib` | Core class extensions, Fiber, Enumerator, Set | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` |
| `stdlib-ext` | Time, Struct, Data, Random, sprintf, pack | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` |
| `stdlib-io` | IO, File, Dir, Socket, Errno | Requires stdio |
| `math` | Math, Rational, Complex, Bigint | Works with `MRB_NO_STDIO` |
| `metaprog` | eval, binding, Method, compiler | Works with `MRB_NO_STDIO` and `MRB_NO_FLOAT` |
| `default` | All of the above + CLI tools | Full installation |
## Key Differences from CRuby
### No Runtime Loading
mruby has no `require` or `load`. All code (gems, libraries) is
linked at build time. To add functionality, include the appropriate
gem in your build configuration:
```ruby
MRuby::Build.new do |conf|
conf.gem :core => "mruby-time"
end
```
### No `defined?` Keyword
The `defined?` keyword raises `NameError` instead of returning a
type string or `nil`. Use alternatives:
```ruby
# Instead of: defined?(Foo)
Object.const_defined?(:Foo)
# Instead of: defined?(@var)
instance_variable_defined?(:@var)
# Instead of: defined?(method_name)
respond_to?(:method_name)
```
### Fiber Limitations
Fibers cannot cross C function boundaries. You cannot yield from a
fiber inside a C-implemented method. Only `mrb_fiber_yield` at
function return is supported.
### Array and String Subclasses
`Array` and `String` do not support instance variables to reduce memory.
This means subclassing `Array` or `String` and adding `@fields` will raise an error.
### Operator Overriding
Operators of primitive classes cannot be overridden by user code.
Redefining `String#+` has no effect on the behavior of the `+` operator.
### Module Loading Hooks
`include`/`prepend`/`extend` do not call `append_features`/
`prepend_features`/`extend_object` hooks. The module is included
directly.
### Small Hash Optimization
For small hashes, `#hash` is not called on keys. Custom `#hash`
methods may not execute for small hash tables.
### No Refinements
Module refinements (`refine`, `using`) are not supported.
### No Encoding Class
There is no `Encoding` class. String encoding is either pure bytes
or UTF-8 (opt-in via `MRB_UTF8_STRING` compile flag).
### `nil?` in Conditionals
Redefining `nil?` has no effect on conditional expressions.
The VM uses direct nil checks for performance.
### Integer Precision
Integer size varies by boxing mode (see [Numeric Types](#numeric-types)
above). Code relying on 64-bit integer precision may behave
differently on 32-bit or NaN boxing configurations.
## Build-Time Configuration
Key compile-time macros that affect language behavior:
| Macro | Effect |
| -------------------- | ---------------------------------- |
| `MRB_NO_FLOAT` | Remove all float support |
| `MRB_USE_FLOAT32` | Use 32-bit float instead of double |
| `MRB_UTF8_STRING` | Enable UTF-8 string handling |
| `MRB_INT32` | Force 32-bit integer |
| `MRB_INT64` | Force 64-bit integer |
| `MRB_STR_LENGTH_MAX` | Max string length (default 1MB) |
| `MRB_ARY_LENGTH_MAX` | Max array length (default 2^17) |
See [mrbconf.md](mrbconf.md) for the complete list of configuration
macros.