Syntax and blocks

Objects everywhere, the naming rules that reveal scope, and the block syntax that makes idiomatic Ruby readable.

Everything is an object

# frozen_string_literal: true

name = "Ada"
count = 3
ratio = 0.75
active = true
nothing = nil
status = :draft

puts "Hello, #{name}"        # interpolation works in double quotes
puts 'Hello, #{name}'        # single quotes print it literally

puts name.upcase
puts [3, 1, 2].sort.join(", ")

age = 30
label = if age >= 18 then "adult" else "minor" end
puts label
  • Everything is an object, including nil, integers and classes themselves: 3.class is Integer.
  • Variables need no declaration, and the sigil reveals scope: local, @instance, @@class, $global, and CONSTANT in capitals.
  • nil and false are the only falsy values, so 0, an empty string and an empty array are all truthy.
  • Symbols such as :draft are immutable interned names, which is why they are the usual hash key and state value.
  • Naming carries meaning: a trailing ? marks a predicate, a trailing ! marks a mutating or surprising variant, as in sort versus sort!.

Blocks, procs and lambdas

[1, 2, 3].each { |n| puts n * 2 }

[1, 2, 3, 4].each do |n|
  next if n.even?        # skip to the next iteration
  puts n
end

# yield runs the block given to the method
def repeat(times)
  times.times { |i| yield i } if block_given?
end
repeat(2) { |i| puts "tick #{i}" }

# lambda: strict about arity, returns like a method
add = ->(a, b) { a + b }
puts add.call(2, 3)
puts add.(4, 5)

# returns an Enumerator when no block is given
def each_pair(list, &block)
  return to_enum(:each_pair, list) unless block
  list.each_cons(2, &block)
end
MethodReturns
eachThe original collection, not the block results
map / collectA new array of transformed values
select / rejectA new array filtered by the block
reduce / injectA single accumulated value
each_with_objectThe object you passed in, for building a hash
partitionTwo arrays: those matching and those not
filter_mapTransformed values with nils dropped
💡
each returns the receiver, not the transformed values. Reaching for each to build a new collection is the most common Ruby mistake — use map, select or filter_map instead.

FAQ

Block, proc or lambda?
A block is the inline code you pass to a method. Wrap it in a lambda when you need strict argument checking and a normal return; use a proc when you want the looser behaviour.
Why is my string interpolation printed literally?
Single-quoted strings do not interpolate escapes or #{...}. Use double quotes, and reserve single quotes for strings that must be taken literally.

Objects, modules and exceptions Standard library and a short note on Rails

Last refreshed 2026-09-18.