Lab42::Forwarder3 A zero cost wrapper around Forwardable, to make it readable (frankly usable).
N.B. All these code examples are verified with the speculate_about gem
Quick Starting Guide
Given some global data like these
let(:a_hash) {Hash[("a".."z").zip(1..26)]}
let(:my_hash) {MyHash.new(a_hash)}
Context The simplest case, forward without aliasing
Given this nice little class
require "lab42/forwarder3"
class MyHash
extend Lab42::Forwarder3
forward :[], to: :@hash
def initialize hash
@hash = hash
end
end
Then normal []
access just works
expect(my_hash["a"]).to eq(1)
Context Aliasing with as:
Given this extension
class MyHash
forward :fetch, to: :@hash, as: :[]
end
Then fetching works like bracket access
expect( my_hash.fetch("b") ).to eq(2)
And we get no exception in case of a missing key
expect( my_hash.fetch("alpha") ).to be_nil
Context The very useful def_delegators
becomes the equally useful forward_all
Given this usage of forward_all
class MyHash
forward_all :keys, :values, :size, to: :@hash
end
Then we get access to these methods as expected
expect( my_hash.keys ).to eq([*"a".."z"])
expect( my_hash.size ).to eq(26)
expect( my_hash.values ).to eq([*1..26])
Context Of course we can delegate to methods
We can also alias the rather long Lab42::Forwarder3
into
the global namespace as Forwarder
as shown below
Given a more complex class
require "lab42/forwarder3/include"
class Person
extend Forwarder
forward_all :[], :fetch, to: :to_h
forward :name_size, to: :name, as: :size
attr_reader :age, :name, :nationality
def initialize(name, age, nationality: "fr")
@age = age
@name = name
@nationality = nationality
end
def to_h
{
age: age,
name: name,
nationality: nationality
}
end
end
let(:myself) {Person.new("Robert", 42)}
Then we can access as follows:
expect{ myself.fetch(:gender) }.to raise_error(KeyError)
expect( myself.fetch(:age) ).to eq(42)
expect( myself.name_size ).to eq(6)
LICENSE
Copyright 2020 Robert Dober [email protected]
Apache-2.0 c.f LICENSE