Latest 2.0.0
Homepage https://github.com/johnfairh/RubyGateway
License MIT
Platforms osx 10.13
Frameworks Foundation
Authors

CI
codecov
Carthage compatible
Pod
Platforms
License

Embed Ruby in Swift: load Gems, run Ruby scripts, get results.

RubyGateway is a framework built on the Ruby C API that lets Swift programs
running on macOS or Linux painlessly and safely run and interact with Ruby
programs. It’s easy to pass Swift datatypes into Ruby and turn Ruby objects
back into Swift types.

The current version of the framework entirely covers calling Ruby from Swift,
including passing Swift closures as blocks. The main
features to add cover
implementing Ruby classes and methods in Swift.

See CRuby if you are looking for a
low-level Ruby C API wrapper.

Examples

Services

Rouge is a code highlighter. In Ruby:

require 'rouge'
html = Rouge.highlight("let a = 3", "swift", "html")
puts(html)

In Swift 4.2 with similar [lack of] error checking:

import RubyGateway

try! Ruby.require(filename: "rouge")
let html = try! Ruby.get("Rouge").call("highlight", args: ["let a = 3", "swift", "html"])
print(html)

Or using dynamic member lookup:

import RubyGateway

try! Ruby.require(filename: "rouge")
let html = try! Ruby.Rouge!.call("highlight", args: ["let a = 3", "swift", "html"])
print(html)

Objects

// Create an object.  Use keyword arguments with initializer
let student = RbObject(ofClass: "Academy::Student", kwArgs: ["name": "barney"])!

// Acess an attribute
print("Name is (student.get("name"))")

// Fix their name by poking an ivar
try! student.setInstanceVar("@name", newValue: "Barney")

// Get a Swift version of `:reading`
let readingSubject = RbSymbol("reading")

// Call a method with mixed Swift data types
try! student.call("add_score", args: [readingSubject, 30])
try! student.call("add_score", args: [readingSubject, 35])

// Get a result as floating point
let avgScoreObj = try! student.call("mean_score_for_subject", args: [readingSubject])
let avgScore = Double(avgScoreObj)!
print("Mean score is (avgScore)")

// Pass Swift code as a block
let scores = student.all_scores!
scores.call("each") { args in
    print("Subject: (args[0]) Score: (args[1])")
    return .nilObject
}

// Convert to a Swift array
let subjects = Array<String>(student.all_subjects!)
subjectsPopularityDb.submit(subjects: subjects)

Dynamic data exchange

Global variables:

// epochStore.current: Int

Ruby.defineGlobalVariable(
        name: "$epoch",
        get: { epochStore.current },
        set: { epochStore.current = newEpoch })

Documentation

Requirements

  • Swift 4.2 or later, from swift.org or Xcode 10.0+
  • macOS (tested on 10.13.6) or Linux (tested on Ubuntu Bionic/18.04 on x86_64) with Clang 6.
  • Ruby 2.2 or later including development files:
    • For macOS, these come with Xcode.
    • For Linux you may need to install a -dev package depending on how your Ruby
      is installed.
    • RubyGateway requires ‘original’ MRI/CRuby Ruby – no JRuby/Rubinius/etc.

Installation

For macOS, if you are happy to use the system Ruby then you just need to include
the RubyGateway framework as a dependency. If you are building on Linux or want
to use a different Ruby then you also need to configure CRuby.

Getting the framework

Carthage for macOS:

github "johnfairh/RubyGateway"

Swift package manager for macOS or Linux:

.package(url: "https://github.com/johnfairh/RubyGateway", from: "2.0.0")

CocoaPods for macOS:

pod 'RubyGateway'

Configuring CRuby

CRuby is the glue between RubyGateway and your Ruby installation. It is a
separate github project but RubyGateway
includes it as submodule so you do not install or require it separately.

By default it points to the macOS system Ruby. Follow the CRuby usage
instructions
to change
this. For example on Linux using Brightbox Ruby
2.5:

sudo apt-get install ruby2.5 ruby2.5-dev pkg-config
mkdir MyProject && cd MyProject
swift package init --type executable
vi Package.swift
# add RubyGateway as a package dependency (NOT CRuby)
# add RubyGateway as a target dependency
echo "import RubyGateway; print(Ruby.versionDescription)" > Sources/MyProject/main.swift
swift package update
swift package edit CRuby
Packages/CRuby/cfg-cruby --mode pkg-config --name ruby-2.5
PKG_CONFIG_PATH=$(pwd)/Packages/CRuby:$PKG_CONFIG_PATH swift run

Contributions

Welcome: open an issue / [email protected] / @johnfairh

License

Distributed under the MIT license.

Latest podspec

{
    "name": "RubyGateway",
    "version": "2.0.0",
    "authors": {
        "John Fairhurst": "[email protected]"
    },
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    },
    "homepage": "https://github.com/johnfairh/RubyGateway",
    "source": {
        "git": "https://github.com/johnfairh/RubyGateway.git",
        "tag": "v2.0.0",
        "submodules": true
    },
    "summary": "Embed Ruby in Swift: load Gems, run scripts, get results.",
    "description": "A Swift framework built on the Ruby C API that lets Swiftnprograms painlessly and safely run and interact with Rubynprograms.  Easily pass Swift datatypes into Ruby and turnnRuby objects back into Swift types.",
    "documentation_url": "https://johnfairh.github.io/RubyGateway/",
    "source_files": [
        "Sources/RubyGateway/*swift",
        "Sources/RubyGatewayHelpers/**/*.{h,m}"
    ],
    "platforms": {
        "osx": "10.13"
    },
    "swift_version": "4.2",
    "frameworks": "Foundation",
    "preserve_paths": [
        "CRuby/*",
        "RubyGatewayHelpers/*"
    ],
    "pod_target_xcconfig": {
        "SWIFT_INCLUDE_PATHS": ""${PODS_ROOT}/RubyGateway/CRuby" "${PODS_ROOT}/RubyGateway/RubyGatewayHelpers"",
        "HEADER_SEARCH_PATHS": ""${PODS_ROOT}/RubyGateway/CRuby""
    },
    "prepare_command": "mkdir RubyGatewayHelpersnecho 'module RubyGatewayHelpers [system] {}' > RubyGatewayHelpers/module.modulemap"
}

Pin It on Pinterest

Share This