{"id":13691654,"url":"https://github.com/phoffer/crystalized_ruby","last_synced_at":"2025-09-17T15:46:40.766Z","repository":{"id":71365800,"uuid":"59442192","full_name":"phoffer/crystalized_ruby","owner":"phoffer","description":"Write native Ruby extensions in Crystal","archived":false,"fork":false,"pushed_at":"2018-05-19T02:14:49.000Z","size":94,"stargazers_count":153,"open_issues_count":1,"forks_count":7,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-07-20T02:16:11.261Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phoffer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-05-23T00:57:56.000Z","updated_at":"2024-11-28T16:32:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"100a9c5b-3ed6-402d-89c5-0dbaf700dd90","html_url":"https://github.com/phoffer/crystalized_ruby","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/phoffer/crystalized_ruby","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fcrystalized_ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fcrystalized_ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fcrystalized_ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fcrystalized_ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phoffer","download_url":"https://codeload.github.com/phoffer/crystalized_ruby/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fcrystalized_ruby/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275621164,"owners_count":25498117,"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","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-08-02T17:00:48.335Z","updated_at":"2025-09-17T15:46:40.723Z","avatar_url":"https://github.com/phoffer.png","language":"Ruby","funding_links":[],"categories":["Examples and funny stuff"],"sub_categories":[],"readme":"# Native Ruby extensions written in Crystal\n\n[![Join the chat at https://gitter.im/phoffer/crystalized_ruby](https://badges.gitter.im/phoffer/crystalized_ruby.svg)](https://gitter.im/phoffer/crystalized_ruby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nFunctional code for native extensions, without using FFI. This can utilize any Crystal code, i.e. existing shards.\n\n**This is still in heavy development and not ready for use.** If you are interested in creating a proof of concept, I'm happy to assist. But otherwise, this isn't ready for real use.\n\nCurrent work is splitting this repo into multiple repos:\n\n1. A Crystal shard that contains the Ruby bindings (will be this repo)\n2. [A faster version of ActiveSupport::Inflector](https://github.com/phoffer/fast_inflector) that utilizes [inflector.cr](https://github.com/phoffer/inflector.cr) as a native extension\n3. A Ruby gem that assists with generating a gem that uses Crystal for a native extension\n\nThis work is being done on the `repo-split` branch.\n\n## Class conversion status\n\n| Ruby class  | Ruby =\u003e Crystal | Crystal =\u003e Ruby |\n| ----------- | :-------------: | :-------------: |\n| String      | :white_check_mark: | :white_check_mark: |\n| Symbol      | :x:                | :white_check_mark: |\n| Integer     | :white_check_mark:* | :white_check_mark: |\n| Float       | :x:                | :x:                |\n| Hash        | :x:                | :white_check_mark: |\n| Array       | :white_check_mark: | :white_check_mark: |\n| Regexp      | :white_check_mark: | :white_check_mark: |\n| Nil         | :white_check_mark: | :white_check_mark: |\n| True        | :white_check_mark: | :white_check_mark: |\n| False       | :white_check_mark: | :white_check_mark: |\n\n# TODO\n\n- [ ] get all types working\n  + [ ] float rb \u003c=\u003e cr\n  + [ ] negative integers rb =\u003e cr\n  + [ ] hash rb =\u003e cr\n  + [ ] something for symbol rb =\u003e cr\n- [ ] be able to build gem and use (even just for checking type conversions)\n- [ ] separate repo into crystal shard for lib_ruby related, generator gem, and fast_inflector gem\n\n## Updates\n\nSee [updates.md](updates.md)\n\n# Problems\n\n* Negative integers don't convert correctly\n* Floats aren't working\n* I am having trouble with defining methods with various parameter counts. There's additional Crystal libs just for defining methods with zero or two parameters. This is obnoxious and the biggest annoyance I have right now, so I'd love to fix that soon.\n* I can't get a proc as a C callback working. There's some broken code commented out. Would love assistance from someone more knowledgeable. Right now this is for converting a Ruby hash to a Crystal hash. \n\n# How to get this working\n\nMinimum crystal version: 0.16.0\n\nMake sure Crystal is installed (Homebrew on OSX is fine)\n\nTest and benchmark scripts both require [fast_blank](https://github.com/SamSaffron/fast_blank) and [active_support](https://github.com/rails/rails/tree/master/activesupport), mainly for comparison. Test script also uses [descriptive_statistics](https://github.com/thirtysixthspan/descriptive_statistics), and the benchmark script uses [benchmark-ips](https://github.com/evanphx/benchmark-ips). None of these are required, except to run those two Ruby scripts. There's a Gemfile to install them if desired.\n\n```\nrake clean\nrake compile\nrake test\nbin/test\nbin/benchmark\n```\n\n# Benchmarking\n\nThere is a benchmark script that compares a few things. The methods replicating ActiveSupport methods are copy-pasted, not even re-implemented from scratch. This uses the improved String#blank? method from AS 5.0, but it's not a hard requirement.\n\nSome highlights (see results.txt for more):\n\n```\nComparison:\n        cr fibonacci:    22743.9 i/s\n        rb fibonacci:      923.2 i/s - 24.63x slower\n\nComparison:\n     empty string rb:  7591363.0 i/s\nempty string crystal:  6973264.7 i/s - same-ish: difference falls within error\n\nComparison:\n     CR blank string:  2393668.6 i/s\n     AS blank string:   923967.3 i/s - 2.59x slower\n\nComparison:\n           cr squish:   691693.1 i/s\n           AS squish:   202554.1 i/s - 3.41x slower\n\nComparison:\n          cr ordinal:  5044785.3 i/s\n          AS ordinal:  1775271.7 i/s - 2.84x slower\n\nComparison:\n       fast_blank rb:  6599201.8 i/s\n       blank crystal:  2199386.4 i/s - 3.00x slower\n```\n\n\n# Thanks and influences\n\nThere's three main projects that I've gained knowledge from to get this fully working:\n\n- [manastech/crystal_ruby](https://github.com/manastech/crystal_ruby)\n- [notozeki/crystal_example_ext](https://gist.github.com/notozeki/7159a9d9ab9707a22129)\n- [gaar4ica/ruby_ext_in_crystal_math](https://github.com/gaar4ica/ruby_ext_in_crystal_math)\n\nThese have all been incredibly helpful, and this is very closely modeled after the last two sources. @gaar4ica's also includes a PDF from a talk she gave at Fosdem, which was highly informative.\n\n# Future Ideas + Contributing\n\nI'd like to get this more fully fleshed out, more functional, and get it usable. There is some question as to whether or not writing a native Ruby extension in Crystal is a useful idea, and I'd love to learn more about both why it _would_ and would _not_ be worthwhile, from people out there who are far more knowledgeable than I am.\n\nIf anyone is interested in this concept, please reach out to me either on this repo or on Twitter (@phoffer8). I'd love to collaborate with anyone interested, and just learn more in general.\n\n# Wish List\n\n* Complete the LibRuby wrapper for ruby.h and possibly a way to automate extracting the signatures from ruby.h into Crystal\n* Create a series of macros to create the wrappers of the Crystal methods (to convert input and output type between Crystal and CRuby)\n* Separate the LibRuby part into a separate gem/shard to make it reusable\n* If it was possible to create the aforementioned macros, then it would be great to create a generator to create the template of a Ruby gem with the native extension bits (libruby, extconf, makefile, etc)\n\nGoal: to make it as easy as possible to create Ruby gems with Crystal-based native extensions where we could start with a \"slow\" Ruby source, tweak it quickly into a Crystal source file, wrap it up with LibRuby and compile it back as a native extension. No having to resort to C, Rust or other low level options.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoffer%2Fcrystalized_ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphoffer%2Fcrystalized_ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoffer%2Fcrystalized_ruby/lists"}