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!
Have an Iterator class (and constructor function if you want).
Nothing you cannot do with Enumerator::Lazy but so much simpler again.
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)
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
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
Author
Copyright 2025 Robert Dober [email protected]
LICENSE
AGPL-3.0-or-later c.f LICENSE