Sidef

 view release on metacpan or  search on metacpan

lib/Sidef/Types/Block/Block.pm  view on Meta::CPAN

}

sub while {
    my ($self, $condition) = @_;

    while ($condition->run) {
        $self->run;
    }

    $self;
}

sub loop {
    my ($self) = @_;

    while (1) {
        $self->run;
    }

    $self;
}

sub if {
    my ($self, $bool) = @_;
    $bool ? $self->run : $bool;
}

sub __fdump {
    my ($self, $obj) = @_;

    my $ref = ref($obj);

    if ($ref eq 'Sidef::Types::Number::Number') {
        my ($type, $str) = $obj->_dump();
        return
          scalar {
                  dump => $type eq 'int'
                  ? "${ref}::_set_int('${str}')"
                  : "${ref}::_set_str('${type}', '${str}')"
                 };
    }

    if ($ref eq 'Sidef::Module::OO' or $ref eq 'Sidef::Module::Func') {

        my $module =
          ref($obj->{module})
          ? Data::Dump::Filtered::dump_filtered($obj->{module}, __SUB__)
          : qq{"$obj->{module}"};

        my $module_name = ref($obj->{module}) || $obj->{module};
        return scalar {dump => qq{do { use $ref; eval "require $module_name"; bless({ module => $module }, "$ref"); }}};
    }

    die "[ERROR] Blocks cannot be serialized!" if $ref eq 'Sidef::Types::Block::Block';
    return;
}

sub ffork {
    my ($self, @args) = @_;

    state $x = require Data::Dump::Filtered;
    open(my $fh, '+>', undef);    # an anonymous temporary file
    my $fork = Sidef::Types::Block::Fork->new(fh => $fh);

    # Try to fork
    my $pid = fork() // die "[ERROR] Cannot fork";

    if ($pid == 0) {
        srand();
        my @objs = ($self->call(@args));
        print $fh scalar Data::Dump::Filtered::dump_filtered(@objs, \&__fdump);
        exit 0;
    }

    $fork->{pid} = $pid;
    $fork;
}

*start = \&ffork;

sub fork {
    my ($self, @args) = @_;

    my $fork = Sidef::Types::Block::Fork->new();

    my $pid = CORE::fork() // die "[ERROR] Cannot fork: $!";
    if ($pid == 0) {
        srand();
        $self->call(@args);
        exit 0;
    }

    $fork->{pid} = $pid;
    $fork;
}

sub thread {
    my ($self, @args) = @_;
    state $x = do {
        eval { require forks; } // require threads;
        *threads::get  = \&threads::join;
        *threads::wait = \&threads::join;
        1;
    };
    Sidef::Module::OO->__NEW__(threads->create({'context' => 'list', 'exit' => 'thread_only'}, sub { $self->call(@args) }));
}

*thr = \&thread;

sub _iterate {
    my ($callback, @objs) = @_;

    foreach my $obj (@objs) {

        $obj // last;

        my $sub = (ref($obj) && UNIVERSAL::can($obj, 'iter')) || do {
            my $arr = eval { ref($obj) ? $obj->to_a : Sidef::Types::Array::Array->new($obj) };
            ref($arr) ? do { $obj = $arr; UNIVERSAL::can($obj, 'iter') } : undef;
        };

lib/Sidef/Types/Block/Block.pm  view on Meta::CPAN


sub first {
    my ($self, $n, $range) = @_;

    state $inf_range = Sidef::Types::Number::Number->inf->range;

    $range //= $inf_range;

    my @array;
    my $max = CORE::int($n // 1);

    _iterate(
        sub {
            if ($self->run(@_)) {
                push @array, @_;
                last if (@array >= $max);
            }
        },
        $range
    );

    defined($n)
      ? Sidef::Types::Array::Array->new(\@array)
      : $array[0];
}

sub nth {
    my ($self, $n, $range) = @_;

    state $inf_range = Sidef::Types::Number::Number->inf->range;

    $range //= $inf_range;

    my $k   = 0;
    my $nth = undef;

    $n = CORE::int($n);
    $n > 0 or return undef;

    _iterate(
        sub {
            if ($self->run(@_) and ++$k == $n) {
                $nth = $_[0];
                last;
            }
        },
        $range
    );

    return $nth;
}

sub sum { $_[1]->sum_by($_[0]) }
*Σ = \∑
sub prod { $_[1]->prod_by($_[0]) }
*Π = \∏

sub cache {
    my ($self) = @_;
    $self->{is_cached} && return $self;
    state $x = require Memoize;
    $self->{code}      = Memoize::memoize($self->{code});
    $self->{is_cached} = 1;
    $self;
}

sub uncache {
    my ($self) = @_;
    $self->{is_cached} || return $self;
    state $x = require Memoize;
    if (defined(my $uncached = eval { Memoize::unmemoize($self->{code}) })) {
        $self->{code}      = $uncached;
        $self->{is_cached} = 0;
    }
    $self;
}

sub flush_cache {
    my ($self) = @_;
    $self->{is_cached} || return $self;
    state $x = require Memoize;
    eval { Memoize::flush_cache($self->{code}) };
    $self;
}

sub dump {
    Sidef::Types::String::String->new("$_[0]");
}

*to_s   = \&dump;
*to_str = \&dump;

{
    no strict 'refs';

    foreach my $name (qw(bsearch bsearch_le bsearch_ge bsearch_inverse)) {

        *{__PACKAGE__ . '::' . $name} = sub {
            my ($self, $x, $y) = @_;

            my $from = $x // Sidef::Types::Number::Number::ZERO;
            my $upto = $y // $from->inc->mul(Sidef::Types::Number::Number::TWO);

            while (1) {
                my $k = $from->$name($upto, $self);

                if (defined($k) and $k->is_between($from, $upto)) {
                    return $k;
                }

                $from = $upto->inc;
                $upto = $from->add($from);
            }

            return Sidef::Types::Number::Number::MONE;
        };
    }

    *{__PACKAGE__ . '::' . '*'}  = \&repeat;
    *{__PACKAGE__ . '::' . '<<'} = \&for;
    *{__PACKAGE__ . '::' . '>>'} = \&map;
    *{__PACKAGE__ . '::' . '&'}  = \&grep;
    *{__PACKAGE__ . '::' . '∘'}  = \&compose;
}

1



( run in 0.595 second using v1.01-cache-2.11-cpan-f03e8824b8d )