---
title: "Ruby"
description: "21 posts about Ruby, summarised, each linking to the original."
---

# Ruby
> 21 posts about Ruby, summarised, each linking to the original.

## Articles

### [Implementing Equality in Ruby](https://yomu.fyi/post/implementing-equality-in-ruby.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: May 26, 2022

Ruby has several equality and comparison mechanisms, so custom classes need explicit implementations when instance identity is not the intended meaning. The post distinguishes value objects, whose equality depends on all attributes, from entities, whose equality depends on an explicit identifier; its Point and Employee examples also use class checks, while an entity with a nil ID is unequal to other entities. It defines reflexivity, symmetry, and transitivity as properties to preserve, notes NaN as an exception to reflexivity, and explains #equal?, #eql?, #hash, and #===. For ordered values, #<=> returns -1, 0, 1, or nil, while Comparable supplies relational operators and useful methods including #min, #sort, #between?, and #clamp.


### [How to Build a Web App with and without Rails Libraries](https://yomu.fyi/post/how-to-build-a-web-app-with-and-without-rails-libraries.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Mar 26, 2021

This tutorial builds Mirth, a Ruby web application that lets users view displayed data and enter new data that persists, using a birthday tracker as its example. It first constructs the application with core Ruby libraries, explaining TCP sockets, HTTP requests and responses, persistent storage, and the need for a web server interface such as Rack. It then replaces that lower-level code with Rails libraries, including Action Controller, Action Dispatch, Active Record, and Action View, while using ERB templates and a configured view path. The tutorial shows how routing, database access, request handling, and HTML generation fit together, with the application available at localhost:1337/birthdays after the Rails-library version is run. Its conclusion is that building from scratch clarifies the implementation details Rails hides, while Rails remains the practical choice for web development.


### [Remove Circular Dependencies by Using Dependency Injection and the Repository Pattern in Ruby](https://yomu.fyi/post/remove-circular-dependencies-by-using-dependency-injection-and-the-rep.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Mar 19, 2021

An internal Ruby pricing gem used by Shopify Core and Storefront Renderer needed consumer-owned data while retaining shared pricing knowledge, creating a circular dependency. The proposed design puts calculation logic and shared domain types in a stateless gem, while each consumer implements a repository contract for retrieving and returning the required data. Constructor injection passes a PricingRepositoryInterface implementation into PricingEngine::Engine, and Sorbet interfaces and function signatures enforce implemented methods and expected return types. Testing separates gem-isolated tests using repository mocks, consumer unit tests for repository behavior, and integration tests confirming the gem works within each consumer. The result, according to the post, is removal of the circular dependency and a typed contract that makes consumers responsible for data access.


### [Simplify, Batch, and Cache: How We Optimized Server-side Storefront Rendering](https://yomu.fyi/post/simplify-batch-and-cache-how-we-optimized-server-side-storefront-rende.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Dec 10, 2020

The post explains how a new Ruby-based server-side Storefront Renderer reduced the time required to serve Shopify storefront requests. It combines MySQL multi-statement queries, handcrafted SQL, a thin data-mapping layer built from plain old Ruby objects, query book-keeping with eager- and lazy-loading, multiple LRU caching layers, and techniques for reducing memory allocations. For a product page, one database round trip can load the product, variants, images, shop, theme, and related resources; later requests can replay previously observed queries early, while less frequently used data remains lazy-loaded. The resulting renderer serves 75% of requests in under ~45ms, 90% in under ~230ms, and 99% in under ~900ms, with average response time nearly five times faster than the previous implementation.


### [The State of Ruby Static Typing at Shopify](https://yomu.fyi/post/the-state-of-ruby-static-typing-at-shopify.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Dec 7, 2020

Shopify’s Ruby monolith receives about 400 commits and 40 deployments daily, spanning 37,000 files, 622,000 methods, and over 2,000,000 calls, making correctness difficult despite rigorous review and 150,000 automated tests. Since 2018, Shopify’s Ruby Infrastructure team has pursued static typing and adopted Sorbet, discussed in a 2020 Shipit! event. The post describes Sorbet’s handling of simple collections such as T::Array\[Integer\], nested types using T.untyped, and dedicated classes for complex structures, while noting obstacles involving ActiveSupport::Concern, implicit inclusion requirements, metaprogramming, and dynamic GraphQL resolvers. For Rails projects, guidance is to begin with typed: false, generate RBI files using Tapioca or sorbet-rails, then move suitable files toward typed: true based on reuse, errors, collaboration, or churn, checking generated files into the repository.


### [Static Typing for Ruby](https://yomu.fyi/post/static-typing-for-ruby.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Nov 19, 2020

Shopify’s Ruby monolith spans 37,000 files, 622,000 methods, and more than 2,000,000 calls, making fast feedback and stability difficult despite rigorous reviews and 150,000 automated tests. Sorbet was selected after the team evaluated requirements for gradual typing, speed, and support for Ruby and Rails features including metaprogramming, overloading, and class reopening. Its RBI files represent constructs it cannot infer, while per-file sigils allow adoption to progress without blocking development, and SorbetMetrics tracks sigils, typed calls, and method signatures. Shopify treats typing as a product, combining CI enforcement, developer support, surveys, and interviews to guide rollout and measure sentiment. The excerpt reports 80% of monolith files, including tests, at typed: true or higher, with almost half of calls and methods covered and type checking under 15 seconds on developer machines.


### [Adopting Sorbet at Scale](https://yomu.fyi/post/adopting-sorbet-at-scale.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Nov 19, 2020

Shopify describes its adoption of Sorbet static typing across a Ruby monolith containing 37,000 files, 622,000 methods, and more than 2,000,000 calls. At the time of writing, Sorbet ran on every pull request, 80% of files were typed: true or higher, almost half of calls were typed, and half of methods had signatures. To handle Ruby and Rails idioms, the team built RuboCop Sorbet for compatibility rules, Tapioca for gem and DSL RBI generation, and Spoom for programmatic tooling, metrics, and LSP access. A controlled experiment found fewer production NoMethodErrors in files typed: true after typing about 20% of the application, although the results were preliminary and signatures had not yet been added. Shopify planned to reach typed: true across all files, improve Rails support, and continue collaboration around Sorbet and RBS.


### [Enforcing Modularity in Rails Apps with Packwerk](https://yomu.fyi/post/enforcing-modularity-in-rails-apps-with-packwerk.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Sep 23, 2020

Large Rails monoliths can develop high coupling, low cohesion, cross-component calls, shared Active Record models, and classes that know too much because Ruby and Rails provide limited boundary enforcement. Shopify created Packwerk, an open-source static analysis tool that groups Ruby files into packages and enforces dependency and privacy boundaries, including controlled public APIs for constants. It reports the violation type and location with actionable next steps, integrates with CI, and can run locally; installation begins by adding the gem and running packwerk init. Because Ruby static analysis is complex, Packwerk ignores constants that are not autoloaded, reducing false positives at the cost of false negatives. The excerpt says it runs in six Shopify Rails applications, with 48 packages and 30 boundary enforcements in the core codebase, while adoption also prompted work on dependency inversion.


### [Under Deconstruction: The State of Shopify’s Monolith](https://yomu.fyi/post/under-deconstruction-the-state-of-shopify-s-monolith.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Sep 16, 2020

Shopify describes the ongoing effort to modularize its core Ruby on Rails monolith, which contains more than 2.8 million lines of Ruby and 500,000 commits. The initiative organizes code into independently owned components intended to narrow developer focus, reduce affected test suites, preserve contracts, and clarify operational ownership, while recognizing that large-scale refactoring is also a people problem. The work has already improved exception triage, distributed codebase chores, and design awareness, while its current practices emphasize grassroots participation, tooling, targeted reviews, and a holistic architectural view. Packwerk restricts dependencies for about a third of the 37 main-monolith components. Shopify is pursuing a cleaner dependency graph, componentized Rails applications by default, and isolated component tests, while reserving service extraction for cases such as storefront rendering and credit-card vaulting.


### [How Shopify Reduced Storefront Response Times with a Rewrite](https://yomu.fyi/post/how-shopify-reduced-storefront-response-times-with-a-rewrite.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Aug 20, 2020

Shopify rewrote the server-side Storefront Renderer, which loads Liquid themes and storefront data before returning HTML, because the legacy Rails-monolith implementation had developed stricter performance demands and rising time-to-first-byte as traffic grew. The new single-purpose application separates storefront traffic from checkout, admin, and API traffic, uses active-active replication with dedicated read replicas, and adds mechanisms for high-load resilience. During migration, a Ruby verifier compares status codes, headers, and bodies from both implementations, while a custom Lua module on OpenResty samples production traffic and routes requests based on verification results. The rollout had reached more than 90% feature parity, and the new implementation averaged 4x faster server response times, with ongoing work aimed at full parity and retiring the legacy system.


### [How We Built Size.link](https://yomu.fyi/post/how-we-built-size-link.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Jul 13, 2020

Size.link is a free Shopify AR tool that lets shoppers view a product’s dimensions in their surroundings through a smartphone camera. It was created during April Hack Days as a quick alternative to commissioning 3D models, with requirements including browser-based operation, speed, accuracy, and iOS and Android support. Because iOS lacks JavaScript WebAR, the implementation uses AR Quick Look with USDZ files and Android’s Scene Viewer with GLB files. Rather than generate files dynamically with slow USDZ tooling or pre-generate billions of dimension combinations, the team modifies binary template data, replacing scale or vertex float values to resize the cube while preserving its outline. The resulting Ruby server generates USDZ files in well under one millisecond, and the same strategy produces GLB files; future work could add textures for standard-sized products.


### [Media at Scale: Callbacks vs pipelines](https://yomu.fyi/post/media-at-scale-callbacks-vs-pipelines.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Jul 9, 2020

Shopify’s Rails monolith needed to add native product videos and 3D models while continuing to support an image infrastructure containing more than 7 billion images. The design question was whether media creation should rely on Active Record callbacks or an explicit pipeline, with transactions protecting interdependent database writes. Callbacks were quick for simple cases, but adding media-specific behavior such as video thumbnails spread conditionals across models and made lifecycle ordering difficult to follow and debug. The pipeline design routes requests through a single Product Create Media Service and media handlers, each organized into before\_transaction, during\_transaction, and after\_transaction steps, while confining logic to one media type. This structure separates concerns, controls creation order, limits model access, and makes implementation details easier to understand and maintain as the feature grows.


### [Writing Better, Type-safe Code with Sorbet](https://yomu.fyi/post/writing-better-type-safe-code-with-sorbet.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Jun 24, 2020

Ruby repositories can hide unsafe method calls and ambiguous data shapes when types are inferred from variable names alone. Sorbet static type checking addresses these risks with method signatures, typed structs, enums, and interfaces. It can flag a potentially nil return before a chained call, distinguish database output fields from input fields, and enforce contracts for synchronous and asynchronous indexers in a dependency-injected hexagonal structure. The article also describes Sorbet’s gradual typing, including five strictness levels and namespace-by-namespace adoption using the minimum typed level of true. The stated conclusion is that enforced type safety catches errors unit tests may miss and helps prevent unsafe code from reaching production.


### [Spark Joy by Running Fewer Tests](https://yomu.fyi/post/spark-joy-by-running-fewer-tests.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Jun 11, 2020

Shopify’s monolithic Ruby repository has more than 150,000 tests, grows 20–30% annually, and takes 30–40 minutes to run across hundreds of Docker containers, making required full-suite CI costly and vulnerable to intermittent failures. The team built a dynamic-analysis test-selection system that logs method calls during each test, records files in each call graph, and maps changed files to relevant tests. Because Ruby, Rails metaprogramming, and non-Ruby files complicate tracing, the system adds Rails patches and fallback rules, runs extra tests when mappings lag, and executes the full suite asynchronously on every deploy. After two months and 8,360 merged commits, it achieved 99.94% failure recall, selected about 60% of tests, and reduced compute time by roughly 25%. Developers requested full-suite runs on fewer than 2% of pull requests.


### [Understanding Programs Using Graphs](https://yomu.fyi/post/understanding-programs-using-graphs.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Jun 2, 2020

TruffleRuby uses a sea-of-nodes graph as an intermediate representation after parsing, allowing its just-in-time compiler to optimize Ruby programs and translate them to machine code. The explanation contrasts this graph with an abstract syntax tree, then shows how control flow, data flow, side effects, pure computations, loops, and phi nodes are represented through boxes and arrows. A three-way conditional demonstrates global value numbering: a repeated multiplication becomes one movable computation that can float across branches without changing program behavior. A loop example shows backward control flow and repeated functional computation, while the discussion weighs graph-based optimization against poor compactness and readability at larger scales. Shopify is building graph-drawing and Ruby decompilation tools to inspect optimization at codebase scale.


### [Dev Degree: Behind the Scenes](https://yomu.fyi/post/dev-degree-behind-the-scenes.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: May 13, 2020

Dev Degree is Shopify’s work-integrated learning program, designed to combine an accredited computer science degree with four years of continuous developer experience. Students take three university courses per semester while working 25 hours weekly, beginning with Shopify-led skills training before moving through four team placements across disciplines such as back-end, front-end, data, security, and production engineering. The program teaches tools and technologies including Git and GitHub, Ruby, Rails, React, TypeScript, and GraphQL, while emphasizing mentorship, feedback, personal development, and support from a multidisciplinary team working with university partners. The first cohort graduated on April 24, 2020, after adapting to program changes and remote learning during the pandemic; the post reports that 100% of graduates accepted full-time positions within six months.


### [How to Fix Slow Code in Ruby](https://yomu.fyi/post/how-to-fix-slow-code-in-ruby.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: May 8, 2020

Performance regressions can accumulate in a large monolithic Rails application, making it difficult to identify offending changes among thousands of daily commits. The post presents profiling and benchmarking as complementary practices: profiling locates runtime bottlenecks, while benchmarking compares code paths and validates fixes. It covers elapsed time, CPU versus wall time, object allocations, TracePoint and ObjectSpace, plus rbspy, stackprof, rack-mini-profiler, and App Profiler, which supports on-demand remote production profiling at Shopify. A flamegraph example showed garbage collection consuming about 35% of CPU time in a slow request, and the team inferred excessive Ruby object allocation; a Rails benchmark showed roughly 50x improvement from caching an order’s total price calculation. The discussion cautions against micro-optimizations whose gains do not justify code changes and recommends addressing larger performance issues first.


### [Optimizing Ruby Lazy Initialization in TruffleRuby with Deoptimization](https://yomu.fyi/post/optimizing-ruby-lazy-initialization-in-truffleruby-with-deoptimization.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Mar 31, 2020

The post examines how TruffleRuby can optimize Ruby’s ||= operator when it is used for lazy initialization rather than repeated assignment. Static profiling of 20 popular open-source projects found 2,082 uses, with 64% meeting conservative criteria based on constant values or naming patterns for parameterless methods assigning instance or class variables. The implementation replaces the usual OrNode with an OrLazyValueDefinedNode, which counts executions of the right-hand side and deoptimizes when it is executed fewer than twice, allowing uncommon assignment paths to remain in the interpreter. In a benchmark, the change compiled code about 6% faster and produced about 63% less machine code by memory, although the post notes that benchmarking larger projects is noisy and the runtime impact is difficult to prove.


### [Sam Saffron AMA: Performance and Monitoring with Ruby](https://yomu.fyi/post/sam-saffron-ama-performance-and-monitoring-with-ruby.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Nov 5, 2019

Sam Saffron discusses Discourse’s approach to Ruby performance and monitoring, arguing that production memory constraints matter more than isolated microbenchmarks for many deployments. He favors clear code and selective optimization, sometimes bypassing ActiveRecord with MiniSql on performance-sensitive paths rather than broadly sacrificing Ruby’s readability. Discourse keeps performance under continuous observation, and Saffron describes budgets for dependencies, boot time, and high-profile pages, including alerts for query-count regressions. He identifies memory leaks as especially difficult to diagnose, describes bisecting an application to isolate a V8-Ruby interop leak, and says MRI remains the only feasible runtime for Discourse while memory profiling and analysis tooling remain substantially behind Java and .NET.


### [How to Write Fast Code in Ruby on Rails](https://yomu.fyi/post/how-to-write-fast-code-in-ruby-on-rails.md)
- Company: [Shopify](https://yomu.fyi/company/shopify.md)
- Author: 2023-10-18
- Published: Oct 8, 2019

Shopify’s guide presents performance advice for Ruby on Rails across Active Record, Rails, and Ruby, while treating speed as a feature rather than the first optimization priority. It recommends understanding Active Record’s lazy query execution, selecting fewer columns, avoiding unindexed queries, using safe indexing approaches for large tables, and treating query cache as short-lived rather than dependable. For Rails applications, it covers caching, throttling expensive or abusive operations, moving long-running work into Active Job-backed queues, and reducing dependency growth to limit boot time and memory use. Ruby-specific guidance includes limiting metaprogramming and indirection, choosing O(1) hash lookups over O(n) array searches when appropriate, and reducing allocations while avoiding harmful global mutation; benchmark figures show method-definition and invocation costs can differ.


[Older posts](https://yomu.fyi/topic/ruby/page/2.md)
