Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Definitive Guide to Ruby's C API (silverhammermba.github.io)
171 points by Lammy on May 18, 2021 | hide | past | favorite | 13 comments


I'm hoping ruby gets a bit of a resurgence. It's really not as slow as it used to be (ran some benchmarks recently, and ruby/roda was pretty much on par with node.js/express with multiple processes). The Actor model looks promising too.


I've covered developments in the Ruby space in https://rubyweekly.com/ for over ten years (and in a blog before that) and Ruby went through a huge lull around 2015-2018 that I was seriously worried about it! Since then, things have bloomed - it's not like the 2005-2010 era of heavy (mostly Rails-fuelled) growth, but a lot of interesting projects have come out, important libraries are being maintained and improved, and there's a much stronger sense of maturity and longevity around Ruby now. Long may it last.

I am now seeing a similar lull in the Node space, which I also cover, but it, too, will surely pass through it unscathed.


I wanted to get back into Ruby after developing a serious allergy to Python, but for me the niche of 10-100 lines long programs right now is comfortably filled by statically compiled or project-less languages such as Go or Deno. I really dislike having to create a whole directory to install dependencies for a quick script, or managing dependencies if I need to run the script on multiple machines.

That said, if Ruby were to get an option to statically compile into a standalone binary, I might check it out again. It really is expressive and joyful.


I really like the Go "philosophy" - I really enjoy tools made with Go like Micro and Caddy, and a statically compiled binary as a deployment unit does sound convenient.

I don't relish the thought of going back to loops though. Or not having a good REPL.

Deno appeals to me, but isn't very portable yet. Also has a limited node style REPL (can't reload files).


I’m curious what the work load was like and the work... IO, concurrent connections, etc.


The work was almost nothing, just a GET request for 'hello world'.

I tried 10, 100 and 1000 concurrent connections.


I wrote a C Ruby binding for a database a long time ago and found it incredibly easy and intuitive to program. I wish I had this manual back then but admittedly, referencing other existing C Ruby bindings got me through it. Definitely a notable improvement in performance.


This is cheating! ;-)

I wrote and retooled a bunch of Ruby C extensions. Back in my day, we looked at other extensions to see how things worked. And then sometimes looked at the docs.


When writing Ruby C extensions, you almost inevitably need to learn to read the Ruby codebase (written in C). It helps if you can get your preferred IDE to build and understand the codebase.

For people who want to use LSP + clangd to explore the Ruby codebase, I wrote up some instructions here:

https://blog.jez.io/clangd-ruby/

tl;dr: Bear[1] is a tool that hijacks a process tree, looks for calls to clang, records the args it was given, and serializes those out into a compile_commands.json file that can be consumed by various clang tools, including clangd. It's really slick and in my experience Just Works (the highest praise, IMO).

You can use more or less the same trick described in that post to get the Ruby C extensions you build working with LSP + clangd (no guide for this, but it should be self-evident from reading the original guide).

[1] https://github.com/rizsotto/Bear


> you almost inevitably need to learn to read the Ruby codebase (written in C)

That's how I ran across this reference, but from the other direction — I've been reading the MRI codebase with the goal of writing faster/better Ruby :)

I've been working on my own version of a file-type identification library (even before the recent `mimemagic` drama) and have found it very necessary to understand the way allocation works since the code in question sits in my app's startup path and gets referenced more frequently than anything else. This post series by Pat Shaughnessy was also very useful for me: http://patshaughnessy.net/2013/2/8/ruby-mri-source-code-idio...


For MSBuild, one can use what IDE does to get the compile targets:

msbuild YourProject.sln /p:Configuration=Release /p:DesignTimeBuild=true /t:_PrintIntellisenseInfo

The _PrintIntellisenseInfo target is the key, and "lying" to the rules that you are the IDE - e.g DesignTimeBuild=true.

This prints almost the info you want for compilation_database.json


I recently did a bit of a dive into the internals of another interpreted dynamic language - R. This may be quite unsurprising but I was struck by how similar many things are here. I guess this says something about how writing a runtime in a language like C naturally leans towards certain patterns


It's the missing manual, invaluable.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: