#540 — February 18, 2021

Read on the Web

💡 The Tip of the Week is back – see the end of the issue for that. It covers a Ruby 2.7 feature that makes a reasonably common task a single call and I'm very glad for its addition to the language 😄
__
Peter Cooper, editor

Ruby Weekly

A More Secure Bundler: How We Fixed Our Source Priorities — Last week there was a major story where a non-malicious developer pushed libraries to public repositories with the same name as private packages and these then took precedence over the private packages several companies’ systems expected to install. Uh-oh! While RubyGems.org was safe, Bundler was affected and v2.2.10 adds a fix to prioritize block sources in Gemfiles.

The Bundler and RubyGems Team

Adornable: A Way to Use Decorators on Ruby Methods — If you’ve ever looked at Python’s decorators or Lisp’s ‘advice’ and thought you’d like a similar way to extend Ruby methods, this is for you. The syntax is nice, although there’s a lot of magic behind the scenes, as you’d expect.

Keegan Leitz

Building Fast & Modern Web Applications with Rails & Hotwire — Taking Rails to the next level with Hotwire for faster, more responsive apps. Part 1 of our introduction to the different components of Hotwire: Turbo and Stimulus. We explore how these elements work and how they can be used in your own projects.

Cloud 66 sponsor

Using Webpacker in Your Rails Apps — A Deep Dive — A look under the hood of Webpacker (basically a Rails friendly wrapper for webpack as used in Rails 6).

Paweł Dąbrowski

Rails 6.1.3 Released — It’s a minor fix-oriented update. 5.2.4.5, 6.0.3.5 and 6.1.2.1 have also been released fixing two security issues.

Official Rails Blog

Quick Bits

  • RubyGems 3.2.10 has been released which installs Bundler 2.2.10 fixing the source priority issue in the top most feature of this issue.
  • RubyGems 3.2.11 quickly followed 3.2.10 (above) with a new feature to optionally fallback to IPv4 when an IPv6 network is unreachable.

💻 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

Experienced UK-Based Ruby/Rails Developer — We’re looking for a Rails dev to join our team to produce high-quality, tested code, working on an e-commerce platform that processes thousands of transactions daily.

Itison

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.

Hired

📘 Articles & Tutorials

Ruby Garbage Collection Deep Dive: Tri-Color Mark and Sweep — This article builds on Jemma’s previous outing on the internal constants used by Ruby’s garbage collector and teaches us more about how Ruby manages memory.

Jemma Issroff

▶  Ruby Game Development with the DragonRuby Game Toolkit — If you love Ruby but fancy a break from building webapps, say, how about creating your own game? This 18 minute screencast introduces how DragonRuby works at the technical level.

Amir Rajan

3 Tips to Tune Your VCR in TestsVCR is a long standing tool for recording HTTP interactions and replaying them during test runs. This post shares three techniques for improving its usage.

Pawel Pacana

Free eBook: Efficient Search in Rails with Postgres — Speed up a search query from seconds to milliseconds and learn about exact matches, trigrams, ILIKE, and full-text search.

pganalyze sponsor

How to Use Sidekiq in Rails 6 — A post from last year about the popular background-processing system but just updated for Rails 6.1 and Sidekiq 6.1.3 – there’s also a guide for getting it running on Heroku.

Catalin Ionescu

Don’t Wrap Instance Variables in attr_reader Unless Necessary — While there are purported benefits of using attr_reader, some of them are specious at best, plus you’re changing the public interface of the class, which may not be your intention.

Jason Swett

Tensors using NumRubyNumRuby is a SciRuby-related project for doing fast numerical linear algebra in Ruby.

Udit Gulati

Tip: Use Rails' link_to_unless_current for Your Navigation Links

Matt Swanson

ActiveRecord For Databases Without Unique Ids — The real takeaway is: Don’t do this. However, the journey to make AR work is an interesting code romp.

Regan Ryan (Honeybadger)

▶  Bridgetown: Ruby on the Jamstack, or Why I Forked Jekyll — Jared White discusses why he decided to fork Jekyll and create the Bridgetown static site generator.

YouTube

🛠 Code and Tools

Chewy 6.0: A High-Level Elasticsearch Framework — An ODM and wrapper for working with Elasticsearch in a more idiomatically Ruby, developer-friendly way (check out the examples in the README). This week’s 6.0 release adds Elasticsearch 6 support and there’s a brief migration guide.

Toptal

Avro::Builder: A Ruby DSL to Create Apache Avro SchemasApache Avro is a schema-driven data serialization system.

Salsify

Founders/CTO’s: Can't Scale in Production? Let’s Talk

Hint sponsor

twterm: A Terminal UI Twitter Client — Want a day to day Twitter client on the terminal? This is one option. Packaged up with nix for easier installation if you’re a nix user.

Ryota Kameoka

Kittyverse: Helper Classes for Cryptokitties Related Data — Honestly, I have no idea what is going on here.. 😂

The CryptoCopycats

Rpush 5.4: A Push Notification Service for Ruby — A long standing project. Rpush supports numerous push notification services including those from Apple, Firebase, and Amazon, and this new release adds Ruby 3 and Rails 6.1 support.

Ian Leitch

RuboCop 1.10: The Ruby Static Code Analyzer and Formatter

RuboCop Headquarters

💡 Tip of the Week

Tallying and Counting

Counting is one of the many things computers do better than humans. Ruby's Enumerable#tally, introduced in Ruby 2.7, makes counting even more straightforward.

It counts the occurences of each element in a collection, and returns a hash whose keys are all of the distinct elements in the collection, and whose values are the number of times each key appears.

Pre Ruby 2.7, if we wanted a hash which gave us counts of the elements in a collection, there were a few less straightforward ways we could do it. One example of code we might have written is:

[1, 2, 0, 2, 2, 3, 2, 1, 3].group_by(&:itself).transform_values(&:size)
=> {1=>2, 2=>4, 0=>1, 3=>2}

Luckily, we now have Enumerable#tally which makes this same functionality cleaner to write and easier to read. Let's look at a couple of examples:

[1, 2, 0, 2, 2, 3, 2, 1, 3].tally
=> {1=>2, 2=>4, 0=>1, 3=>2}

%w(r u b y w e e k l y).tally
=> {"r"=>1, "u"=>1, "b"=>1, "y"=>2,
    "w"=>1, "e"=>2, "k"=>1, "l"=>1}

As we can see, the keys are the elements in each array, and the values are their counts. If we were only interested in the number of times a specific element appeared in an Enumerable, we could also use Enumerable#count which takes an element as a parameter. For example:

[1, 2, 0, 2, 2, 3, 2, 1, 3].count(1)
=> 2

[1, 2, 0, 2, 2, 3, 2, 1, 3].count(5)
=> 0

Hopefully Enumerable#tally and Enumerable#count help with any Ruby counting needs!

This week’s tip was written by Jemma Issroff.