#537 — January 28, 2021

Read on the Web

💡 The Tip of the Week is back! If you missed last week's, feel free to step back in time, but otherwise this week's is at the end of the issue, as before. You might also want to follow Jemma on Twitter as she's currently writing a book about garbage collection and has posted some interesting tweets so far.
Peter Cooper, editor

Ruby Weekly

RBS: The New Ruby 3 Typing Language in Action — We briefly covered what RBS was when Ruby 3.0 launched but.. it’s not the easiest thing to get your head around. This article goes into more depth and is a worthwhile introduction (and comparison to Sorbet) if typed Ruby intrigues you.

Diogo Souza

Designing a Ruby Serverless Runtime for Google Cloud Functions — A senior software engineer at Google digs into the design decisions and trade-offs involved in bringing Ruby support to Google Cloud Functions.

Daniel Azuma

Complete Peace of Mind Rails Hosting — If you need 100% peace of mind Rails hosting, OpsCare is for you. Built on our custom stack with comprehensive yet flexible deployment, scaling and monitoring tools, we keep your application online and performing, 24 hours a day, 7 days a week.

OpsCare by reinteractive sponsor

Logidze 1.0: Active Record, Postgres, Rails, and Time Travel — The rather tricky to pronounce Logidze is a library that tracks changes made to tables managed by Active Record by way of Postgres triggers and a JSONB record. It proudly claims to be the ‘fastest gem for auditing models in the Rails ecosystem.’

Vladimir Dementyev

How ActiveRecord Uses Caching To Avoid Unnecessary Trips to the Database — Jonathan talks about caches that we don’t need to mess with (counter cache, SQL action cache, lazy evaluation), but it’s good to know how to mess with it for edge cases.

Jonathan Miles

Quick Bits

📘 Articles & Tutorials

Object#tap And How To Use It — I think my favorite part of this explanation of this oft-confusing method is the reasoning behind its name, which now makes perfect sense.

Tom Dalling

What Week Is It Anyway? — Working with dates and times is hard. Time zones and mind-bending edge cases make tests flaky and bugs hard to reproduce. This two-part series walks through two such cases. Did you know that some years have 53 weeks?

Barbara Litwińska

Some Interesting throw/catch Behavior — Did you know that catching a throw means none of the rescue clauses are executed?

Janko Marohnić

Find Out What Developer & Community Relations as a Service Can Mean — We help build and work with communities through content, events, podcasts, and more. Get your message to the right people now.

DevRelate.io sponsor

How to Run Tests in Parallel on GitHub Actions — An advanced use case for GitHub Actions right here.

Axel Kee

How to Memoize Expensive Code — A nice reminder of a basic performance improving technique.

Andy Croll

Rails 6.1 Improves Support for Postgres' Interval Data Type — The code to do this is now much easier to read.

Akhil Gautam

Two Patterns for StimulusReflex Form Submissions — This presumes you are somewhat comfortable with StimulusReflex, providing a way to handle your form submissions in a reusable manner.

Julian Rubisch

🛠 Code and Tools

mini_phone: A Fast Phone Number Library for Ruby — mini_phone uses Google’s libphonenumber so it’s very fast, integrates with ActiveRecord, and aims to be a drop-in replacement for Phonelib (another phone number gem.)

Ian Ker-Seymer

Chaskiq: A Rails + React Powered Conversational Marketing Platform — Imagine an open source, self hosted version of Drift, Intercom, and the like. It’s now up to Rails 6.1 standards and there have been a few releases since we mentioned it last. An interesting example of a large scale, open source Rails app.


Founders/CTO’s Slow or Failing CI Killing Productivity? We Can Help

Hint sponsor

Brakeman 5.0.0: A Security Vulnerability Scanner for Rails Apps — A list of what’s new in today’s release.

Justin Collins

Rack::Attack 6.4.0: Rack Middleware for Blocking and Throttling — This release brings Ruby 3.0 support and drops Ruby 2.3.

Rack Project

ruby-dns-mock: Mimic Any DNS Records for Your Test Environment

Vladislav Trotsenko

💻 Jobs

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.


Full-Stack/Backend Software Engineer (Fully Remote/US) — Small team innovating supply chain collaboration for Fortune 1000 companies. Former Uber Freight founders. Built with empathy and no egos.

Isometric Technologies

Find Your Next Job 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.


ℹ️ Interested in running a job listing in Ruby Weekly? There's more info here.

💡 Tip of the Week

Using Comparable#clamp to limit a value to within a range

Forcing a value to fall within a range became a whole lot easier when Ruby 2.4 introduced Comparable#clamp.

Comparable#clamp takes min and max arguments. If the value we're "clamping" is within the min and max, Comparable#clamp returns the value unchanged. Otherwise, if the value is less than min, Comparable#clamp returns min, and if the value is greater than max, Comparable#clamp returns max:

=> 1

=> 2

"jemma".clamp("a", "z")
=> "jemma"

"jemma".clamp("a", "j")
=> "j"

And then, just when we were getting really excited about Comparable#clamp, Ruby 2.7 gave us even more to work with! As of Ruby 2.7, clamp can also take an inclusive .. (not exclusive ...) range of values.

Notably, nil can be within this range. val.clamp(..max) will be the equivalent of taking the minimum of val and max. And vice versa. Let's take a look:

=> 2

=> 1

And lastly, just as a reminder, the Comparable mixin is used by classes whose objects can be comparaed and therefore ordered. If you'd like to have clamping work for a class you've written, be sure to include Comparable and define the <=> operator.

This week’s tip was written by Jemma Issroff.