{"id":13819382,"url":"https://github.com/johnfairh/RubyGateway","last_synced_at":"2025-05-16T04:33:33.521Z","repository":{"id":44953999,"uuid":"124666160","full_name":"johnfairh/RubyGateway","owner":"johnfairh","description":"Embed Ruby in Swift: load Gems, run scripts, call APIs seamlessly in both directions.","archived":false,"fork":false,"pushed_at":"2024-09-19T11:12:38.000Z","size":12983,"stargazers_count":158,"open_issues_count":1,"forks_count":7,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-10-13T14:13:16.718Z","etag":null,"topics":["api","bindings","linux","macos","ruby","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnfairh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-10T15:00:22.000Z","updated_at":"2024-09-28T02:48:12.000Z","dependencies_parsed_at":"2023-02-15T11:01:37.883Z","dependency_job_id":"9e29fad1-7215-41b0-aba5-2937330e0360","html_url":"https://github.com/johnfairh/RubyGateway","commit_stats":{"total_commits":311,"total_committers":2,"mean_commits":155.5,"dds":0.003215434083601254,"last_synced_commit":"63e623fd9f6afb7a8ae1d2f14b4576004cf88ee3"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnfairh%2FRubyGateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnfairh%2FRubyGateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnfairh%2FRubyGateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnfairh%2FRubyGateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnfairh","download_url":"https://codeload.github.com/johnfairh/RubyGateway/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225405599,"owners_count":17469375,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","bindings","linux","macos","ruby","swift"],"created_at":"2024-08-04T08:00:46.467Z","updated_at":"2025-05-16T04:33:33.512Z","avatar_url":"https://github.com/johnfairh.png","language":"Swift","funding_links":[],"categories":["Swift","Happy Exploring 🤘"],"sub_categories":[],"readme":"\u003c!--\nRubyGateway\nREADME.md\nDistributed under the MIT license, see LICENSE.\n--\u003e\n\n# RubyGateway\n\n[![CI](https://travis-ci.org/johnfairh/RubyGateway.svg?branch=master)](https://travis-ci.org/johnfairh/RubyGateway)\n[![codecov](https://codecov.io/gh/johnfairh/RubyGateway/branch/master/graph/badge.svg)](https://codecov.io/gh/johnfairh/RubyGateway)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n![Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20linux-lightgrey.svg)\n![License](https://cocoapod-badges.herokuapp.com/l/RubyGateway/badge.png)\n\nEmbed Ruby in Swift: load Gems, run Ruby scripts, invoke APIs seamlessly in\nboth directions.\n\nRubyGateway is a framework built on the Ruby C API that lets Swift programs\nrunning on macOS or Linux painlessly and safely run and interact with Ruby\nprograms.  It's easy to pass Swift values into Ruby and turn Ruby objects\nback into Swift types.\n\nRubyGateway lets you call any Ruby method from Swift, including passing Swift\nclosures as blocks.  It lets you define Ruby classes and methods that are\nimplemented in Swift.\n\nSee [CRuby](https://github.com/johnfairh/CRuby) if you are looking for a\nlow-level Ruby C API wrapper.\n\n* [Examples](#examples)\n* [Documentation](#documentation)\n* [Requirements](#requirements)\n* [Installation](#installation)\n* [Contributions](#contributions)\n* [License](#license)\n\n## Examples\n\n### Services\n\n[Rouge](https://github.com/jneen/rouge) is a code highlighter.  In Ruby:\n```ruby\nrequire 'rouge'\nhtml = Rouge.highlight(\"let a = 3\", \"swift\", \"html\")\nputs(html)\n```\n\nIn Swift:\n```swift\nimport RubyGateway\n\ntry Ruby.require(filename: \"rouge\")\nlet html = try Ruby.get(\"Rouge\").call(\"highlight\", args: [\"let a = 3\", \"swift\", \"html\"])\nprint(html)\n```\n\n### Calling Ruby\n\n```swift\n// Create an object.  Use keyword arguments with initializer\nlet student = RbObject(ofClass: \"Academy::Student\", kwArgs: [\"name\": \"barney\"])!\n\n// Access an attribute\nprint(\"Name is \\(student.get(\"name\"))\")\n\n// Fix their name by poking an ivar\ntry! student.setInstanceVar(\"@name\", newValue: \"Barney\")\n\n// Get a Swift version of `:reading`\nlet readingSubject = RbSymbol(\"reading\")\n\n// Call a method with mixed Swift data types\ntry! student.call(\"add_score\", args: [readingSubject, 30])\ntry! student.call(\"add_score\", args: [readingSubject, 35])\n\n// Get a result as floating point\nlet avgScoreObj = try! student.call(\"mean_score_for_subject\", args: [readingSubject])\nlet avgScore = Double(avgScoreObj)!\nprint(\"Mean score is \\(avgScore)\")\n\n// Pass Swift code as a block\nlet scores = student.all_scores!\nscores.call(\"each\") { args in\n    print(\"Subject: \\(args[0]) Score: \\(args[1])\")\n    return .nilObject\n}\n\n// Convert to a Swift array\nlet subjects = Array\u003cString\u003e(student.all_subjects!)\nsubjectsPopularityDb.submit(subjects: subjects)\n```\n\n## Calling Swift\n\nBound class definition:\n```swift\nclass Cell {\n    init() {\n    }\n\n    func setup(m: RbMethod) throws {\n        ...\n    }\n    \n    func getContent(m: RbMethod) throws -\u003e String {\n        ...\n    }\n}\n\nlet cellClass = try Ruby.defineClass(\"Cell\", initializer: Cell.init)\n\ntry cellClass.defineMethod(\"initialize\",\n        argsSpec: RbMethodArgsSpec(mandatoryKeywords: [\"width\", \"height\"])\n        method: Cell.setup)\n\ntry cellClass.defineMethod(\"content\",\n        argsSpec: RbMethodArgsSpec(requiresBlock: true),\n        method: Cell.getContent)\n```\nCalled from Ruby:\n```ruby\ncell = Cell.new(width: 200, height: 100)\ncell.content { |c| prettyprint(c) }\n```\n\nGlobal variables:\n```swift\n// epochStore.current: Int\n\nRuby.defineGlobalVar(\"$epoch\",\n        get: { epochStore.current },\n        set: { epochStore.current = newEpoch })\n```\n\nGlobal functions:\n```swift\nlet logArgsSpec = RbMethodArgsSpec(leadingMandatoryCount: 1,\n                                   optionalKeywordValues: [\"priority\" : 0])\ntry Ruby.defineGlobalFunction(\"log\",\n                              argsSpec: logArgsSpec) { _, method in\n    Logger.log(message: String(method.args.mandatory[0]),\n               priority: Int(method.args.keyword[\"priority\"]!))\n    return .nilObject\n}\n```\nCalls from Ruby:\n```ruby\nlog(object_to_log)\nlog(object2_to_log, priority: 2)\n```\n\n## Documentation\n\n* [User guide](https://johnfairh.github.io/RubyGateway/guides/user-guide.html)\n* [API documentation](https://johnfairh.github.io/RubyGateway)\n* [Docset for Dash](https://johnfairh.github.io/RubyGateway/docsets/RubyGateway.tgz)\n\n## Requirements\n\n* Swift 6.0 or later, from swift.org or Xcode 16+\n* macOS (tested on 15.3) or Linux (tested on Ubuntu Jammy)\n* Ruby 2.6 or later including development files:\n  * For macOS, these come with Xcode.\n  * For Linux you may need to install a -dev package depending on how your Ruby\n    is installed.\n  * RubyGateway requires 'original' MRI/CRuby Ruby - no JRuby/Rubinius/etc.\n\n## Installation\n\nFor macOS, if you are happy to use the system Ruby then you just need to include\nthe RubyGateway framework as a dependency.  If you are building on Linux or want\nto use a different Ruby then you also need to configure CRuby.\n\n## Linux\n\nAs of Swift 6, Apple have broken Swift PM such that you must pass \"-Xcc -fmodules\" to build the project.  Check the CI invocation for an example.\n\n### Getting the framework\n\nCarthage for macOS:\n```\ngithub \"johnfairh/RubyGateway\"\n```\n\nSwift package manager for macOS or Linux:\n```\n.package(url: \"https://github.com/johnfairh/RubyGateway\", from: \"6.1.0\")\n```\n\n### Configuring CRuby\n\nCRuby is the glue between RubyGateway and your Ruby installation.  It is a\n[separate github project](https://github.com/johnfairh/CRuby) but RubyGateway\nincludes it as submodule so you do not install or require it separately.\n\nBy default it points to the macOS system Ruby.  Follow the [CRuby usage\ninstructions](https://github.com/johnfairh/CRuby#usage) to change\nthis.  For example on Ubuntu 18 using `rbenv` Ruby 3:\n```shell\nmkdir MyProject \u0026\u0026 cd MyProject\nswift package init --type executable\nvi Package.swift\n# add RubyGateway as a package dependency (NOT CRuby)\n# add RubyGateway as a target dependency\necho \"import RubyGateway; print(Ruby.versionDescription)\" \u003e Sources/MyProject/main.swift\nswift package update\nswift package edit CRuby\nPackages/CRuby/cfg-cruby --mode rbenv --name 3.0.0\nPKG_CONFIG_PATH=$(pwd)/Packages/CRuby:$PKG_CONFIG_PATH swift run -Xcc -fmodules\n```\n\n## Contributions\n\nWelcome: open an issue / johnfairh@gmail.com / @johnfairh@mastodon.social\n\n## License\n\nDistributed under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnfairh%2FRubyGateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnfairh%2FRubyGateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnfairh%2FRubyGateway/lists"}