Gem Version Gem Downloads

WithEase

Very basic but useful extensions to Ruby.

N.B.: still in alpha

Installation

  gem install with_ease

With bundler

  gem 'with_ease'

Usage

  require 'with_ease'

For more sophisticated tools and imports into the current tools look at the speculations

In all the speculations we assume that require 'with_ease' has been used in the setup (spec_helper.rb or speculations_helper.rb)

Synopsis

What can you do WithEase.

Have an OpenStruct with a complete Hash like API

  • merge, update, slice
  • pattern matching

Have a ClosedStruct with the same API but fixed keys

Have a lean wrapper Forward around Forwardable which is actually readable!

c.f. for details

Have an Iterator class (and constructor function if you want).

Nothing you cannot do with Enumerator::Lazy but so much simpler again.

c.f for details

Quick Start

All functionality is described in detail in the speculations (see links above for the specific speculations of a functionality).

But here is a quick overview (also tested with the speculate_about gem as all other speculations).

Context: OpenStruct

Given

    require 'with_ease'

    let(:subject) { OpenStruct.new(a: 1, b: 2) }

Then we can use it mostly like a Hash instance.

    expect(subject.merge(a: 11, c: 31)).to eq(OpenStruct.new(a: 11, b: 2, c:31))

And we can pattern match

    subject => {a:, b: 2}
    expect(a).to eq(1)

Context: ClosedStruct

Given

    require 'with_ease'
    ClosedStruct = WithEase::ClosedStruct

    let(:subject) { ClosedStruct.new(a: 1, b: 2) }

Then we can do pretty much the same as with OpenStruct

   subject.update(a: 0)
   expect(subject).to eq(ClosedStruct.new(a: 0, b: 2))

But you must not add a key

    expect { subject.update(c: 3) }
      .to raise_error(KeyError)
    expect{ subject.merge(c: 3) }
      .to raise_error(KeyError)

c.f for details

Context: Iterator

As mentioned above you can ~easily~ (it's not complicated but it is not easy!) create an iterator in Ruby, howver this one is so much simpler.

Given

    require 'with_ease'
    Iterator = WithEase::Iterator

    let(:subject) { Iterator.new(0, &:succ) }

Then we can just advance it

    expect(subject.value).to be_zero
    expect(subject.advance.value).to eq(1)

It is an Enumerable of course and quite lazy, if you are intereted here is more

c.f for details

Context: Forward

Given

    require 'with_ease'

    Forward = WithEase::Forward

N.B.: We could have used require 'with_ease/import_all' instead.

And

    class Wrapper
      extend Forward
      forward :empty?, :size, to: :@array
      def initialize(array) = @array = array.to_a
    end

    let(:subject) { Wrapper.new(0..9) }

Then we can see that

    expect(subject).not_to be_empty
    expect(subject.size).to eq(10)

But also

    expect(Wrapper.new([])).to be_empty

c.f. for details

Author

Copyright 2025 Robert Dober [email protected]

LICENSE

AGPL-3.0-or-later c.f LICENSE