Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^3: [Perl6] Seq iterator already consumed

by duelafn (Parson)
on Jun 17, 2019 at 13:36 UTC ( [id://11101467]=note: print w/replies, xml ) Need Help??


in reply to Re^2: [Perl6] Seq iterator already consumed
in thread [Perl6] Seq iterator already consumed

@dirs contains nothing until you call the split. Split doesn't iterate the Seq, it creates them. Then the join iterates them the first time and map tries to iterate them again.

my @paths = data(); my @dirs.push: $_.split('/') for @paths; # A : @dirs == [(...).Seq, + (...).Seq] say $_.join('/') for @dirs; # C : @dirs == [Seq.new-co +nsumed(), Seq.new-consumed()] my $depth = @dirs.map(*.elems).min; # D : oops, consumed!

Personally, I think the nicest looking way to fix this is to consume the Seq into an Array (update: though upon consideration, using .cache may be more efficient since it is lazy)

my @dirs.push: [ $_.split('/') ] for @paths;

Calling .perl "fixes" the error because the .perl method automatically calls .cache for you. Else attempting to debug via .perl would consume the Seq which would generally break code. The documentation for Seq mentions this:

Caching is a volatile state exposed to the developer as an optimization. The Seq may become cached by many operations, including calling perl on the Seq (if called prior to a non-cached iteration).

Good Day,
    Dean

Replies are listed 'Best First'.
Re^4: [Perl6] Seq iterator already consumed
by Athanasius (Archbishop) on Jun 19, 2019 at 06:51 UTC

    Hello Dean,

    Thanks for this explanation! I apologise for not replying sooner, but I wanted to look at the whole question with a fresh pair of eyes first. You are absolutely right:

    my @dirs.push: $_.split('/') for @paths; say @dirs.perl;

    shows:

    [("", "aardvark", "bison", "camel", "dromedary").Seq, ("", "aardvark", + "bison", "camel", "dromedary", "elephant").Seq]

    (i.e., 2 unconsumed Seq objects), but with .cache added to the split they are Lists:

    [("", "aardvark", "bison", "camel", "dromedary"), ("", "aardvark", "bi +son", "camel", "dromedary", "elephant")]

    — and therefore can be iterated as often as needed.

    Update:

    upon consideration, using .cache may be more efficient since it is lazy

    Where is this documented?

    Thanks again,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Again, the documentation for Seq:

      A Seq represents anything that can lazily produce a sequence of values. A Seq is born in a state where iterating it will consume the values. However, calling .cache on a Seq will return a List that is still lazy, but stores the generated values for later access.

      Good Day,
          Dean

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-03-29 08:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found