Methods in Ruby
Methods are reusable blocks of code that perform specific tasks. Ruby methods are elegant and flexible, making your code clean and maintainable.
Defining Methods
ruby
1# Basic method
2def greet
3 puts "Hello, World!"
4end
5
6greet # => Hello, World!
7
8# Method with parameters
9def greet(name)
10 puts "Hello, #{name}!"
11end
12
13greet("Alice") # => Hello, Alice!
14
15# Method with default parameters
16def greet(name = "Guest")
17 puts "Hello, #{name}!"
18end
19
20greet # => Hello, Guest!
21greet("Bob") # => Hello, Bob!Return Values
In Ruby, methods automatically return the last expression:
ruby
1# Implicit return
2def add(a, b)
3 a + b # This is returned automatically
4end
5
6result = add(3, 5) # => 8
7
8# Explicit return
9def divide(a, b)
10 return "Cannot divide by zero" if b == 0
11 a / b
12end
13
14divide(10, 2) # => 5
15divide(10, 0) # => "Cannot divide by zero"
16
17# Multiple return values
18def min_max(numbers)
19 [numbers.min, numbers.max]
20end
21
22min, max = min_max([3, 1, 4, 1, 5])
23# min => 1, max => 5Method Arguments
Positional Arguments
ruby
1def create_user(name, email, age)
2 { name: name, email: email, age: age }
3end
4
5create_user("John", "john@example.com", 30)Keyword Arguments
ruby
1# Required keyword arguments
2def create_user(name:, email:)
3 { name: name, email: email }
4end
5
6create_user(name: "John", email: "john@example.com")
7# Order doesn't matter:
8create_user(email: "john@example.com", name: "John")
9
10# Optional keyword arguments with defaults
11def create_user(name:, email:, role: "user", active: true)
12 { name: name, email: email, role: role, active: active }
13end
14
15create_user(name: "John", email: "john@example.com")
16# => { name: "John", email: "john@example.com", role: "user", active: true }Splat Operators
ruby
1# *args - collect remaining positional arguments
2def sum(*numbers)
3 numbers.reduce(0, :+)
4end
5
6sum(1, 2, 3, 4, 5) # => 15
7
8# **kwargs - collect remaining keyword arguments
9def log(message, **options)
10 puts "#{message} (#{options})"
11end
12
13log("Error occurred", level: :error, timestamp: Time.now)
14
15# Combining all types
16def method(required, optional = "default", *args, keyword:, **kwargs)
17 # required - must be provided
18 # optional - has a default value
19 # *args - array of extra positional args
20 # keyword: - required keyword argument
21 # **kwargs - hash of extra keyword args
22endMethod Naming Conventions
Ruby has conventions for method names that convey meaning:
ruby
1# Question mark (?) - returns boolean
2def active?
3 @status == "active"
4end
5
6user.active? # => true or false
7
8# Bang (!) - modifies object in place or dangerous operation
9name = "hello"
10name.upcase # => "HELLO" (returns new string)
11name # => "hello" (original unchanged)
12
13name.upcase! # => "HELLO" (modifies in place)
14name # => "HELLO" (original changed)
15
16# Setter methods (=)
17class User
18 def name=(value)
19 @name = value.strip
20 end
21end
22
23user.name = " John " # Calls name= method
24
25# Private methods often start with underscore (convention)
26def _internal_calculation
27 # ...
28endBlocks, Procs, and Lambdas
Blocks
Blocks are chunks of code passed to methods:
ruby
1# Block with do...end (multi-line)
2[1, 2, 3].each do |number|
3 puts number * 2
4end
5
6# Block with braces (single line)
7[1, 2, 3].each { |number| puts number * 2 }
8
9# Accepting a block in your method
10def with_timing
11 start = Time.now
12 yield # Execute the block
13 puts "Took #{Time.now - start} seconds"
14end
15
16with_timing do
17 sleep(1)
18 puts "Working..."
19end
20
21# Block with arguments
22def repeat(times)
23 times.times { |i| yield(i) }
24end
25
26repeat(3) { |i| puts "Iteration #{i}" }Procs
Procs are saved blocks you can reuse:
ruby
1# Creating a proc
2double = Proc.new { |n| n * 2 }
3# Or using proc
4double = proc { |n| n * 2 }
5
6double.call(5) # => 10
7double.(5) # => 10 (shorthand)
8double[5] # => 10 (shorthand)
9
10# Using procs with methods
11[1, 2, 3].map(&double) # => [2, 4, 6]
12
13# Converting methods to procs
14def triple(n)
15 n * 3
16end
17
18[1, 2, 3].map(&method(:triple)) # => [3, 6, 9]Lambdas
Lambdas are like procs but stricter:
ruby
1# Creating a lambda
2multiply = ->(a, b) { a * b }
3# Or
4multiply = lambda { |a, b| a * b }
5
6multiply.call(3, 4) # => 12
7
8# Differences from procs:
9# 1. Lambdas check argument count
10lam = ->(a, b) { a + b }
11lam.call(1) # ArgumentError: wrong number of arguments
12
13# 2. return in lambda returns from lambda only
14def test_lambda
15 lam = -> { return "from lambda" }
16 lam.call
17 "from method"
18end
19test_lambda # => "from method"
20
21def test_proc
22 p = proc { return "from proc" }
23 p.call
24 "from method" # Never reached
25end
26test_proc # => "from proc"Method Visibility
ruby
1class User
2 # Public by default
3 def greet
4 puts "Hello!"
5 end
6
7 private
8
9 # Private methods - can only be called within the class
10 def secret_method
11 puts "This is private"
12 end
13
14 protected
15
16 # Protected - can be called by same class or subclasses
17 def internal_method
18 puts "This is protected"
19 end
20end
21
22user = User.new
23user.greet # Works
24user.secret_method # NoMethodError: private method calledAlias Methods
ruby
1class User
2 def full_name
3 "#{first_name} #{last_name}"
4 end
5
6 alias_method :name, :full_name
7end
8
9user.full_name # => "John Doe"
10user.name # => "John Doe" (same method)Method Missing
Handle calls to undefined methods:
ruby
1class FlexibleObject
2 def method_missing(method_name, *args)
3 puts "You called: #{method_name} with #{args}"
4 end
5end
6
7obj = FlexibleObject.new
8obj.anything("hello", 123)
9# => You called: anything with ["hello", 123]Methods are the building blocks of Ruby programs. Understanding them deeply will help you write elegant Rails code!
