🗓 We're back! And, no, you didn't miss a special Xmas edition of the newsletter, as I decided to enjoy the week off ;-) Unsurprisingly this issue focuses on the Ruby 3.1 release but Jemma is also back with a new Tip of the Week at the end of the issue, so we hope you enjoy that too :-)
Peter Cooper — Editor

#​585 — January 6, 2022

Read on the Web

Ruby Weekly

🎁  Ruby 3.1.0 Released on Christmas Day — As is traditional for Ruby, we got a significant new release on Christmas Day, although I was too busy eating turkey to notice at the time. The most exciting addition this time is YJIT, the latest attempt at adding JIT compilation to Ruby, although it’s still considered experimental. There are some other things, too:

  • A brand new debugger which even plays nicely with VS Code and Chrome.
  • error_highlight for more accurately showing where naming errors occur in backtraces.
  • IRB gains an autocompletion feature (and feels a lot faster to me, at least).
  • A new hash literal and keyword arguments syntax to reduce duplication.
  • Class#subclasses
  • And a lot more.. but see the item below!

Yui Naruse

A Look at All of Ruby 3.1's Changes — As great as the official release posts (above) are, we really love Victor’s technical and code-led guides to what’s new in new versions of Ruby. His 3.1 guide is no exception and while 3.1 isn’t as rich with new language feature as 3.0 was, it’s great to see them shown off in this way along with links to the original discussions.

Victor Shepelev

Stripe-Quality Webhooks for Everyone — Get reliable inbound and outbound webhook delivery, with debugging and logging, in minutes. Click here to learn how.

Hook Relay sponsor

How Ruby and Web Components Can Work Together — Jared (the creator of Bridgetown) shares some real-world examples of a componentized view architecture, mostly using the Serbea template engine and Ruby2JS.

Jared White

Opal 1.4 Released: Ruby 3.1 Support and More — Opal is a popular Ruby to JavaScript transpiler for writing frontend code in pure Ruby. v1.4 focuses on Ruby 3.1 compatibility (2.6 remains fine, however) but also packs in some performance and bundle size improvements.

Adam Beynon and Contributors



Dalli 3.2 – High perf memcached client.
shoulda-matchers 5.1 – One liners for testing Rails functionality.
Fusuma 2.3 – Multitouch gestures on Linux.
MemoWise 1.5 – Smarter Ruby memoization.
Pygments.rb 2.3 – Syntax highlighting wrapper.
AnyCable 1.2


Senior Ruby Engineer (Remote, EU Time Zones) — Read how we balance life/work and what our values are. Maybe we can pique your interest to join our remote team and help make accountants’ work more meaningful.

Software Engineer (Remote) — Come join us at Invoca and help build cutting edge Conversation Intelligence systems using Rails, Python, GraphQL, and more.

Find Ruby Jobs Through Hired — Create a profile on Hired to connect with hiring managers at growing startups and Fortune 500 companies. It's free for job-seekers.

📕 Articles & Tutorials

Rails Authentication From Scratch — A nice code-along that creates your own Devise including confirmation, password reset, sessions, accounting for common attacks, and more.

Steve Polito

How Ruby's instance_exec Works — Ever wonder how some DSLs, like RSpec, can call methods with no receiver and do what you’d expect? Well, here’s their secret.

Jason Swett

Five Things You Did Not Know About Rails Transactions — Whether you’re using them explicitly or not, they’re there, so knowing some of their surprising behavior is a good idea.

Paweł Dąbrowski (Long Live Ruby)

🐘 The Developer Experience You’ve Always Wanted for Postgres

Crunchy Bridge sponsor

▶  Talking about Game Development in Ruby with Victor David Santos — Victor David Santos is the creator of a Ruby platform game we’ve mentioned a few times in the past year: Super Bombinhas.

The Ruby on Rails Podcast podcast

Rails is the 'One Person Framework' — Rails 7.0 was 2021’s big news, but DHH took some time to reflect on how he feels Rails is the perfect framework for a single person to use to “create modern applications upon which they might build a competitive business”.

David Heinemeier Hansson

Why I Don't Buy 'Duplication Is Cheaper Than The Wrong Abstraction'
Jason Swett

🛠 Code & Tools

Bullet 7.0: Help to Resolve N+1 Queries and Unused Eager Loading — Monitor your app’s database queries to find inefficiencies (N+1 queries, unused eager loading) for you to resolve. Works with Active Record and Mongoid.

Richard Huang

EBNF 2.3: An EBNF Parser and Generic Parser Generator — Supports LL(1) parsing as well as the packrat parser approach.

D.R.Y. Ruby

Seamlessly Integrate Video into Your Ruby App — Mux is an API-first platform that makes it easy to build beautiful video that streams everywhere.

Mux sponsor

immudb-ruby: A Ruby Client for an Immutable DatabaseImmuDB is an immutable ‘zero trust’-based database system written in Go.

Andrew Kane

ocktokit_scripts: Some Helpful Ruby Scripts Using Octokit to Automate Tasks in GitHub — There’s a label update script and a one to transfer a repo from a user to an organization.

Meg Gutshall

AttrJson: Serialized JSON-Hash-Backed Active Record Attributes — Focused on Postgres which has great native JSON type support.

Jonathan Rochkind

slack-ruby-client: A Ruby Client for Slack's Web, Real Time Messaging and Event APIs
Daniel Doubrovkine, Artsy and Contributors

devise_cas_authenticatable 2.0: CAS Authentication Support for Devise
Nat Budin

ActiveType 2.1.0: Make Any Object 'Quack' Like an Active Record Object

MessageBus: A Reliable and Robust Messaging Bus for Ruby and Rack
Sam Saffron

💡 Tip of the Week

Hash#except in Ruby 3+

If you're an avid Rails user, you might be familiar with ActiveSupport's Hash#except which has been around for roughly 15 years. As of Ruby 3.0, Hash#except is now a native Ruby method too!

But... what does it do? Hash#except gives us a hash excluding all of the keys we've passed as arguments. Let's look at an example:

jemma = { name: "Jemma",
          username: "jemma",
          password: "super secure" }

# => { name: "Jemma", username: "jemma" }

Before Ruby 3.0, if we were in a repo which wasn't using Rails, we could have done something like this:

jemma = { name: "Jemma",
          username: "jemma",
          password: "super secure" }

jemma.reject { |k,_| k == :password }
# => { name: "Jemma", username: "jemma" }

While this works totally fine, it gets a little clunky if we're trying to exclude multiple different keys. Yet Hash#except can also take multiple arguments:

jemma = { name: "Jemma",
          username: "jemma",
          password: "super secure" }

jemma.except(:name, :password)
# =>  { username: "jemma" }

Hash#except might look familiar because it's the inverse of Hash#slice. Hash#slice will give us a hash containing key / value pairs whose keys we specify as arguments, while Hash#except will give us a hash containing key / value pairs whose keys we don't specify as arguments.

We might be wondering, what happens if we pass a key that is not in the hash?

jemma = { name: "Jemma", username: "jemma",
          password: "super secure" }

jemma.except("key doesn't exist")
# => { name: "Jemma", username: "jemma",
       password: "super secure" }

In this case, Ruby is technically still excluding this key from our hash - it just never appeared in the hash to begin with. (This is the same behavior as Hash#slice.)

This week’s tip was written by Jemma Issroff.