---
title: "The gift of Ruby 3.1"
publication: "Ruby Weekly"
issue: 585
published_at: "2022-01-06"
canonical_url: "https://rubyweekly.com/issues/585"
---

Plus Jemma's back with a Ruby 3 flavored tip of the week. |       

🗓 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](https://rubyweekly.com/issues/585)   

Ruby Weekly 

[![\](https://res.cloudinary.com/cpress/image/upload/w_1280,e_sharpen:60/a6a9y8a3rxscgdw7eagd.jpg)](https://www.ruby-lang.org/en/news/2021/12/25/ruby-3-1-0-released/)   

🎁 [Ruby 3.1.0 Released on Christmas Day](https://www.ruby-lang.org/en/news/2021/12/25/ruby-3-1-0-released/) — 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](https://dl.acm.org/doi/10.1145/3486606.3486781), 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](https://github.com/ruby/debug) which even plays nicely with VS Code and Chrome.
- [error_highlight](https://github.com/ruby/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](https://www.bigbinary.com/blog/ruby-3-1-adds-class-subclasses)
- And _a lot more.._ but see the item below! 

Yui Naruse   

[A Look at All of Ruby 3.1's Changes](https://rubyreferences.github.io/rubychanges/3.1.html) — 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   [![\](https://copm.s3.amazonaws.com/34c746c3.png)](https://www.hookrelay.dev/?utm_source=rubyweekly) 

[Stripe-Quality Webhooks for Everyone](https://www.hookrelay.dev/?utm_source=rubyweekly) — Get reliable inbound and outbound webhook delivery, with debugging and logging, in minutes. [Click here](https://www.hookrelay.dev/?utm_source=rubyweekly) to learn how. 

Hook Relay sponsor   

[How Ruby and Web Components Can Work Together](https://www.fullstackruby.dev/fullstack-development/2022/01/04/how-ruby-web-components-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](https://opalrb.com/blog/2021/12/24/opal-1-4/) — 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   

**IN BRIEF:** 

- There have been [_five_ RubyGems releases](https://blog.rubygems.org/#2021) since our last issue, though none are significant. [RubyGems 3.3.4](https://blog.rubygems.org/2021/12/29/3.3.4-released.html) is the latest.
- A retired, former teacher reflects on [their contributions to Ruby's documentation.](https://dev.to/burdettelamar/ive-been-contributing-to-ruby-documentation-3o82) Thanks for this work!
- Thomas Leitner has [benchmarked Ruby 2.5 through 3.1](https://gettalong.org/blog/2021/benchmarking-rubies.html) using HexaPDF. YJIT looks promising here, especially on longer running examples. 

**RELEASES:** 

[Dalli 3.2](https://github.com/petergoldstein/dalli) – High perf memcached client.
 [shoulda-matchers 5.1](https://github.com/thoughtbot/shoulda-matchers) – One liners for testing Rails functionality.
 [Fusuma 2.3](https://github.com/iberianpig/fusuma) – Multitouch gestures on Linux.
 [MemoWise 1.5](https://github.com/panorama-ed/memo_wise) – Smarter Ruby memoization.
 [Pygments.rb 2.3](https://github.com/pygments/pygments.rb/releases/tag/v2.3.0) – Syntax highlighting wrapper.
 [AnyCable 1.2](https://github.com/anycable/anycable)     

Jobs  

[Senior Ruby Engineer (Remote, EU Time Zones)](https://jobs.eu.lever.co/silverfin/29d0dc26-e51c-45a9-8157-53a8b9676ee1?lever-origin=applied&lever-source%5B%5D=RubyWeekly) — 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. 
Silverfin   

[Software Engineer (Remote)](https://grnh.se/9f59d68f2us) — Come join us at Invoca and help build cutting edge Conversation Intelligence systems using Rails, Python, GraphQL, and more. 
Invoca   

[Find Ruby Jobs Through Hired](https://hired.com/join/?utm_source=newsletter&utm_medium=sponsor&utm_campaign=%28b2c%29%28l-all%29%28r-all%29%28cooper-rubyweekly%29&utm_content=find-your-next-job) — Create a profile on Hired to connect with hiring managers at growing startups and Fortune 500 companies. It's free for job-seekers. 
Hired    

📕 Articles & Tutorials  

[Rails Authentication From Scratch](https://stevepolito.design/blog/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](https://www.codewithjason.com/ruby-instance-exec/) — 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](https://longliveruby.com/articles/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](https://crunchybridge.com/use-case/rails?utm_source=cp-rails&utm_medium=em) 

Crunchy Bridge sponsor   

▶[Talking about Game Development in Ruby with Victor David Santos](https://www.therubyonrailspodcast.com/397) — Victor David Santos is the creator of a Ruby platform game we’ve mentioned a few times in the past year: [Super Bombinhas](https://github.com/victords/super-bombinhas). 

The Ruby on Rails Podcast podcast   

[Rails is the 'One Person Framework'](https://world.hey.com/dhh/the-one-person-framework-711e6318) — 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'](https://www.codewithjason.com/duplication-cheaper-wrong-abstraction/) 
Jason Swett  

🛠 Code & Tools  

[Bullet 7.0: Help to Resolve N+1 Queries and Unused Eager Loading](https://github.com/flyerhzm/bullet) — 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](https://github.com/dryruby/ebnf) — Supports LL(1) parsing as well as the packrat parser approach. 

D.R.Y. Ruby   

[Seamlessly Integrate Video into Your Ruby App](https://get.mux.com/3mwSSfL) — 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 Database](https://github.com/ankane/immudb-ruby) — [ImmuDB](https://github.com/codenotary/immudb) 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](https://github.com/meg-gutshall/octokit_scripts) — 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](https://github.com/jrochkind/attr_json) — 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](https://github.com/slack-ruby/slack-ruby-client) 
Daniel Doubrovkine, Artsy and Contributors   

[devise_cas_authenticatable 2.0: CAS Authentication Support for Devise](https://github.com/nbudin/devise_cas_authenticatable) 
Nat Budin   

[ActiveType 2.1.0: Make Any Object 'Quack' Like an Active Record Object](https://github.com/makandra/active_type) 
Makandra   

[MessageBus: A Reliable and Robust Messaging Bus for Ruby and Rack](https://github.com/discourse/message_bus) 
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](https://github.com/rails/rails/commit/cb2381696029ad839ecddad08afea061d07685fb). As of Ruby 3.0, `Hash#except` is now a native Ruby method too! 

But... what does it do? [`Hash#except`](https://ruby-doc.org/core-3.1.0/Hash.html#method-i-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" }

jemma.except(:password)
# => { 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`](https://ruby-doc.org/core-3.1.0/Hash.html#method-i-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](https://twitter.com/jemmaissroff).          

Curated by [Peter Cooper](https://twitter.com/peterc), [Glenn Goodrich](https://twitter.com/ruprict) and [Cooperpress](https://cooperpress.com/). 

[Change your email address](https://rubyweekly.com/edit_subscription/*|UID|*) or[Stop getting this newsletter](https://rubyweekly.com/leave/*|UID|*) 

© Cooper Press Ltd · Fairfield Enterprise Centre, Louth, LN11 0LS, United Kingdom
