Git Product home page Git Product logo

immutable's Introduction

Immutable

Build Status codecov Type Coverage

A set of classes to wrap PHP primitives to build immutable data.

Documentation

Installation

composer require innmind/immutable

Usage

Here are some examples of what you can do:

Sequence

To be used to wrap an ordered list of elements (elements can be of mixed types).

use Innmind\Immutable\Sequence;

$seq = Sequence::of(24, 42, 'Hitchhiker', 'Magrathea');
$seq->get(2); // Maybe::just(Hitchhiker)
$another = $seq->drop(2);
$another->toList(); // [Hitchhiker, Magrathea]
$seq->toList(); // [24, 42, Hitchhiker, Magrathea]

//----
// this example demonstrates the lazyness capability of the sequence
// precisely here it's able to read a file line by line and echo the lines
// that are less than 42 characters long (without requiring to load the whole
// file in memory)
$someFile = fopen('some/file.txt', 'r');
$lines = Sequence::lazy(fn() => yield fgets($someFile))
    ->filter(fn($line) => strlen($line) < 42);
// at this point no reading to the file has been done because all methods
// returning a new instance of a sequence will pipeline the operations to do,
// allowing to chain complex logic while accessing the original data once and
// without the need to keep the discarded data along the pipeline in memory
$lines->foreach(fn($line) => echo($line));

For a complete list of methods check Sequence.

Set

To be used as a collection of unordered elements (elements must be of the same type).

use Innmind\Immutable\Set;

$set = Set::of(24, 42);
$set->equals(Set::of(24, 42)); // true
$set->add(42.0); // psalm will raise an error

For a complete list of methods check Set.

Map

To be used as a collection of key/value pairs (both keys and values must be of the same type).

use Innmind\Immutable\Map;

$map = Map::of(
    [new \stdClass, 42]
    [$key = new \stdClass, 24]
);
$map->size(); // 2, because it's 2 different instances
$map->values()->toList(); // [42, 24]
$map = $map->put($key, 66);
$map->size(); // 2
$map->values()->toList(); // [42, 66]

For a complete list of methods check Map.

Strings

use Innmind\Immutable\Str;

$var = Str::of('the hitchhiker\'s guide to the galaxy');
echo $var
    ->replace('galaxy', '42') // the hitchhiker's guide to the 42
    ->drop(18) // guide to the 42
    ->toUpper()
    ->toString(); // outputs: GUIDE TO THE 42
echo $var->toString(); // outputs: the hitchhiker\'s guide to the galaxy

Regular expressions

use Innmind\Immutable\{
    RegExp,
    Str,
};

$regexp = RegExp::of('/(?<i>\d+)/');
$regexp->matches(Str::of('foo123bar')); // true
$regexp->matches(Str::of('foobar')); // false
$regexp->capture(Str::of('foo123bar')); // Map<int|string, Str> with index `i` set to Str::of('123')

This library provides 2 Sets that can be used with innmind/black-box.

You can use them as follow:

use Innmind\BlackBox\{
    PHPUnit\BlackBox,
    Set,
};
use Fixtures\Innmind\Immutable;

class SomeTest extends \PHPUnit\Framework\TestCase
{
    use BlackBox;

    public function testSomeProperty()
    {
        $this
            ->forAll(
                Immutable\Set::of(
                    Set\RealNumbers::any(),
                ),
                Immutable\Sequence::of(
                    Set\Uuid::any(),
                ),
            )
            ->then(function($set, $sequence) {
                // $set is an instance of \Innmind\Immutable\Set<float>
                // $sequence is an instance of \Innmind\Immutable\Sequence<string>

                // write your test here
            });
    }
}

immutable's People

Contributors

baptouuuu avatar drupol avatar jdecool avatar nclshart avatar ngdo-pro avatar quentint avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

immutable's Issues

A lazy `Sequence::takeEnd()` should not load the whole sequence in memory

Problem

When working with a lazy Sequence, the call to takeEnd() will load the whole sequence in memory and then throw out the unnecessary data.

Solution

The generator should be walked over and a buffer of the expected size should kept a memory. On each iteration add the new element to the buffer and throw out the first element if the buffer is larger than the expected size.

PHPUnit data providers

I guess there is no way of implementing PHPUnit tests with data providers, right?

Instead of this:

public function testAddIsCommutative(): void
{
    $this->forAll(
        Set\Integers::any(),
        Set\Integers::any(),
    )->then(function (int $a, int $b) {
        self::assertSame(
            add($a, $b),
            add($b, $a),
        );
    });
}

We could also aim for this:

#[DataProvider('additionProvider')]
public function testAddIsCommutative(int $a, int $b): void
{
    self::assertSame(
        add($a, $b),
        add($b, $a),
    );
}

public function additionProvider(int $a, int $b): iterable
{
    return $this->forAll(
        Set\Integers::any(),
        Set\Integers::any(),
    )->getIterator();
}

How would you feel about this approach? I think it allows to test more properties with the same generators with less code ๐Ÿ˜„

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.