Обложка канала

Пых

4468 @phpyh

Блог @vudaltsov о разработке на PHP

Пых

4 года назад
Открыть в
Варварский генератор Недавно с коллегами обсудили, что, строго говоря, генератор не соблюдает принцип подстановки Барбары Лисков. Он кидает исключение при попытке перемотки после начала обхода и тем самым нарушает контракт Iterable, где такое поведение не предусмотрено. Понятно, почему конструктивно так сделали. Тем не менее передача генератора в функцию, которая принимает Traversable или iterable, приводит к WTF казусу, если она вполне законно пытается обойти аргумент больше одного раза. Если очень хочется, чтобы инстанс генератора отрабатывал многократно, и при этом вы уверены, что это не приведёт к ненужным побочным эффектам, можно обернуть функцию, порождающую генератор, в 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.
Принцип подстановки Барбары Лисков

Принцип подстановки Барбары Лисков (англ. Liskov Substitution Principle, LSP) в объектно-ориентированном программировании является специфичным определением подтипа, предложенным Барбарой Лисков в 1987 году на конференции в основном докладе под названием Абстракция данных и иерархия .

Wikipedia