ruby
46 lines · 7 steps
Typed environment variable config in Ruby
A module reads environment variables and coerces them into typed, validated config values with sensible defaults.
Explained by
highlit
1module AppConfig
2 module_function
3
4 def fetch(key, default: nil, required: false)
5 value = ENV[key]
6 if value.nil? || value.strip.empty?
7 raise KeyError, "Missing required env var: #{key}" if required
8 return default
9 end
10 value
11 end
12
13 def integer(key, default: nil, required: false)
14 raw = fetch(key, default: nil, required: required)
15 return default if raw.nil?
16 Integer(raw)
17 rescue ArgumentError
18 raise ArgumentError, "Env var #{key} must be an integer, got #{raw.inspect}"
19 end
20
21 def float(key, default: nil, required: false)
22 raw = fetch(key, default: nil, required: required)
23 return default if raw.nil?
24 Float(raw)
25 rescue ArgumentError
26 raise ArgumentError, "Env var #{key} must be a float, got #{raw.inspect}"
27 end
28
29 def boolean(key, default: false)
30 raw = fetch(key)
31 return default if raw.nil?
32 %w[1 true yes on].include?(raw.strip.downcase)
33 end
34
35 def list(key, default: [], separator: ",")
36 raw = fetch(key)
37 return default if raw.nil?
38 raw.split(separator).map(&:strip).reject(&:empty?)
39 end
40
41 DATABASE_URL = fetch("DATABASE_URL", required: true)
42 POOL_SIZE = integer("DB_POOL", default: 5)
43 TIMEOUT = float("REQUEST_TIMEOUT", default: 30.0)
44 DEBUG = boolean("DEBUG", default: false)
45 ALLOWED_HOSTS = list("ALLOWED_HOSTS", default: ["localhost"])
46end
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Centralizing env access behind one module gives you a single place to validate and coerce configuration.
- 2Coercing raw strings into integers, floats, booleans, and lists catches misconfiguration at boot instead of deep in the app.
- 3Raising descriptive errors for missing or malformed values turns silent misconfiguration into loud, actionable failures.
Related explainers
python
from configparser import ConfigParser, ExtendedInterpolation from pathlib import Path
Layered INI config loading in Python
configuration
parsing
defaults
Intermediate
8 steps
typescript
interface JwtPayload { exp?: number; iat?: number; sub?: string;
Decoding a JWT to check expiry
jwt
base64url
type-guards
Intermediate
8 steps
ruby
class ThumbnailPool def initialize(worker_count: 4, capacity: 100) @queue = SizedQueue.new(capacity) @running = true
A thread pool for thumbnail jobs in Ruby
concurrency
thread-pool
bounded-queue
Advanced
7 steps
go
package middleware import ( "net/http"
Localized validation errors in Gin
middleware
internationalization
validation
Intermediate
8 steps
ruby
require "csv" class CsvExporter def initialize(records, columns: nil)
Turning records into CSV in Ruby
csv
data-export
serialization
Intermediate
7 steps
javascript
async function uploadInBatches(records, uploadFn, { batchSize = 100, concurrency = 3 } = {}) { const batches = []; for (let i = 0; i < records.length; i += batchSize) { batches.push(records.slice(i, i + batchSize));
Uploading records with bounded concurrency
concurrency
worker-pool
async-await
Advanced
8 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/typed-environment-variable-config-in-ruby-explained-ruby-4b85/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.