Gem Version

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