Polished Ruby Programming
August 3, 2021 in ruby

I started reading Polished Ruby Programming by Jeremy Evans, author of the popular sequel and roda libraries. This is an advanced Ruby book, diving into the design principles, best practices, and trade-offs while programming Ruby. So far, it hasn’t disappointed. Here are my notes from the first chapter.

When to use core classes?

Only create custom classes when the benefits outweigh the costs.

With core classes, your code is more intuitive and in general, will perform better as it results in less indirection.

Use custom classes when you have to encapsulate the logic to write maintainable code. However, the benefits of encapsulation are not greater than the loss of intuition and performance.

Start with the core classes, and only add a custom class when you see a clear advantage.

Strings or Symbols?

Ruby is focused on programmer happiness and productivity, so it will often automatically convert a string to a symbol if it needs a symbol, or a symbol to a string if it needs a string.

A string in Ruby is a series of characters or bytes, useful for storing text or binary data. Unless the string is frozen, you can append to it, modify existing characters in it, or replace it with a different string.

A symbol in Ruby is a number with an attached identifier that is a series of characters or bytes.

The general principle is to use symbols when you need an identifier in your code, and strings when you need text or data.

Arrays, Hashes, or Sets?

Use an array if you need a simple list of values that you are iterating over or using the collection as a queue or a stack.

If you need a mapping of one or more objects to one or more objects, use a hash.

If you want a large list of unique objects and want to see whether a given object is contained in it, use a set.

Use Structs

It’s one of the underappreciated core class in Ruby. Struct allows you to create classes with one or more fields and automatically creates accessors for each field.

Using Struct, you can replace the following code:

class Artist
  attr_accessor :name, :albums

  def initialize(name, albums)
    @name = name
    @albums = albums
  end
end

with

Artist = Struct.new(:name, :albums)

Though Struct is lighter on memory than a regular class, it has slower accessor methods. It used to be faster than accessor methods in older versions of Ruby, but regular classes and attr_accessor methods have gotten significantly faster.

For maximum performance, stick to regular classes.