xp-lang / xp-records
XP recods for PHP
Installs: 1 260
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 3
Forks: 0
Open Issues: 0
Requires
- php: >=7.4.0
- xp-framework/compiler: ^9.0 | ^8.0 | ^7.0
- xp-framework/core: ^12.0 | ^11.0 | ^10.0
Requires (Dev)
- xp-framework/test: ^2.0 | ^1.0
README
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.
Example
// 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.
Initialization
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.
Destructuring
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}");
Installation
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.