Re: New module: Array::Each

From: Brad Baxter (bmb_at_ginger.libs.uga.edu)
Date: 03/29/04

  • Next message: Anno Siegel: "Re: New module: Array::Each"
    Date: Mon, 29 Mar 2004 11:41:07 -0500
    
    

    On Sun, 28 Mar 2004, Anno Siegel wrote:

    > Brad Baxter <bmb@ginger.libs.uga.edu> wrote in comp.lang.perl.misc:
    >
    > [...]
    >
    > > And this code returns groups of elements from each array, and it returns
    > > the value in $undef if we've gone past the end of any array:
    > >
    > > my @ret;
    > > foreach my $aref ( @$set ) {
    > > push @ret, map {$_<@$aref ? $aref->[$_] : $undef}
    > ^
    > What is that "$"? Not the result of a copy/paste operation for sure :)
    >
    > > ($i..$i+$group-1) }
    > > return ( @ret, $c );

    In fact, it is a copy/paste, but I can see it's confusing out of context.
    Here's another example of that construct that perhaps shows better my
    intent:

    sub each_group { # group is defined
        my $self = shift;
        my $group = $self->[GROUP];
        my $i = $self->[ITERATOR]; # inlined
        $self->[ITERATOR] += $group; # incr_iterator
        $self->[ITERATOR] = $self->[REWIND], # inlined rewind
            return if grep {$i >= @$_} @{$self->[SET]};
        my @ret;
        foreach my $aref ( @{$self->[SET]} ) {
            push @ret,
                map {$_<@$aref ? $aref->[$_] : $self->[UNDEF]}
                ($i..$i+$group-1) }
        ( @ret, $i );
    }

    So you see, $undef is really $self->[UNDEF], a user-definable value to be
    used when the code falls off the end of an array.

    > >
    > > I'd like to think this could be done with two maps in succession, but
    > > inspiration just hasn't come.
    >
    > The inner map can be written as a slice: @$aref[ $i .. $i + $group - 1]"
    > That will give you undef beyond the array limits. Since $_ is no longer
    > used in the inner expression, now the outer loop can become a map:
    >
    > my @ret = map @$_[ $i .. $i + $group - 1], @$set;
    > return ( @ret, $c);

    Yes, this will give me undef beyond the array limits, but I want it to
    give me $self->[UNDEF] (but not change _existing_ undefined elements).

    I took another close look at perlvar to see if I missed a special
    variable. I looked for one that would let me tell perl what to supply in
    the case of a slice element (or array element autovivification, too?) when
    it goes past the end. Something along these lines:

    my ( @a, @b );
    {
        local ${^UNDEF} = ''; # imaginary special variable
        @a = (undef)[0..2]; # note, undef NOT changed when explicit
        $#b = 2;
    }

    Then @a would contain (undef,'','') and @b would contain ('','','')
    instead of the current (undef,undef,undef). I don't think such a special
    variable exists--at least, I didn't see reference to one.

    Regards,

    Brad


  • Next message: Anno Siegel: "Re: New module: Array::Each"