Plugin for the XP Compiler which adds a record
syntax to the PHP language. Records declare a final class with immutable components for each of its members and appropriate accessors and a constructor, which implements the lang.Value
interface.
// Declaration
namespace com\example;
use IteratorAggregate, Traversable;
record Range(int $lo, int $hi) implements IteratorAggregate {
public function getIterator(): Traversable {
for ($i= $this->lo; $i <= $this->hi; $i++) {
yield $i;
}
}
}
// Usage
$r= new Range(1, 10);
$r->lo(); // 1
$r->hi(); // 10
$r->toString(); // "com.example.Range(lo: 1, hi: 10)"
foreach ($r as $item) {
// 1, 2, 3, ... 10
}
Note: The generated toString()
, hashCode()
and compareTo()
methods may be overriden by supplying an implementation in the record body.
To verify constructor parameters, add an initialization block as follows:
use lang\IllegalArgumentException;
record Range(int $lo, int $hi) {
init {
if ($this->lo > $this->hi) {
throw new IllegalArgumentException('Lower border may not exceed upper border');
}
}
}
This block is called after the members have been initialized from the constructor parameters.
To destructure a record into its members, use the invocation syntax:
// Using the declaration from above:
$r= new Range(1, 10);
// Use https://wiki.php.net/rfc/short_list_syntax (>= PHP 7.1)
[$lo, $hi]= $r();
// Optionally map the members, returns the string "1..10"
$string= $r(fn($lo, $hi) => "{$lo}..{$hi}");
After installing the XP Compiler into your project, also include this plugin.
$ composer require xp-framework/compiler
# ...
$ composer require xp-lang/xp-records
# ...
No further action is required.