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

Extend the &:<method> cludge from symbols to arrays with Array#.to_proc

My philosophy on this, is either use both or hate both

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