Skip to content

Instantly share code, notes, and snippets.

@0racle
Created November 4, 2016 11:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0racle/2c29dc664135525959ccefa795767a08 to your computer and use it in GitHub Desktop.
Save 0racle/2c29dc664135525959ccefa795767a08 to your computer and use it in GitHub Desktop.
Listy Method

For a class method that returns a list, I am performing an expensive computation to a list of values

class Thingy {
    has Int $.start;
    has Int $.end;
    
    method things {
        ($.start .. $.end).map( &expensive_transform );
    }
}

Now, if the user subscripts into the result of that method, it still has to perform the expensive computation on the first $n indexes.

my $t = Thingy.new(:100start :1000000end);
my $n = 64334;
say $t.things[$n]; # waiting...

Ideally, the method should return the result of this instead

    ($.start .. $.end)[$n].map( &expensive_transform );

After some playing around, I realise I could implement AT-POS on the object itself and fudge the method this way

class Thingy {
    ...
    method AT-POS(|pos) {
        ($.start .. $.end)[|pos].map( &expensive_transform );
    }
    method things {
        self[]
    }
    ...
}
say $t.things[$n]; # Instant result

This means the syntax $t[$n] will also work, which may not be ideal.

Is there a way to do it with the method call directly?

Can the method be made aware that it is being subscripted into?

@0racle
Copy link
Author

0racle commented Nov 4, 2016

The other option I can think of is returning an anonymous class

class Thingy {
    has Int $.start;
    has Int $.end;
    method range {
        class {
            has Int $.start;
            has Int $.end;
            method AT-POS(|pos) {
                ($.start .. $.end)[|pos].map( &expensive_transform )[0];
            }   
        }.new(:$.start, :$.end)
    }   
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment