RbGateway
public final class RbGateway: RbObjectAccess, Sendable
Provides top-level Ruby services: information about the Ruby VM, evaluate expressions, access various kinds of Ruby objects, and define new Ruby classes, modules, and functions.
You cannot instantiate this type. Instead RubyGateway exports a public
instance Ruby
. Among other things this permits a dynamic member lookup
programming style.
The Ruby VM is initialized when the object is first accessed and is
automatically stopped when the process ends. The VM can be manually shut
down before process exit by calling RbGateway.cleanup()
but once this has
been done the VM cannot be restarted and subsequent calls to RubyGateway
services will fail.
The loadpath (where require
looks) is set to the lib/ruby
directories
adjacent to the libruby
the program is linked against and $RUBYLIB
.
RubyGems are enabled.
Accessing Ruby objects
The class inherits from RbObjectAccess
which lets you look up constants
or call functions as you would at the top level of a Ruby script, for example:
import RubyGateway
print("Ruby version is \(Ruby.version)")
do {
try Ruby.require(filename: "rouge")
let html = try Ruby.get("Rouge").call("highlight", args: ["let a = 1", "swift", "html"])
} catch {
}
If you just want to create a Ruby object of some class, see
RbObject.init(ofClass:args:kwArgs:)
.
Running Ruby code
Use RbGateway.eval(ruby:)
to evaulate a Ruby expression in the current VM.
For example:
let result = try Ruby.eval(ruby: "Rouge.highlight('let a = 1', 'swift', 'html')")
Defining new Ruby classes
Use RbGateway.defineClass(_:parent:under:)
and RbGateway.defineModule(_:under:)
to define new classes and modules. Then add methods using RbObject.defineMethod(...)
and RbObject.defineSingletonMethod(...)
.
Topics
func cleanup() -> Int32
func cleanup() -> Int32
Explicitly shut down Ruby and release resources.
This includes calling END{}
code and procs registered by Kernel.#at_exit
.
You generally don’t need to call this: it happens automatically as part of process exit.
Once called you cannot continue to use Ruby in this process: the VM cannot be re-setup.
Declaration
public func cleanup() -> Int32
Return Value
0 if the cleanup went fine, otherwise some error code from Ruby.
func getID(for: String) -> RbObject.VALUE
func getID(for: String) -> RbObject.VALUE
Get an ID
ready to call a method, for example.
This is public to permit interop with CRuby
. It is not
needed for regular RubyGateway use.
Declaration
public func getID(for name: String) throws -> RbObject.VALUE
Parameters
name |
Name to look up, typically constant or method name. |
Throws
RbError.rubyException(_:)
if Ruby raises an exception. This
probably means the ID
space is full, which is fairly unlikely.
Return Value
The corresponding ID.
func softSetup() -> Bool
func softSetup() -> Bool
Attempt to initialize Ruby but swallow any error.
This is for use from places that could be the first use of Ruby but it is not practical to throw an exception for API or aesthetic reasons.
The idea is that callers can get by long enough for the user to call
require()
or send()
which will properly report the VM setup error.
This is public to let you implement RbObjectConvertible.rubyObject
for
custom types. It is not required for regular RubyGateway use.
Declaration
public func softSetup() -> Bool
Top Self Instance Variables
func getInstanceVar(String) -> RbObject
func getInstanceVar(String) -> RbObject
Get the value of a top-level instance variable. Creates a new one with a nil
value if it doesn’t exist yet.
This is like doing @f
at the top level of a Ruby script.
For a version that does not throw, see RbObjectAccess.failable
.
Declaration
Parameters
name |
Name of IVar to get. Must begin with a single ‘@’. |
Throws
RbError.badIdentifier(type:id:)
if name
looks wrong.
RbError.rubyException(_:)
if Ruby has a problem.
Return Value
Value of the IVar or Ruby nil
if it has not been assigned yet.
func setInstanceVar(String, newValue: (any RbObjectConvertible)?) -> RbObject
func setInstanceVar(String, newValue: (any RbObjectConvertible)?) -> RbObject
Set a top-level instance variable. Creates a new one if it doesn’t exist yet.
This is like doing @f = 3
at the top level of a Ruby script.
For a version that does not throw, see RbObjectAccess.failable
.
Declaration
@discardableResult
public override func setInstanceVar(
_ name: String, newValue: (any RbObjectConvertible)?
) throws -> RbObject
Parameters
name |
Name of IVar to set. Must begin with a single ‘@’. |
newValue |
New value to set. |
Throws
RbError.badIdentifier(type:id:)
if name
looks wrong.
RbError.rubyException(_:)
if Ruby has a problem.
Return Value
The value that was set.
Defining New Classes and Modules
func defineClass(String, parent: RbObject?, under: RbObject?) -> RbObject
func defineClass(String, parent: RbObject?, under: RbObject?) -> RbObject
Define a new, empty, Ruby class.
Declaration
Parameters
name |
Name of the class. |
parent |
Parent class for the new class to inherit from. The default
is |
under |
The class or module under which to nest this new class. The
default is |
Throws
RbError.badIdentifier(type:id:)
if name
is bad. RbError.badType(...)
if
parent
is provided but is not a class, or if under
is neither class nor
module. RbError.rubyException(...)
if Ruby is unhappy with the definition,
for example when the class already exists with a different parent.
Return Value
The class object for the new class.
func defineClass<SwiftPeer>(String, under: RbObject?, initializer: () -> SwiftPeer) -> RbObject
func defineClass<SwiftPeer>(String, under: RbObject?, initializer: () -> SwiftPeer) -> RbObject
Define a new, empty, Ruby class associated with a Swift class.
The Ruby class inherits from the Ruby Data
Data
class.
When any new instance of the Ruby class is created, the initializer
closure
is called to get hold of an instance of the bound Swift class. Typically this closure
is an initializer for the Swift class. A strong reference is held to the Swift object
while the Ruby object is live; this reference is released only when the Ruby object is
garbage-collected.
If you want to implement the Ruby initialize
entrypoint to support passing arguments
to new
then you need to do that separately with one of the
RbObject.defineMethod(_:argsSpec:method:)
methods.
Ruby methods defined with RbObject.defineMethod(_:argsSpec:method:)
can be bound
directly to methods of the SwiftPeer
class.
Declaration
Parameters
name |
Name of the class. |
under |
The class or module under which to nest this new class. The
default is |
initializer |
Closure to return an instance of |
Throws
RbError.badIdentifier(type:id:)
if name
is bad. RbError.badType(...)
if
parent
is provided but is not a class, or if under
is neither class nor
module. RbError.rubyException(...)
if Ruby is unhappy with the definition,
for example when the class already exists with a different parent.
Return Value
The class object for the new class.
func defineModule(String, under: RbObject?) -> RbObject
func defineModule(String, under: RbObject?) -> RbObject
Define a new, empty, Ruby module.
For example to create a module Math::Advanced
:
let mathModule = try Ruby.get("Math")
let advancedMathModule = try Ruby.defineModule(name: "Advanced", under: mathModule)
Declaration
Parameters
name |
Name of the module. |
under |
The class or module under which to nest this new module. |
Throws
RbError.badIdentifier(type:id:)
if name
is bad. RbError.badType(...)
if under
is neither class nor module. RbError.rubyException(...)
if
Ruby is unhappy with the definition, for example when a non-module constant
already exists with this name.
Return Value
The module object for the new module.
VM Properties
var debug: Bool
var debug: Bool
enum Verbosity
enum Verbosity
Verbosity setting for Ruby scripts - affects Kernel#warn
etc.
Declaration
public enum Verbosity
var verbose: Verbosity
var verbose: Verbosity
Verbose mode for Ruby code, sets $VERBOSE
/ $-v
.
Declaration
public var verbose: Verbosity { get set }
var scriptName: String
var scriptName: String
var apiVersion: (Int32, Int32, Int32)
var apiVersion: (Int32, Int32, Int32)
var version: String
var version: String
The version number triple of Ruby being used, for example 2.5.0.
Declaration
public var version: String { get }
var versionDescription: String
var versionDescription: String
The full version string for the Ruby being used.
For example ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin17].
Declaration
public var versionDescription: String { get }
func setArguments([String])
func setArguments([String])
Ruby Code Execution
func eval(ruby: String) -> RbObject
func eval(ruby: String) -> RbObject
Evaluate some Ruby and return the result.
This is a lower level than Kernel#eval
and less flexible - if you
need that function then access it via RbGateway.call("eval")
.
Don’t be tempted by rb_eval_string_wrap()
, it is broken. #10466.
Declaration
Parameters
ruby |
Ruby code to execute at the top level. |
Throws
RbError
if something goes wrong.
Return Value
The result of executing the code.
func require(filename: String) -> Bool
func require(filename: String) -> Bool
Load a Ruby file once-only. See Kernel#require
, but note this
method is dispatched dynamically so it will invoke any replacements of
require
.
Declaration
Parameters
filename |
The name of the file to load. |
Throws
RbError
if something goes wrong. This usually means that Ruby
couldn’t find the file.
Return Value
true
if the file was loaded OK, false
if it is already loaded.
func load(filename: String, wrap: Bool)
func load(filename: String, wrap: Bool)
See Ruby Kernel#load
. Load a file, reloads if already loaded.
Declaration
Parameters
filename |
The name of the file to load |
wrap |
If |
Throws
RbError
if something goes wrong.
Swift Global Variables
func defineGlobalVar<T>(String, get: () -> T)
func defineGlobalVar<T>(String, get: () -> T)
Create a readonly Ruby global variable implemented by Swift code.
If your global variable is not a simple Swift value type then use RbObject
as the closure return type.
Declaration
public func defineGlobalVar<T: RbObjectConvertible>(
_ name: String,
get: @escaping @Sendable () -> T) throws
Parameters
name |
The name of the global variable. Must begin with |
get |
Function called whenever Ruby code reads the global variable. |
Throws
RbError.badIdentifier(type:id:)
if name
is bad; some other kind of error if Ruby is
not working.
func defineGlobalVar<T>(String, get: () -> T, set: (T) -> Void)
func defineGlobalVar<T>(String, get: () -> T, set: (T) -> Void)
Create a read-write Ruby global variable implemented by Swift code.
Errors thrown from the setter closure propagate into Ruby as exceptions. Ruby does not permit getters to raise exceptions.
If your global variable is not a simple Swift value type then use RbObject
as the
closure return/argument type; you can manually throw an RbException
from the setter
if the provided Ruby value is the wrong shape.
Declaration
public func defineGlobalVar<T: RbObjectConvertible>(
_ name: String,
get: @escaping @Sendable () -> T,
set: @escaping @Sendable (T) throws -> Void) throws
Parameters
name |
The name of the global variable. Must begin with |
get |
Function called whenever Ruby code reads the global variable. |
set |
Function called whenever Ruby code writes the global variable. |
Throws
RbError.badIdentifier(type:id:)
if name
is bad; some other kind of error if Ruby is
not working.
Swift Global Functions
func defineGlobalFunction(String, argsSpec: RbMethodArgsSpec, body: RbMethodCallback)
func defineGlobalFunction(String, argsSpec: RbMethodArgsSpec, body: RbMethodCallback)
Define a global function that can use positional, keyword, and optional arguments as well as splatting. The function can also be passed a block.
Use the RbMethod
passed into body
to access the function arguments;
RubyBridge validates the arguments according to argsSpec
before invoking
this callback.
The first parameter to the body
callback is best ignored: it is the Ruby
internal object that is used to implement so-called “global functions”.
Declaration
public func defineGlobalFunction(
_ name: String,
argsSpec: RbMethodArgsSpec = RbMethodArgsSpec(),
body: @escaping RbMethodCallback) throws
Parameters
name |
The function name. |
argsSpec |
A description of the arguments required by the function. The default for this parameter specifies a function that does not take any arguments. |
body |
The Swift code to run when the function is called. |
Throws
RbError.badIdentifier(type:id:)
if name
is bad.
Some other kind of RbError
if Ruby is not working.