Back to Mruby

mruby Language Features

doc/guides/language.md

4.0.013.3 KB
Original Source
<!-- 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.

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 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

ConfigurationRange
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):

ClassNotes
ObjectBase class for all objects
ModuleModule definition and mixin
ClassClass definition and instantiation
NilClassSingleton nil
TrueClassSingleton true
FalseClassSingleton false
IntegerFixed-precision integer
FloatFloating-point (unless MRB_NO_FLOAT)
SymbolInterned identifier
StringMutable byte string
ArrayOrdered collection
HashKey-value mapping
RangeInterval representation
ProcClosure / callable object
ExceptionException hierarchy root
StandardErrorCommon error base

Core Modules

ModuleNotes
KernelCore methods (puts, p, raise, etc.)
ComparableComparison operators via <=>
EnumerableCollection 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/ModuleGemboxGem
Fiberstdlibmruby-fiber
Enumeratorstdlibmruby-enumerator
Enumerator::Lazystdlibmruby-enum-lazy
Setstdlibmruby-set
ObjectSpacestdlibmruby-objectspace
Timestdlib-extmruby-time
Structstdlib-extmruby-struct
Datastdlib-extmruby-data
Randomstdlib-extmruby-random
IO, Filestdlib-iomruby-io
Socketstdlib-iomruby-socket
Dirstdlib-iomruby-dir
Errnostdlib-iomruby-errno
Mathmathmruby-math
Rationalmathmruby-rational
Complexmathmruby-complex
Bigintmathmruby-bigint
Method, UnboundMethodmetaprogmruby-method

Methods and Features

FeatureGemboxGem
catch/throwstdlibmruby-catch
Kernel#sprintf, String#%stdlib-extmruby-sprintf
Array#pack, String#unpackstdlib-extmruby-pack
Kernel#randstdlib-extmruby-random
Kernel#evalmetaprogmruby-eval
Kernel#bindingmetaprogmruby-binding
Proc#bindingmetaprogmruby-proc-binding
Runtime compilermetaprogmruby-compiler

Core Class Extensions

The stdlib gembox also extends built-in classes with additional methods. These are included by default:

ExtensionExamples
Array extensions#dig, #union, #difference
Hash extensions#dig, #transform_keys, #transform_values
String extensions#encode, #bytes, #chars
Numeric extensionsInteger#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 extensionsModule#name

Gembox Summary

GemboxContentsNotes
stdlibCore class extensions, Fiber, Enumerator, SetWorks with MRB_NO_STDIO and MRB_NO_FLOAT
stdlib-extTime, Struct, Data, Random, sprintf, packWorks with MRB_NO_STDIO and MRB_NO_FLOAT
stdlib-ioIO, File, Dir, Socket, ErrnoRequires stdio
mathMath, Rational, Complex, BigintWorks with MRB_NO_STDIO
metaprogeval, binding, Method, compilerWorks with MRB_NO_STDIO and MRB_NO_FLOAT
defaultAll of the above + CLI toolsFull 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 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:

MacroEffect
MRB_NO_FLOATRemove all float support
MRB_USE_FLOAT32Use 32-bit float instead of double
MRB_UTF8_STRINGEnable UTF-8 string handling
MRB_INT32Force 32-bit integer
MRB_INT64Force 64-bit integer
MRB_STR_LENGTH_MAXMax string length (default 1MB)
MRB_ARY_LENGTH_MAXMax array length (default 2^17)

See mrbconf.md for the complete list of configuration macros.