Useful Ruby methods and tips that you might not know (or remember)
“Code is like humor. When you have to explain it, it’s bad.” — Cory House
Enumerable Methods
Enumerable#tally
The tally method groups and counts elements in an enumerable. It’s great for frequency analysis.
irb> ["apple", "banana", "apple", "orange"].tally
=> {"apple"=>2, "banana"=>1, "orange"=>1}
Enumerable#inject
inject
accumulates a result by applying a block to each element. It’s useful for summing, multiplying, and more.
Using with an accumulator:
irb> [1, 2, 3, 4].inject(0) { |sum, num| sum + num }
=> 10
Or passing a method proc as argument:
irb> [1, 2, 3, 4].inject(:+)
=> 10
Enumerable#chunk
chunk
groups consecutive elements based on a block condition.
irb> [1, 2, 2, 3, 1, 1].chunk(&:even?).to_a
=> [[false, [1]], [true, [2, 2]], [false, [3]], [true, [1, 1]]]
Enumerable#each_with_object
each_with_object
iterates and builds an object like a hash or array.
irb> ["apple", "banana"].each_with_object({}) { |fruit, hash| hash[fruit] = fruit.length }
=> {"apple"=>5, "banana"=>6}
Enumerable#slice_when
slice_when
splits an enumerable when the block returns true.
irb> [1, 3, 6, 10].slice_when { |a, b| (b - a) > 3 }.to_a
=> [[1, 3, 6], [10]]
Enumerable#flat_map
flat_map
maps and flattens the result in one step.
irb> [[1, 2], [3, 4]].flat_map { |arr| arr.map { |x| x * 2 } }
=> [2, 4, 6, 8]
Hash Methods
Hash#dig
Extracts the nested value specified by the sequence of key objects.
irb> h = { foo: {bar: {baz: 1}}}
irb> h.dig(:foo, :bar, :baz)
=> 1
irb> h.dig(:invalid, :key)
=> nil
Hash#invert
invert
swaps keys and values in a hash.
irb> { a: 1, b: 2 }.invert
=> {1=>:a, 2=>:b}
Hash#transform_keys
transform_keys
lets you change hash keys with a block.
irb> { a: 1, b: 2 }.transform_keys { |key| key.to_s.upcase }
=> {"A"=>1, "B"=>2}
Hash#transform_values
transform_values
creates a new hash with the values transformed by the given block, while keeping the keys unchanged.
irb> { a: 1, b: 2 }.transform_values { |value| value * 10 }
=> { a: 10, b: 20 }
Array Methods
Array#rotate
rotate
shifts elements to the left by default, or by a given count.
irb> [1, 2, 3, 4].rotate
=> [2, 3, 4, 1]
Array#combination
combination
generates all combinations of a given length.
irb> [1, 2, 3].combination(2).to_a
=> [[1, 2], [1, 3], [2, 3]]
Array#permutation
permutation
returns all possible permutations of a given length.
irb> [1, 2, 3].permutation(2).to_a
=> [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
Object Methods
Object#method(:method_name).source_location
Find where a method is defined in your source code.
irb> g = Greeter.new
irb> g.method(:say_it).source_location
=> ["/Users/home/app/models/greeter.rb", 5]
Object#method(:method_name).arity
Check the number of arguments a method accepts.
irb> foo = "Hello"
irb> foo.method(:slice).arity
=> -2
Object#methods(false)
List only methods defined directly on the object, excluding inherited methods.
irb> obj = Object.new
def obj.greet; "Hello!"; end
irb> obj.methods(false)
=> [:greet]
Kernel Methods
callee
callee returns the current method’s name.
irb> def example
irb> __callee__
end
irb> example
=> :example
rescue/retry
retry
restarts the block after a rescue
clause.
irb> attempts = 0
irb> begin
irb> raise "Error" if (attempts += 1) < 3
irb> rescue
irb> retry
irb> end
=> nil
BEGIN / END
BEGIN
and END
define blocks executed before and after the script runs.
BEGIN { puts "Starting..." }
END { puts "Ending..." }
puts "Hello!"
ActiveSupport Methods
Enumerable#compact_blank
compact_blank
removes blank elements from an enumerable.
irb> [nil, "", "Hello", [], {}].compact_blank
=> ["Hello"]
Array#index_by
index_by
creates a hash where keys are determined by the block.
irb> ["apple", "banana", "pear"].index_by { |fruit| fruit[0] }
=> {"a"=>"apple", "b"=>"banana", "p"=>"pear"}
Miscellaneous
Right Assignment
Assign results in reverse order for cleaner syntax.
irb> Users.where(active: true).all => users
=> nil
irb> users
=> [#<Contact:>,...]
Destructuring Block Arguments
Pattern matching in blocks lets you destructure array elements.
irb> a = [[1, 2], [3, 4]]
irb> a.each do |(first, last)|
irb> puts "First: #{first}, Last: #{last}"
irb> end
First: 1, Last: 2
First: 3, Last: 4
Calling Procs
You could call procs in different ways:
irb> my_proc = -> arg { puts arg }
#<Proc:0x007fb1ebe9c1a0@(irb):1 (lambda)>
irb> my_proc.call('hello')
hello
irb> my_proc.('hello')
hello
irb> my_proc['hello']
hello
Command line Ruby tips
Given the following files in the current directory:
$ ls -l
-rw-r--r--@ 1 user group 36 28 Mai 17:57 file1.txt
-rw-r--r--@ 1 user group 8 28 Mai 17:57 file2.txt
-rw-r--r--@ 1 user group 613 28 Mai 17:58 file3.txt
-rw-r--r--@ 1 user group 3143 28 Mai 18:48 photo.jpg
-rw-r--r--@ 1 user group 1004 28 Mai 18:47 report.ofx
Using -n and -e to Process Lines
-n
wraps your code in a loop that reads each line from input. Combine with -e
for quick one-liners.
$ ls -1 | ruby -n -e 'puts $_ if $_.match(/\.txt/'
file1.txt
file2.txt
file3.txt
Using -p to Modify Lines in Place
-p
is like -n
but automatically prints each line. Great for filters and transformations.
$ ls -1 | ruby -p -e '$_ = $_.capitalize'
File1.txt
File2.txt
File3.txt
Photo.jpg
Report.ofx
Using STDIN
The command below returns the total size of all files returned by ls -l
command:
$ ls -l | ruby -e 'puts STDIN.to_a.map { |l| l.split[4].to_i }.sum'
4804
Lastest Posts
- 14 Apr 2025 I've been writing software for the last 25 years. Here are a few more things I've learned so far (part 2)
- 16 Mar 2025 How to backup your photos from Google and fix the Exif metadata
- 03 Sep 2024 Monitoring my swimming pool temperature with a cheap BLE sensor and ESPHome
- 01 Aug 2024 I've been writing software for the last 25 years. Here some things I learned so far