Skip to content

Instantly share code, notes, and snippets.

@vudaltsov
Created June 2, 2025 17:59
Show Gist options
  • Save vudaltsov/49a77f12b12c40fc38264ead27705317 to your computer and use it in GitHub Desktop.
Save vudaltsov/49a77f12b12c40fc38264ead27705317 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
/**
* @template T
* @param T $x
* @return T
*/
function id(mixed $x): mixed
{
return $x;
}
final readonly class It implements ArrayAccess
{
private Closure $function;
public function __construct(?Closure $function = null)
{
$this->function = $function ?? id(...);
}
public function __invoke(mixed $result): mixed
{
return ($this->function)($result);
}
public function __get(string $name)
{
return new self(
fn(mixed $result): mixed => ($this->function)($result)->{$name},
);
}
public function __call(string $name, array $arguments)
{
return new self(
fn(mixed $result): mixed => ($this->function)($result)->{$name}(...$arguments),
);
}
public function offsetExists(mixed $offset): bool
{
return true;
}
public function offsetGet(mixed $offset): mixed
{
return new self(
fn(mixed $result): mixed => ($this->function)($result)[$offset],
);
}
public function offsetSet(mixed $offset, mixed $value): void
{
throw new BadMethodCallException();
}
public function offsetUnset(mixed $offset): void
{
throw new BadMethodCallException();
}
}
const it = new It();
final readonly class SomeClass
{
public function __construct(
public string $prop = '',
) {}
public function method(mixed ...$args): array
{
return $args;
}
}
assert(
array_map(
it['key'],
[
['key' => 'a'],
['key' => 'b'],
['key' => 'c'],
],
) === ['a', 'b', 'c'],
'Test 1 failed.',
);
assert(
array_map(
it->prop,
[
new SomeClass('a'),
new SomeClass('b'),
new SomeClass('c'),
],
) === ['a', 'b', 'c'],
'Test 2 failed.',
);
assert(
array_map(
it->method('a', arg2: 'b'),
[
new SomeClass(),
],
) === [['a', 'arg2' => 'b']],
'Test 3 failed.',
);
assert(
array_map(
it->method(key: ['key' => 'value'])['key']['key'],
[
new SomeClass(),
],
) === ['value'],
'Test 4 failed.',
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment