# What is delegation?
In Ruby, the `delegate` method is used to delegate method calls to an associated object, often referred to as a delegate or proxy. This helps to simplify the code and reduce redundancy by allowing an object to pass method calls to another object.
The `delegate` method is part of the `Forwardable` module and the `Delegator` class in Ruby's standard library. Here's how you can use `delegate` in different contexts:
Using the `Forwardable` Module
The `Forwardable` module provides methods to delegate specified method calls to designated objects.
require 'forwardable'
class User
extend Forwardable
attr_accessor :profile
def_delegators :@profile, :name, :age
def initialize(profile)
@profile = profile
end
end
class Profile
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
profile = Profile.new("Alice", 30)
user = User.new(profile)
puts user.name # Outputs: Alice
puts user.age # Outputs: 30In this example, the `User` class delegates the `name` and `age` methods to its `profile` object.
Using the `SimpleDelegator` Class
The `SimpleDelegator` class allows an object to delegate all of its methods to another object.
require 'delegate'
class User < SimpleDelegator
def initialize(profile)
super(profile)
end
end
class Profile
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
profile = Profile.new("Alice", 30)
user = User.new(profile)
puts user.name # Outputs: Alice
puts user.age # Outputs: 30In this example, the `User` class is a subclass of `SimpleDelegator` and delegates all method calls to its `profile` object.
Using the Active Support `delegate` Method
If you are using Rails, Active Support provides a convenient `delegate` method that can be used within a class to delegate method calls to an associated object.
class User
attr_accessor :profile
def initialize(profile)
@profile = profile
end
delegate :name, :age, to: :profile
end
class Profile
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
profile = Profile.new("Alice", 30)
user = User.new(profile)
puts user.name # Outputs: Alice
puts user.age # Outputs: 30In this example, the `User` class uses the `delegate` method provided by Active Support to delegate the `name` and `age` methods to its `profile` object.
By using delegation, you can design more modular and maintainable code, as it allows you to split responsibilities among different objects without unnecessary repetition.