#​564 — August 5, 2021

Read on the Web

Ruby Weekly

Sorbet Compiler: Stripe's Experimental, Ahead-of-Time Compiler for Ruby — Stripe has been experimenting with an AOT compiler for Sorbet for about a year, and is now open-sourcing it for all to see. It’s not ready for production (outside of Stripe) yet, but the concept is solid, and the potential is exciting.

Sorbet

A Sneak Peek at Ruby's New Debugger — Ruby 3.1 will ship with a new debugger (clearly inspired by both GDB and byebug) that has some great features like scripting debug commands within your code so you don’t, for example, have to dig through gems to set breakpoints.

Stan Lo

Try Scout’s New Error Monitoring Feature Add-On for Free — Scout APM uses tracing logic that ties bottlenecks to source code so you know the exact line of code causing performance issues in minutes. See for yourself why Scout is a Ruby developers’s best friend with a free 14-day trial, no credit card needed.

Scout APM sponsor

The 2022 Fukuoka Ruby Award Competition — Every year the government of Fukuoka (a prefecture of Japan) teams up with Matz (the creator of Ruby) to offer a 1 million yen prize to the developer(s) of an ‘interesting Ruby program’ developed in the past year. So if you like competitions and think you can impress Matz, enter by December 3rd.

Fukuoka Ruby

▶  Matz's Talk at a Crystal Conference — We’ve mentioned Crystal, a Ruby-inspired compiled and statically typed language, a few times recently, and even Ruby’s creator gave a talk to the Crystal community where he showed support for their endeavors and said he ‘encourages the search’ for better solutions.

Yukihiro 'Matz' Matsumoto

Ruby Support Added to Compiler Explorer — If you’re not familiar with Compiler Explorer it’s a really neat tool for compiling code and letting you walk through the output (I’ve spent many an hour analyzing GCC optimizations with it with simple C code - yes, I’m a nerd) and it now shows you the VM code for Ruby code of your choice. I’d struggle to explain why this is neat, so.. have a play.

Matt Godbolt

Jobs

Senior Ruby on Rails Engineer (Remote) — Join our distributed team and build high-volume eCommerce applications in a workplace made by developers for developers.
Nebulab

Senior Rails Team Seek New Members — We’re seeking two experienced Rails devs to join our team. Cool tech, strong remote culture, solid FinTech product. ✌️
startuplandia.io

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.
Hired

📕 Articles & Tutorials

An Introduction to Pattern Matching in Ruby — Pattern matching is a new, experimental feature in Ruby 2.7 (certain features are stable in 3.0) inspired by Elixir. It seems foreign at first, but the utility soon becomes very apparent.

Pulkit Goyal

Running Rails on the Google Cloud Run EnvironmentCloud Run is Google’s service for running containerized apps in a serverless fashion.

Google Cloud

▶  Information Foraging: Tricks Great Developers Use to Find Solutions — Professor Austin Henley explains the tactics veteran developers use to quickly find the best solutions.

Stack Overflow Podcast sponsorpodcast

Esoteric Ruby in MemoWise — Frequent Tip of the Week contributor Jemma Issroff pens another post on the internals of MemoWise (a memoization gem) including how to memoize frozen objects and other oddities.

Jemma Issroff

Using ActiveRecord's #update_counters to Prevent Race Conditionsupdate_counter provides a convenient way to avoid race conditions when incrementing or decrementing values in the database.

Jonathan Miles

Deprecating Code in a Rails Application — Did you know ActiveSupport::Deprecation makes it pretty easy to add deprecation warnings to your own code? If plentiful deprecations are good enough for Rails, they're good enough for you ;-)

Aaron Sumner

Free eBook: Effective Indexing in Postgres

pganalyze sponsor

▶  Dynamic Select Fields in Rails with Hotwire — Want to dynamically update fields when a user changes a select box? Hotwire’s Turbo Stream actions to the rescue.

Go Rails

ActiveRecord::Calculations Will Now Use Column-based Type Casting
Swaathi Kakarla

Understanding Ruby: for vs each
Brandon Weaver

🛠 Code & Tools

Nokogiri 1.12.0 Released with New HTML5 Support — HTML5 support has been added (to the CRuby variant only) by merging Nokogumbo into Nokogiri, a still popular way to work with XML and HTML from Ruby. P.S. Did you know a 'nokogiri' is a type of Japanese saw? Hence the picture above.

Sparkle Motion

Six Command Line Tools for Productive Programmers — Some truly helpful items here. The FZF fuzzy file finder (written in Go) is particularly handy.

Adam Gordon Bell

MemoWise 1.1: The Modern Choice for Ruby Memoization — It’s fast, has good test coverage, full documentation, lets you reset or preset values, and more.

Panorama Education

Babosa: A Library for Creating Slugs — An extraction of code from FriendlyId for normalizing and sanitizing data for use as a simultaneously computer and human friendly identifier. Apparently babosa is Spanish for slug – it certainly sounds nicer.

Norman Clarke

Puma 5.4 Released: A Rack Web Server Built for Concurrency

Puma Team

SearchFlip 3.5.0: Full-Featured Elasticsearch Client with Chainable DSL — If you need Elasticsearch’s powerful brand of full text search in your Ruby apps, this is a worthy option.

Benjamin Vetter

💡 Tip of the Week



include

In last week's tip, we learned about ancestors. This set us up to learn about three ways of using code from a module in a class. This week, we'll discuss what is likely the most common of these approaches: include.

We can look at an example of using include to include a module's methods in a class:

module ExampleModule
  def example_method
    "This is defined in the module we're including"
  end
end

class ExampleClass
  include ExampleModule
end

ExampleClass.new.example_method
=> "This is defined in the module we're including"

What is actually happening when we include ExampleModule, or include any module or class, is that this module or class will be inserted in the ancestors chain directly after the class which includes it:

ExampleClass.ancestors
=> [ExampleClass, ExampleModule, Object, Kernel, BasicObject]

As we learned last week, this means that Ruby will first look for a method defined on ExampleClass, and if it's not defined there, it will continue to traverse the list of ancestors, looking next at ExampleModule.

This means using include gives us the helpful property of being able to easily override methods defined in an included module:

module ExampleModule
  def example_method
    "This is defined in the module we're including"
  end
end

class ExampleClass
  include ExampleModule
  
  def example_method
    "This is defined in ExampleClass itself"
  end
end

ExampleClass.new.example_method
=> "This is defined in ExampleClass itself"

If we're used to using include, we might have an intuitive understanding of this overriding in action. Hopefully now with the context around ancestors, we can see why it's happening. In the coming weeks, we'll have tips around two other ways of using code from modules or classes: extend and prepend.

This week’s tip was written by Jemma Issroff.