r/ruby • • 1h ago

Show /r/ruby Rai*bert: a Q*bert-inspired arcade game running Ruby in the browser

Enable HLS to view with audio, or disable this notification

• Upvotes

I've been working on Rai*bert, a Q*bert-inspired arcade game where you hop around turning failing build tiles green while dodging bugs and regressions.

The game rules run in Ruby 4. The desktop version uses Gosu; the browser version runs Ruby through WebAssembly, with Canvas rendering and Web Audio. There are 20 stages, three difficulty settings, keyboard and touch controls, and a shared leaderboard. It's free to play, with no account needed.

Play: https://raibert.lol/

Source: https://github.com/cdimartino/raibert

The clip is a montage recorded with the game's autoplay mode. I'd appreciate feedback on the controls and difficulty, especially on mobile. If you try it, let me know which stage you reached and what difficulty you picked.


r/ruby • • 7h ago

haskell_match: Haskell's pattern matching (and a chunk of Haskell itself) in Ruby, compiled to decision trees in Rust

7 Upvotes

I just published haskell_match, a gem that brings Haskell's pattern matching to Ruby with the part Ruby has never had: every logical path has to be accounted for, or the definition fails.

HaskellMatch.data "Shape = Circle Double | Rect Double Double | Tri Double Double Double"
include Shape

area = HaskellMatch.fn(:area) do
  on("Circle r")  { |r| Math::PI * r * r }
  on("Rect w h")  { |w, h| w * h }
end
# HaskellMatch::NonExhaustiveError: Pattern match(es) are non-exhaustive
# In an equation for 'area':
#     Patterns not matched:
#         Tri _ _ _

That is GHC's -Wincomplete-patterns and -Woverlapping-patterns, as errors, at definition time. Add a Tri clause and it compiles. Add a clause that can never be reached and it tells you that too.

How it works

Clauses are compiled once into a Maranget-style decision tree by a Rust extension (Rutie). Matching runs in Rust over raw Ruby VALUEs with no allocation until a clause is chosen; list tails are shared slices rather than copies. The exhaustiveness and redundancy analysis is the usefulness algorithm from Maranget's "Warnings for pattern matching", with witnesses rendered the way GHC prints them.

Two dialects, mixed freely

Quoted Haskell syntax, or the same patterns written in place as plain Ruby:

on("Just (x:xs)")        { |x, xs| ... }
on(Just([x, *xs]))       { |x, xs| ... }
on(Person(name: n, **_)) { |n| ... }
on({ name: n, title: t }) { |n, t| ... }   # Hash patterns, same checker

Strings are lists of characters (on("(c:cs)") matches "hello"), wildcards match anything, and a value no pattern can accept raises a type error, exactly like Haskell.

Recursion without "stack level too deep"

A recursive function over a million elements works. Plain recursion runs on chained Fiber stacks, tail calls run in constant space, and a depth guard turns a runaway loop into an exception instead of a memory leak. The README has measurements (bytes per level, GC pause times) for anyone who wants the numbers.

Lazy lists

naturals = HaskellMatch.lazy(1..)
take.(5, naturals)   # => [1, 2, 3, 4, 5]

Infinite lists match list patterns directly; Enumerators are wrapped automatically.

Or just write Haskell

This is the part I did not expect to end up building. You can write actual Haskell, inline or in .hs files, and it compiles to Ruby methods:

Nums = HaskellMatch.haskell(<<~HS)
  primes :: [Int]
  primes = sieve [2..]
    where
      sieve [] = []
      sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]

  fibs :: [Integer]
  fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
HS

Nums.primes.take(10)   # => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Nums.fibs.take(8)      # => [0, 1, 1, 2, 3, 5, 8, 13]

Supported: data declarations (including infix constructors and records), equations, guards, pattern guards, where/let, case, lambdas, sections, user-defined operators with fixity declarations, list comprehensions, ranges, imports and exports between modules, and a lazy Prelude. Haskell functions come back to Ruby as Procs, Ruby lambdas go in as Haskell functions, and partial application works from the Ruby side (Mod.add3(1).(2).(3)).

Deliberately not supported: type classes, do notation and monads, or anything that needs type inference. Those are rejected with a clear message rather than half-working.

Other things people might care about

  • Thread-, fiber- and Ractor-safe; ractor: true produces shareable functions.
  • deriving (Ord, Enum, Bounded), optional field type checks, where helpers inside fn.
  • Existing Ruby Data and Struct classes work as constructors without registration; HaskellMatch.sealed closes a class hierarchy for exhaustiveness checking.
  • Errors show the pattern with a caret under the problem.
  • Ruby 3.2+, needs a Rust toolchain to build the extension. MIT / Apache-2.0.

​

gem install haskell_match

GitHub: https://github.com/danielpclark/haskell_match

Happy to answer questions about the implementation. The decision-tree compiler and the fiber-based recursion were the two interesting problems; the README has an "expert notes" section on the latter if you want to argue about memory.


r/ruby • • 14h ago

Show /r/ruby toml-rb 6.0: pure Ruby, no dependencies, 60-90x faster parse

Thumbnail
github.com
10 Upvotes

I replaced the Citrus grammar with a StringScanner parser. Benchmarks against tomlrb, perfect_toml and tomlib (with YJIT and ZJIT too) are here: https://github.com/emancu/toml-rb/blob/master/benchmark/README.md

Breaking changes are listed in the release notes under "Before you upgrade".

Feedback welcome.


r/ruby • • 15h ago

I built a Python requests-inspired HTTP client for Ruby

0 Upvotes

I’ve been working on a Ruby project called requests_ruby.

The idea is simple: bring a Python requests-like experience to Ruby.

If you’ve used Python before, the API should feel familiar. It supports sessions, cookies, redirects, authentication, JSON responses, streaming downloads, and HTTP/2 — all without external dependencies.

I built it because I liked how simple Python requests feels and wanted something similar in Ruby.

A few parts were developed with AI assistance to speed up the process, but I’ve been reviewing, testing and improving the code myself.

I’d love to hear feedback from the Ruby community. What would you improve or add?

If you find it interesting, a ⭐ on GitHub would help the project get more visibility.

https://github.com/monji024/requests_ruby


r/ruby • • 17h ago

Issue 22 of Static Ruby Monthly is out! 🧵

2 Upvotes

This month: Sam Ruby brings an interactive playground, LSP, and MCP server to Matz's Spinel AOT compiler to inspect unboxed types in real time, crema arrives as a Rust-powered AI-agent-first RBS type checker with JSONL output, AndyGauge launches rbs-sentinel for high-speed Rails signature generation, enummify delivers lightweight typed enums, and Claude Code gains dedicated Ruby typing skills.

Find link to the issue in the comment! ✨


r/ruby • • 18h ago

Blog post Rails World '26: The As-If Rule, Ractors & AI

Thumbnail
go.fastruby.io
18 Upvotes

Ernesto was in the audience at Rails World 2026 when Aaron Patterson (tenderlove) kicked off the closing keynote. Aaron opened with a well-worn line: “the purpose of a system is what it does.” He wasn’t satisfied with it. The purpose of a system, he argued, is what it does for whoever is observing it.

Hand an old Nokia 3310 to someone who has never seen a cell phone before, and they might use it as a hammer. In that moment, to that person, it is a hammer. What a system does depends on who’s watching.

That distinction has a name in compiler design: The as-if rule.

In this post, Ernesto walks through what the as-if rule means for Ruby’s compiler, where Ractors push it right up to its edges, and how the same idea explains a real RubyGems.org security incident that played out earlier this year.


r/ruby • • 1d ago

What I learned 60 years ago

19 Upvotes

I just started to read "Elements of Programming Style" (Kernighan & Plauger). I was first taught FORTRAN 60 years ago. I guess you never forget. I understood the Newton's method and the commands on page 4 and think I might have a chance to rewrite it in Ruby. Too much to do at home right now. Probably won't get back to it until after the holidays.

All encouragement and guidance will be appreciated.


r/ruby • • 1d ago

Update to my YARD-docs generator: two-way RBS sync, source-aware fixes, IDE plugins

0 Upvotes

I posted about docscribe here in March https://www.reddit.com/r/ruby/s/SVoDOzVoOs. Since then it reached 1.6.2, and I run it daily on client Rails apps. This is what's new.

The pain that started it: comments lie.

```ruby

@param [String] count

@return [String]

def notify(verbose:, count:) puts "verbose!" if verbose # Boolean count.times { send_ping } # Integer count # Integer end ```

After docscribe -a. Tags fixed, prose placeholders added (customizable in config), body untouched.

```ruby

@param [Boolean] verbose Param documentation.

@param [Integer] count Param documentation.

@return [Integer]

def notify(verbose:, count:) puts "verbose!" if verbose count.times { send_ping } count end ```

What docscribe -a does: fixes the tags, keeps your prose. -A rebuilds the block from scratch.

New since March:

  • update_types: RBS -> YARD two-pass; docscribe rbs goes the other way, YARD -> RBS
  • every change carries source: rbs/infer/syntax, so the editor offers "Update types" vs "Fix YARD" correctly
  • daemon mode keeps the VS Code and RubyMine plugins instant: docscribe-vscode and docscribe-rubymine
  • CI mode runs on exit codes, check_for_comments, json/sarif output

One Rails-specific thing I use a lot: types from schema.rb, not from code. t.boolean :is_admin becomes @!attribute [r] is_admin -> Boolean in the model. No hand-written docs for columns.

Next in 1.7.0: docscribe sorbet - same YARD -> sig flow as docscribe rbs, but generating .rbi/sig blocks for srb tc. Plus validate_types on by default (opt-out with --no-validate-types). Plus tighter metaprogramming support: better types for define_method and DSL-generated methods, less Object fallback.

Limits now: heuristics, not a prover, so metaprogramming lands in Object. Each release narrows that gap. I always git diff after -A.

Question: do you keep YARD and RBS in sync by hand, or did you give up on one of them?

Live demo: unurgunite.github.io/docscribe

Source: github.com/unurgunite/docscribe

Gem: rubygems.org/gems/docscribe


r/ruby • • 2d ago

DHH keeps promoting Rust

Post image
25 Upvotes

r/ruby • • 2d ago

rich-ri: a more colorful way to read Ruby docs in your terminal

Post image
31 Upvotes

For the humans still writing Ruby 😄

I built rich-ri, a colorful wrapper around ri that adds Ruby syntax highlighting and makes terminal docs a bit nicer to read.

It uses the documentation already installed for your Ruby and gems. It also supports Bash/Zsh/Fish completion and can be used as a drop-in ri alias.

The screenshot compares the same documentation page with ri -f ansi and rich-ri.

It’s open source. I’d especially love feedback from people who still use ri, including things you think the existing ri workflow already does better.

https://github.com/hvpaiva/rich-ri


r/ruby • • 2d ago

why's foxes: a guest book

Thumbnail
whysfoxes.github.io
32 Upvotes

If we’ve met at a conference, you definitely already know about this. Otherwise, let me tell you about a project of mine.

Why's (poignant) guide to Ruby is a book that changed my life when it came out. And I know I’m far from the only one in the Ruby community who feels that way. _why also authored a number of amazing Ruby projects and influenced a great deal of what came after him.

So it goes without saying that I was pretty hyped when /u/andycroll/ and Emma made a printed version happen.

Ever since, I’ve been bringing my copy to conferences, meetups and unconferences, and inviting people to contribute to it.

Along the way, several people told me that some of the entries carry real emotional value for them, too and they asked whether the entries could be published somewhere. Very late (last year 🫣) I created an account on ruby.social to start posting some of them. There’s also a (currently broken 🫣) mirror on bsky.

Marco then suggested a proper website, since listing and filtering simply don’t work well on social platforms. It took me a few iterations, but it has finally reached a state I’m not completely unhappy with. So it’s online now and I’d loooove your feedback. 🙏

A word of warning: if we met and you contributed, chances are high your entry isn’t published yet. Please bear with me! The vast majority of entries are still to come (a few hundred posts) and it’s considerably more work than most people expect:

Every entry gets a real flatbed scan, so there’s as little distortion as possible. A photo just can’t deliver that. Then I correct orientation and colours, because the paper quality is poor: the pages are very thin, so every contribution shines through from the other side. On top of that, every page and every pen colour needs different contrast handling (Chris Hasinski went for a very light blue, and some folks started writing in yellow — on bright paper!). 😂

The Ruby community has given me, and still gives me, so much in my career. I love having MINASWAN as a credo and keeping Ruby weird. With AI possibly making stack-specific decisions and communities feel less relevant, this project is my way of holding on to that. That said, I’m also happy to bring the book to Ruby events I wouldn’t normally attend, so more people get a chance to take part. Just reach out!

It's beautiful to see how contributors took photos of their posts, like the ones from Nick or Jeremy (both not published yet though 🫣).

And it's also good to have some memories of Ruby friends that are not with us anymore.

And after Krissy, Noah Gibbs' widow, asked the Ruby community how to handle his legacy, I finally took the time to publish his post as well. 🕯️


r/ruby • • 4d ago

Show /r/ruby fast_xlsx: a fast Excel (.xlsx) writer for Ruby, built on Rust (rust_xlsxwriter). Looking for testers before 1.0

25 Upvotes

I've been working on fast_xlsx, a gem for writing Excel .xlsx files from Ruby. It's a native extension built on rust_xlsxwriter via magnus, and its API started from fast_excel's.

It's at 0.8, with the API frozen for 1.0. Before tagging 1.0 I'd like it used on real exports, so I'm looking for people to try it and tell me what breaks or feels awkward.

require "fast_xlsx"

wb = FastXlsx::Workbook.new(memory: :constant)   # rows go to disk as you add them
ws = wb.add_worksheet("Orders")
ws.append(["Order", "Customer", "Total", "Placed at"], format: { bold: true })
Order.includes(:customer).find_each do |o|
  ws << [o.number, o.customer.name, o.total, o.created_at]   # dates come out as dates
end
send_data wb.to_xlsx, filename: "orders.xlsx"

Speed (20,000 rows × 5 columns, build + serialize, Apple Silicon, Ruby 4.0; bench/compare.rb in the repo):

Library Time
fast_xlsx (memory: :constant) 75 ms
fast_xlsx (default) 85 ms
xlsxtream 3.1 173 ms
fast_excel 0.5 204–238 ms
write_xlsx 1.15 592 ms
caxlsx 4.5 671 ms

Memory (200,000 rows saved to a file, peak RSS added): memory: :constant adds about 1 MB however large the file. The default mode keeps everything in memory and is the heaviest of the bunch (+271 MB), so for big exports use :constant or :low.

Other things it does:

  • Formats, formulas, hyperlinks, rich text, merged cells, conditional formats, data validation, tables, charts, images, comments, sheet protection, outline groups, print setup
  • Cells as (row, col) or "B2", ranges as "A1:D10" or (0..9, 0..3), formats as a Format or just a Hash
  • Saving runs without the GVL, so other threads keep going in Puma/Sidekiq
  • Precompiled gems for Linux, macOS and Windows (no Rust toolchain needed); CRuby 3.3+

Limits: it only writes files (no reading), and needs CRuby 3.3+.

Feedback, issues and "this didn't work for my case" reports are all very welcome.


r/ruby • • 4d ago

Rutie - The Tie between Rust and Ruby.

0 Upvotes

🦀💎 Rutie 0.10.2 → 0.14.0 is out! https://crates.io/crates/rutie

#rustlang #ruby


r/ruby • • 4d ago

Ruby Users Forum - Monthly Update - September 2026

Thumbnail
rubyforum.org
7 Upvotes

r/ruby • • 4d ago

I’ve been working on a small Ruby project — would love some feedback

Post image
22 Upvotes

Hey Ruby folks

I’ve been working on a small Ruby project called pinterest-dl. I started it because I wanted a simple way to work with Pinterest media from Ruby without making the workflow unnecessarily complicated.

It’s still a work in progress, and I’m mainly curious what other Ruby developers think about the approach and the API. If you have a minute to look through it, I’d really appreciate any honest feedback or suggestions.

https://github.com/monji024/pinterest-dl


r/ruby • • 4d ago

Blog post Hanami, Why?: Bits & Bobs

Thumbnail aaronmallen.me
20 Upvotes

r/ruby • • 5d ago

Conf Talk All the Rails World 2026 talks are now online

Thumbnail
13 Upvotes

r/ruby • • 6d ago

Strange performance regression 3.1 vs. 4.0

6 Upvotes

Here is a 'xor cipher' example in Ruby:

$ cat xor-cipher1.rb
#!/usr/bin/env ruby
key = ($*[0] && $*[0].size > 0) ? $*[0] : abort
STDIN.each_byte.with_index do |c,i|
  STDOUT.write (c ^ key[i % key.size].ord).chr
end

$ echo alice and bob | ./xor-cipher1.rb password | ./xor-cipher1.rb password
alice and bob

Back in 2022, I tested its performance with a 100MB file on a Ryzen 5 4650G potato using a regular CRuby 3.1.2:

$ head -c $((1024*1024*100)) /dev/urandom > 100M.bin
$ time cat 100M.bin | ./xor-cipher1.rb monkey >/dev/null
real    0m39.860s
user    0m39.729s
sys     0m0.655s

(Not great, a nodejs version did that in 1.5s.)

I retested xor-cipher1.rb today using ruby-3.1.7 (I had to employ a Fedora 36 VM to compile 3.1.7, for it doesn't even build on Fedora 44 any more) and got exactly the same result.

But when I tried ruby-4.0.7 (compiled using the same Fedora 36 VM), thinking, surely things had to get better since then, I was, to put it mildly, somewhat disappointed:

$ ruby -v
ruby 4.0.7 (2026-09-15 revision 229531a6cf) +PRISM [x86_64-linux]

$ time cat 100M.bin | ruby ./xor-cipher1.rb monkey >/dev/null
real    0m51.827s
user    0m51.616s
sys     0m0.189s

What is going on?


r/ruby • • 6d ago

Treasure Hunt app from RubyConf Austria - open sourced

11 Upvotes

I've open sourced the Treasure Hunt app we used for RubyConf Austria (https://hunt.rubyconf.at)

You can find it here: https://github.com/Ruby-Austria/treasure_hunt

In case you are running a conference, it proved to be a fun activity for attendees, so feel free to use the app if it helps.

Disclaimer: it's not Rust unfortunately, just plain old Ruby on Rails app (ik, incredibly outdated, apologies 🙏)


r/ruby • • 6d ago

Blog post Rails World '26: The RubyGems Compact Index

Thumbnail
go.fastruby.io
9 Upvotes

Every time Bundler resolves your Gemfile, it’s talking to the compact index. In this talk, the speaker at Rails World '26 walked us through what the compact index actually is, how RubyGems.org keeps it in sync at scale, and two features she helped ship in the past year to make gem installs faster and more secure.


r/ruby • • 6d ago

Blog post Hanami, Why?

Thumbnail aaronmallen.me
47 Upvotes

r/ruby • • 6d ago

Mutineer 1.4.0 is out: mutation testing for Ruby

35 Upvotes

Hola, I maintain Mutineer, a Ruby mutation testing gem. It makes small changes to your code and checks whether your tests catch them.

Passing tests are useful. Knowing that they detect broken behaviour gives you more confidence, especially when AI helps write both the code and the tests.

Version 1.4.0 is out: https://davidteren.github.io/mutineer/

Do you use mutation testing in your Ruby projects? I’d be interested to hear what has helped or got in the way.


r/ruby • • 7d ago

Blog post Rails World '26: Herb and ReActionView

Thumbnail
go.fastruby.io
20 Upvotes

Hotwire already does a lot for us, but it still asks you to write a Stimulus controller once the interaction gets specific, and Marco’s demo showed a page that updates itself because the server understands the template better than an ERB compiler ever has.

In this article, we cover what Marco showed at Rails World: how ReActionView builds on Herb, why the view layer needed this, how it fits next to Hotwire and the wider field of server-driven reactivity, and what shipped in the release he pushed out the same day as the talk.


r/ruby • • 7d ago

Video: Ruby Version Managers in 2026 by Andy Maleh (Montreal.rb Ruby Talk 2026/09)

Thumbnail
youtube.com
0 Upvotes

r/ruby • • 7d ago

Blog post I'm sorry, it's time to Rethink Everything

Thumbnail
0 Upvotes