Created
March 15, 2023 01:59
-
-
Save AnandPilania/24052781effe1e5b9e078ef3a2e7b3dc to your computer and use it in GitHub Desktop.
NUTTY Pipe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function pipe($subject) { | |
return new Pipe($subject); | |
} | |
class Pipe implements \Stringable, \ArrayAccess, \IteratorAggregate | |
{ | |
use Transparency; | |
function __construct($target) | |
{ | |
$this->target = $target; | |
} | |
function __invoke(...$params) { | |
if (empty($params)) return $this->target; | |
[ $before, $through, $after ] = [ [], null, [] ]; | |
foreach ($params as $key => $param) { | |
if (! $through) { | |
if (is_callable($param)) $through = $param; | |
else $before[$key] = $param; | |
} else { | |
$after[$key] = $param; | |
} | |
} | |
$params = [ ...$before, $this->target, ...$after ]; | |
$this->target = $through(...$params); | |
return $this; | |
} | |
} | |
trait Transparency | |
{ | |
public $target; | |
function __toString() | |
{ | |
return (string) $this->target; | |
} | |
function offsetExists(mixed $offset): bool | |
{ | |
return isset($this->target[$offset]); | |
} | |
function offsetGet(mixed $offset): mixed | |
{ | |
return $this->target[$offset]; | |
} | |
function offsetSet(mixed $offset, mixed $value): void | |
{ | |
$this->target[$offset] = $value; | |
} | |
function offsetUnset(mixed $offset): void | |
{ | |
unset($this->target[$offset]); | |
} | |
function getIterator(): \Traversable | |
{ | |
return (function () { | |
foreach ($this->target as $key => $value) { | |
yield $key => $value; | |
} | |
})(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function pipe($thing) { | |
$fluent = new class ($thing) { | |
public $calls = 0; | |
public $ticks = 0; | |
public $onTick; | |
public $kill = false; | |
public $fluent; | |
public function __construct(public $thing) {} | |
public function setFluentRef(&$fluent) | |
{ | |
$this->fluent = $fluent; | |
} | |
public function &__invoke(...$params) { | |
if (empty($params)) return $this->thing; | |
$this->calls++; | |
$before = []; | |
$through = null; | |
$after = []; | |
foreach ($params as $key => $param) { | |
if (! $through) { | |
if (is_callable($param)) $through = $param; | |
else $before[$key] = $param; | |
} else { | |
$after[$key] = $param; | |
} | |
} | |
$params = array_merge($before, [$this->thing], $after); | |
$this->thing = $through(...$params); | |
$this->ticks = 0; | |
declare(ticks=1); | |
return $this->fluent; | |
} | |
}; | |
$fluent->setFluentRef($fluent); | |
$onTick = function () use (&$fluent) { | |
if (is_string($fluent)) return; | |
if ($fluent->ticks === 1 && $fluent->calls === 0) { | |
$fluent->fluent = $fluent->thing; | |
} | |
$fluent->ticks++; | |
$fluent->calls = 0; | |
}; | |
register_tick_function($onTick); | |
return $fluent; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment