ruby
41 lines · 9 steps
Recursively freezing nested Ruby data
A recursive helper walks any nested structure and freezes every object inside, giving you deeply immutable constants.
Explained by
highlit
1module DeepFreeze
2 module_function
3
4 def call(obj)
5 case obj
6 when Hash
7 obj.each { |key, value| call(key); call(value) }
8 obj.freeze
9 when Array, Set
10 obj.each { |element| call(element) }
11 obj.freeze
12 when Range
13 call(obj.begin)
14 call(obj.end)
15 obj.freeze
16 when Struct
17 obj.each_pair { |_, value| call(value) }
18 obj.freeze
19 else
20 obj.freeze
21 end
22
23 obj
24 end
25end
26
27class Configuration
28 SUPPORTED_CURRENCIES = DeepFreeze.call(%w[USD EUR GBP JPY])
29
30 RATE_LIMITS = DeepFreeze.call(
31 free: { requests_per_minute: 60, burst: 10 },
32 pro: { requests_per_minute: 600, burst: 100 },
33 enterprise: { requests_per_minute: 6_000, burst: 1_000 }
34 )
35
36 FEATURE_FLAGS = DeepFreeze.call(
37 beta_search: false,
38 dark_mode: true,
39 allowed_hosts: %w[app.example.com api.example.com]
40 )
41end
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1`freeze` only affects the top object, so deep immutability requires walking every nested element yourself.
- 2A `case` over container types lets one recursive method handle hashes, arrays, ranges, and structs uniformly.
- 3Returning `obj` after freezing lets the helper wrap constant assignments inline.
Related explainers
ruby
module ConfigMerge module_function def deep_merge(base, override)
Recursively merging nested config hashes in Ruby
recursion
hash-merge
immutability
Intermediate
8 steps
ruby
class Webhooks::StripeController < ApplicationController skip_before_action :verify_authenticity_token skip_before_action :authenticate_user!
How a Rails Stripe webhook controller works
webhooks
signature verification
event dispatch
Intermediate
7 steps
java
public record ServerConfig(String host, int port, boolean tls, List<String> allowedOrigins) { public ServerConfig { Objects.requireNonNull(host, "host is required");
Validating config with a Java record
records
validation
immutability
Intermediate
9 steps
python
from functools import lru_cache import math
Memoizing number theory with lru_cache
memoization
number-theory
caching
Intermediate
8 steps
ruby
class ReportGenerator def initialize(account, period) @account = account @period = period
Memoized report metrics in Ruby in Rails
memoization
query-composition
service-object
Intermediate
7 steps
javascript
export function cloneState(state) { if (typeof structuredClone !== "function") { throw new Error("structuredClone is not available in this runtime"); }
Deep cloning with structuredClone
deep-copy
error-handling
immutability
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/recursively-freezing-nested-ruby-data-explained-ruby-8946/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.