MethodHuntingDelegator
class Book < SomeModelThing | |
attr_reader :title, :blurb | |
end | |
class Course < SomeModelThing | |
attr_reader :name, :description | |
end | |
class SearchResult < MethodHuntingDelegator | |
def description | |
hunt_and_call :description, :blurb | |
end | |
def title | |
hunt_and_call :title, :name | |
end | |
end | |
# simulate the results of a search with mixed result types | |
results = [ Book.first, Course.first ].map(&SearchResult.method(:new)) | |
results.each { |r| puts "#{r.title}: #{r.description}" } |
require "delegate" | |
class MethodHuntingDelegator < SimpleDelegator | |
def hunt_and_call *candidates | |
hunt_method(*candidates).call | |
end | |
private | |
def hunt_method *candidates | |
__getobj__.method candidates.detect( | |
->{ raise Error.new(candidates, __getobj__) }, | |
&__getobj__.method(:respond_to?) | |
) | |
end | |
class Error < StandardError | |
def initialize candidates, object | |
super "#{candidates.inspect} not implemented by #{object.inspect}" | |
end | |
end | |
end |
require "spec_helper" | |
require "method_hunting_delegator" | |
describe MethodHuntingDelegator do | |
context "decorating a string" do | |
let(:delegate) { "abcd" } | |
let(:delegator) { MethodHuntingDelegator.new(delegate) } | |
describe "#hunt_and_call" do | |
it "delegates [ :not_a_method, :length, :upcase ] to String#length" do | |
delegator.hunt_and_call(:not_a_method, :length, :upcase).should == 4 | |
end | |
it "raises MethodHuntingDelegator::Error for [ :nope_A, :nope_B ]" do | |
expect do | |
delegator.hunt_and_call(:nope_A, :nope_B) | |
end.to raise_error(MethodHuntingDelegator::Error) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment