Варварский генератор
Недавно с коллегами обсудили, что, строго говоря, генератор не соблюдает принцип подстановки Барбары Лисков. Он кидает исключение при попытке перемотки после начала обхода и тем самым нарушает контракт
Понятно, почему конструктивно так сделали. Тем не менее передача генератора в функцию, которая принимаетWTF казусу, если она вполне законно пытается обойти аргумент больше одного раза.
Если очень хочется, чтобы инстанс генератора отрабатывал многократно, и при этом вы уверены, что это не приведёт к ненужным побочным эффектам, можно обернуть функцию, порождающую генератор, в
Вот как это будет работать: https://3v4l.org/46Evq.
Пишите в комментариях, где ещё PHP нарушает LSP.
Недавно с коллегами обсудили, что, строго говоря, генератор не соблюдает принцип подстановки Барбары Лисков. Он кидает исключение при попытке перемотки после начала обхода и тем самым нарушает контракт
Iterable
, где такое поведение не предусмотрено.Понятно, почему конструктивно так сделали. Тем не менее передача генератора в функцию, которая принимает
Traversable
или iterable
, приводит к Если очень хочется, чтобы инстанс генератора отрабатывал многократно, и при этом вы уверены, что это не приведёт к ненужным побочным эффектам, можно обернуть функцию, порождающую генератор, в
RewindableGenerator
:
/**
* @template TKey
* @template TValue
* @implements IteratorAggregate<TKey, TValue>
*/
final class RewindableGenerator implements IteratorAggregate
{
/**
* @param callable(): Generator<TKey, TValue> $generatorFunction
*/
public function __construct(private $generatorFunction) {}
public function getIterator(): Traversable
{
return ($this->generatorFunction)();
}
}
Вот как это будет работать: https://3v4l.org/46Evq.
Пишите в комментариях, где ещё PHP нарушает LSP.