Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Re: How to make references more like aliases?

by Prior Nacre V (Hermit)
on Sep 28, 2004 at 03:57 UTC ( [id://394457]=note: print w/replies, xml ) Need Help??

in reply to How to make references more like aliases?

I didn't really have a problem with the FUGLY line; however, I did think the closure was doing more than necessary and I generally don't like passing whole arrays, so here's yet another variation on this theme.

I have noted what appears to be a bug (but it may be the intended behaviour).

use strict; use warnings; my @array = 0 .. 30; my $rc_next = by_groups_of( 3, [ \(@array) ] ); while ( my $ra_group = $rc_next->() ) { last unless @$ra_group; ${$ra_group->[1]} = 'foo'; } print "$_\n" for @array; sub by_groups_of { my ($by, $ra_list) = @_; $by ||= 0; $ra_list ||= []; my $rc_return = sub { [] }; if ($by && $by !~ /\D/ && @$ra_list) { my $pos = 0; my $done; $rc_return = sub { return [] if $done; my $start = $pos; my $stop = $pos + $by - 1 > $#{$ra_list} ? $#{$ra_list} : +$pos + $by - 1; #$pos += $by - 1; # ?? bug ?? - changed to "$pos += $by; +" $pos += $by; $done = 1 if $stop == $#{$ra_list}; return [ @{$ra_list}[$start .. $stop] ]; }; } return $rc_return; }



Replies are listed 'Best First'.
Re^2: How to make references more like aliases?
by Limbic~Region (Chancellor) on Sep 28, 2004 at 12:47 UTC
    Prior Nacre V,
    I generally don't like passing whole arrays

    Neither do I. But what you did is likely even more work than passing the whole array. Your code is equivalent to the following:

    • Make a reference to every element in the array
    • Make a copy for the anonymous array
    • Pass the reference to the anonymous array

    To avoid making copies and only passing a reference, that should have been by_groups_of( 3, \@array ). Additionally, an iterator should stop when it is finished. In your code, you have to explicitly force it to abandon the infinite loop.

    I do appreciate the reply and finding the fencepost bug. See this node for the latest version.

    Cheers - L~R

      Benchmarking disagrees with you.

      The closure is generated only once - my code does more here:

      by_groups_of( 3, \@array ); by_groups_of( 3, [ \(@array) ] );

      The closure is called multiple times - your code does more here:

      return sub { \@_ }->( @$list[ $start .. $stop ] ); return [ @{$ra_list}[$start .. $stop] ];

      I benchmarked on a P3/Win98 system using both Cygwin/Perl5.6 and Msys/Perl5.8. I got comparable results for both versions (no discernible speed differences). These results were repeated when volume testing with array sizes between 100,000 and 500,000.

      At the end of the day, either will do nicely :-)



        Prior Nacre V,
        Benchmarking disagrees with you.

        Then you misunderstood what I said. I made no claim my code was faster, only that your statement (I generally don't like passing whole arrays), seemed odd given what you were doing is more work than passing a whole array.

        Now my goal was being user-friendly, not being fast which is why I preferred $group->[1] over ${ $group->[1] }. But since you did bring up speed, my rudimentary tests show my code as being much faster. Perhaps you should try the following:

        Cheers - L~R

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://394457]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2024-05-27 07:35 GMT
Find Nodes?
    Voting Booth?

    No recent polls found