2017 © Pedro Pelรกez
 

library match

Match DSL

image

xp-forge/match

Match DSL

  • Sunday, May 21, 2017
  • by thekid
  • Repository
  • 2 Watchers
  • 0 Stars
  • 3 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 3 Versions
  • 0 % Grown

The README.md

Matching DSL

Build Status on TravisCI XP Framework Module BSD Licence Required PHP 5.4+ Supports PHP 7.0+ Supports HHVM 3.4+ Latest Stable Version, (*1)

Fluent API for matching., (*2)

Matching

The following outputs two lines, My Team ๐Ÿ”’ and Developers:, (*3)

Sequence::of([new Group('My Team', Types::$CLOSED), new Group('Developers', Types::$OPEN)])
  ->map((new Match('Group::type'))
    ->when(new IsEqual(Types::$OPEN), function($group) { return $group->name(); })
    ->when(new IsEqual(Types::$CLOSED), function($group) { return $group->name().' ๐Ÿ”’'; })
  )
  ->each('util.cmd.Console::writeLine')
;

If the group's type() method where to return an unhandled group type, e.g. Types::$HIDDEN, an exception would be raised., (*4)

Unhandled values

To handle the default case, use the otherwise() method:, (*5)

$match= (new Match('Group::type'))
  ->when(new IsEqual(Types::$OPEN), function($group) { return $group->name(); })
  ->when(new IsEqual(Types::$CLOSED), function($group) { return $group->name().' ๐Ÿ”’'; })
  ->otherwise(function($group) { return $group->name().' ('.$group->type()->name().')'; })
;

Matching values

For the special case of testing equality, we can use the specialized ValueOf matcher:, (*6)

$kind= (new ValueOf('Event::weekday'))
  ->when(Day::$SATURDAY, function() { return 'Weekend'; })
  ->when(Day::$SUNDAY, function() { return 'Weekend'; })
  ->otherwise(function() { return 'During the week'; })
;

$display= $kind(new Event('Relax', new Date('2015-01-18')));    // `Weekend`
$display= $kind(new Event('Meeting', new Date('2015-01-19')));  // `During the week`

Matching types

The following is a reimplementation of PHP's serialize function (incomplete, but you get the idea):, (*7)

$serialize= (new TypeOf())
  ->when(Primitive::$INT, function($value) { return 'i:'.$value.';'; })
  ->when(Primitive::$STRING, function($value) { return 's:'.strlen($value).':"'.$value.'";'; })
  ->when(Type::$ARRAY, function($value, $self) {
    $r= 'a:'.sizeof($value).':{';
    foreach ($value as $key => $val) {
      $r.= $self($key).$self($val);
    }
    return $r.'}';
  })
  ->when(null, function() { return 'N;'; })
;

$serialized= $serialize(1);       // `i:1;`
$serialized= $serialize('Test');  // `s:4:"Test";`
$serialized= $serialize([1, 2]);  // `a:2:{i:0;i:1;i:1;i:2;}`
$serialized= $serialize(null);    // `N;`

The Type::$ARRAY is actually a type union consisting of zero-indexed arrays and maps, both of which are known to PHP as an array (in contrast, the XP Framework only speaks of the first as arrays). We use it here for performance reasons since we don't need to distinguish between the two anyways., (*8)

Performance

They KeyOf class is a high-performance alternative to the ValueOf class although it's restricted to integers and strings (it uses them as keys in its backing map)., (*9)

// Using native if and comparison
$match= function($value) {
  if (0 === $value) {
    return 'No elements';
  } else if (1 === $value) {
    return 'One element';
  } else {
    return $value.' elements';
  }
};

// Using KeyOf class
$match= (new KeyOf())
  ->when(0, function() { return 'No elements'; })
  ->when(1, function() { return 'One element'; })
  ->otherwise(function($value) { return $value.' elements'; })
;

// Using ValueOf class
$match= (new ValueOf())
  ->when(0, function() { return 'No elements'; })
  ->when(1, function() { return 'One element'; })
  ->otherwise(function($value) { return $value.' elements'; })
;

Using 500000 iterations, PHP 5.4 / Windows 8.1:, (*10)

Invocation Result Native if KeyOf class ValueOf class
$match(0) "No elements" 0.283 secs 0.386 secs (1.36x) 0.566 secs (2.00x)
$match(1) "One element" 0.287 secs 0.385 secs (1.34x) 0.750 secs (2.61x)
$match(2) "2 elements" 0.386 secs 0.500 secs (1.29x) 0.882 secs (2.28x)
$match(100) "100 elements" 0.383 secs 0.524 secs (1.37x) 0.900 secs (2.35x)

Further reading

This library was inspired by Scala's patter matching., (*11)

The Versions

21/05 2017

dev-master

9999999-dev http://xp-framework.net/

Match DSL

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

module xp

21/05 2017

v0.2.0

0.2.0.0 http://xp-framework.net/

Match DSL

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

module xp

12/02 2015

v0.1.1

0.1.1.0 http://xp-framework.net/

Match DSL

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

module xp