Methods

Defining Methods

def method_name
  # code
end

def greet(name)
  "Hello, #{name}!"
end

Method Parameters

Required Parameters

def add(a, b)
  a + b
end

Default Parameters

def greet(name = "World")
  "Hello, #{name}!"
end

Variable Arguments (*args)

def sum(*numbers)
  numbers.inject(0) { |sum, n| sum + n }
end

sum(1, 2, 3, 4)  # 10

Keyword Arguments

def create_user(name:, age: 18, email: nil)
  # code
end

create_user(name: "John", age: 25)

Keyword Arguments with **kwargs

def user_info(**attributes)
  attributes.each { |key, value| puts "#{key}: #{value}" }
end

Return Values

Methods return the last evaluated expression:

def add(a, b)
  a + b  # implicit return
end

def explicit_return
  return "early return"
  "this won't execute"
end

Method Visibility

Public Methods (default)

def public_method
  "anyone can call me"
end

Private Methods

private

def private_method
  "only callable within this class"
end

Protected Methods

protected

def protected_method
  "callable by instances of same class or subclasses"
end

Class Methods

class MyClass
  def self.class_method
    "I'm a class method"
  end

  def instance_method
    "I'm an instance method"
  end
end

MyClass.class_method    # "I'm a class method"
obj = MyClass.new
obj.instance_method     # "I'm an instance method"

Method Aliases

alias old_name new_name

def original_method
  "original"
end

alias :old_method :original_method

Method Missing

class DynamicClass
  def method_missing(name, *args)
    puts "Called #{name} with #{args.inspect}"
  end
end

obj = DynamicClass.new
obj.any_method("arg")  # Called any_method with ["arg"]

Blocks, Procs, and Lambdas

Blocks

def my_method
  yield if block_given?
end

my_method { puts "Block executed" }

Procs

my_proc = Proc.new { |x| x * 2 }
my_proc.call(5)  # 10

Lambdas

my_lambda = lambda { |x| x * 2 }
my_lambda.call(5)  # 10

# Or:
my_lambda = ->(x) { x * 2 }

Method Objects

class Calculator
  def add(a, b)
    a + b
  end
end

calc = Calculator.new
method_obj = calc.method(:add)
result = method_obj.call(2, 3)  # 5

Operator Methods

class Point
  attr_accessor :x, :y

  def initialize(x, y)
    @x, @y = x, y
  end

  def +(other)
    Point.new(@x + other.x, @y + other.y)
  end

  def to_s
    "(#{@x}, #{@y})"
  end
end

p1 = Point.new(1, 2)
p2 = Point.new(3, 4)
p3 = p1 + p2  # (4, 6)

Singleton Methods

obj = "hello"
def obj.shout
  upcase
end

obj.shout  # "HELLO"

Method Chaining

class Chainable
  def initialize(value)
    @value = value
  end

  def add(n)
    @value += n
    self  # Return self for chaining
  end

  def multiply(n)
    @value *= n
    self
  end

  def result
    @value
  end
end

result = Chainable.new(5).add(3).multiply(2).result  # 16

Best Practices

Ruby's method system is flexible and powerful, allowing for clean, readable code with great expressiveness.

Loading