The Crystal Programming Language Forum

Ruby interop

Hello!
I’ve read a few posts about the effort needed to make Crystal interop with Ruby, and I wonder if anyone is working in something like Helix to make Rust interop with Ruby.

I could find some projects on Github like “crystalized_ruby” and “crystal_ruby” (can’t add links here since I’m a new user) with that goal, but all of them seem to have been abandoned years ago. Something like this would make it very practical to port and existing Ruby/Rails application to Crystal gradually.

Seeing that this road is full of corpses makes me wonder if there is a deeper reason that makes this problem hard to tackle.

The best answer I could find was posted on StackOverflow in 2016:

This question has been maybe asked a million times now. You can try to do it, but remember that Crystal has a GC, so it really doesn’t make much sense to write native extensions in Crystal. Use C or Rust, which don’t have a GC.

Is that the best answer in 2020? Sorry for the ignorance, but I don’t get why having a GC is such a huge pitfall. Can’t we just build a library to generate code to make Ruby and Crystal interop through C, and add some hints for the developer about how to deal with the memory issue manually?

Hey! Welcome to the community. I haven’t really seen much in the way of this other than the projects you mentioned already. My guess is that it’s less of a “You shouldn’t do this”, and more of a “I have no practical reason to do this” sort of thing. I’d say if this is something that interests you, by all means have at it! Maybe fork one of those other projects, and look to get some project using Crystal on the backend somehow. Then blog about it.

I wouldn’t worry about “performance” or anything like that. Make it work first, then make it clean and fast later. Plus, that will give you a better understanding of Crystal.

Also, if you want to get a feel for some web dev in Crystal, come checkout Lucky :smiley:

Thanks for your feedback!

My guess is that it’s less of a “You shouldn’t do this”, and more of a “I have no practical reason to do this” sort of thing.

So, the practical reason to do it is this: How do I start migrating an existing Rails app to Crystal, so that I can proceed piece by piece? So far the only options I have come up with are:
a) (HTTP layer glue) Put the Crystal app in front of the Ruby app as a proxy (or vice-versa)
b) (IPC glue) Develop one or multiple modules in Crystal and communicate with the Ruby app through STDIN/STDOUT
c) (C FFI glue) Do something like this to publish a Crystal module to Ruby through FFI.

It would be great if somebody that tried one of these options (or something else entirely) could share their opinion about it, and maybe give some advice.

a) and b) are probably the main ways to go. a) can also be your reverse proxy sending certain paths to either or the other app. b) can also be any kind of IPC, for example your Rails app scheduling sidekiq jobs where some jobs are picked up by sidekiq.cr. Or a microserve communicating with the main app via HTTP, msgpack, protobuf, ZeroMQ etc.

1 Like

Or a microserve communicating with the main app via HTTP, msgpack, protobuf, ZeroMQ etc.

Good idea! I’m a fan of gRPC and by reading this issue we can see that someone has already implemented it. Seems promising! :slightly_smiling_face:

1 Like

Check https://github.com/rheimbuch/crystal_shared_library_testing . I think he uses some level of ruby <-> crystal integration. I am not sure he is in the forum though.

1 Like

Thanks! It seems like a good recipe. :+1:t2:

Sorry, I didn’t mean that there was “no” practical reason, I was more making an assumption that no one in the community has really had a reason for working on that :laughing: My company runs almost fully on Crystal now, and we’ve ported several rails apps now, but all of them were just built from the ground up, deployed to new servers, then pointed traffic over little by little until I was fully on crystal.

My company was more fortunate in that we had 1 guy continue to work on the rails stuff while the other 2 of us started porting stuff over. So I get that it’s not really an option for everyone to just start from ground up, especially if you’re working with a monolith. It’d be cool to see what path you take for this. I honestly never even considered trying to slow port an app. I hope you’re able to make some progress on that! Good Luck

1 Like

Put nginx reverse proxy where you will redirect specific paths (the ones you already migrated) to Crystal and the rest will go back to your original app.

Put nginx reverse proxy where you will redirect specific paths (the ones you already migrated) to Crystal and the rest will go back to your original app.

Good strategy! :+1:t2:

1 Like

It is planned to integrate Crystal into metacall which would allow Crystal to interop with a number of different languages, including Ruby. I just need to get up the motivation to work on it.

2 Likes