“When something is too hard it means that you’re not cheating enough.”
DHH
Before:
1
2
3
4
5
6
7
8
9
10
11
|
class Cart
def initialize
@items = []
end
def size ; @items.size end
def clear ; @items.clear end
def empty? ; @items.empty? end
attr_reader :items
end
|
After
1
2
3
4
5
6
7
8
9
|
class Cart
def initialize
@items = []
end
delegate :clear, :empty?, :size, :to => :items
attr_reader :items
end
|
What it does:
When you call
cart.size
, Rails
delegates the
size() method call to the
items object and executes:
cart.items.size
How it works:
If you look at the
source, you'll notice that Rails actually generates 3 methods equivalent to the code we have just removed (see 'Before'), and injects them in the class code. The behaviour does not change; it's just a shorter way to write this code.
Should you want (be careful) to delegate ALL the unknown methods calls, you could write :
1
2
3
4
|
# delegate unknown methods calls to @items
def method_missing(method, *args, &block)
@items.send method, *args, &block
end |
API doc :
http://caboo.se/doc/classes/Module.html#M003442
1 comments:
Refactoring with Delegates (C#)
Problem:
If multiple derived classes require slightly different versions of a method provided in the base class
Old Solution:
> Have the base method accept new parameters to execute different code within the base method
> However, this becomes unwieldy with function signatures like
protected double Calculate(data,someOtherflag,newflag,oldflag,forgottenMeaningFlag)
{
double dblReturnPrice = data.value;
if (someotherflag || newflag && olflag || forgottenMeaningFlag)
{
dblReturnPrice += 5;
}
return dblReturnPrice;
}
> and after all, you don't want derived-class specific code in a base class.
New Solution:
> Declare a delegate pointing to a function in the derived class
Base:
public Delegate double CalculateHandler(data)
Protected CalculateHandler PriceCalculator = null;
protected double Calculate(data)
{
double dblReturnPrice = data.value;
if (PriceCalculator!=null)
{
dblReturnPrice = PriceCalculator(data)
}
return dblReturnPrice;
}
Derived
base.PriceCalculator = new CalculateHandler(SpecificPriceCalculator)
public double SpecificPriceCalculator(data)
{
return data.value +5;
}
Post a Comment