Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: [Perl6] Seq iterator already consumed

by choroba (Archbishop)
on Jun 17, 2019 at 09:11 UTC ( #11101457=note: print w/replies, xml ) Need Help??


in reply to [Perl6] Seq iterator already consumed

From the documentation of lines it seems that it returns a Seq object.

But

say @dirs.^name;

returns Array, so it should be OK. But: split returns a Seq, too! Behold:

say @dirs[0].^name; # Seq

That's probably the problem.

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^2: [Perl6] Seq iterator already consumed
by Athanasius (Archbishop) on Jun 17, 2019 at 12:24 UTC

    Thanks, choroba. I didn’t know about .^name — that’s useful. I found this explanation under https://docs.perl6.org/language/classtut#Introspection:

    The syntax of calling a method with .^ instead of a single dot means that it is actually a method call on its meta class, ...

    I’ll have to look into that.

    But

    say @dirs.^name;

    returns Array, so it should be OK.

    Actually, at this point @dirs contains two Seq objects. I think the subsequent call to split iterates each Seq (which is ok, since a Seq is a one-shot iterable); the later call to map attempts to iterate them again, causing the error.

    This explanation would be fine if it weren’t for line C. Since join iterates over the Seq, it should be line C that produces the error. But it isn’t — and, as I stated in the OP, removing line C removes the error at line D too. So, still confused. :-(

    But I did find another fix: change line A to this:

    my @dirs.push: $_.split('/').cache for @paths; # A'

    At least this looks less like a kludge than line B.

    Cheers,

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

      @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

        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,

Re^2: [Perl6] Seq iterator already consumed
by karlgoethebier (Abbot) on Jun 17, 2019 at 18:21 UTC

    Totally OT and useless but you got rhythm:

    Medium Uptempo Funky Minor Blues Intro... ...Speak: From the documentation of lines it seems that it returns a s +eq object... Verse (very relaxed) But say at dirs dot caret name Returns array, so it should be OK Colored girls: (very vigorously) Behold! (ad lib: Oh yeah, Oh yeah!) But colon split returns a seq, too! Colored girls (very theatrical): Sequence! Say at dirs square bracket zero square bracket dot caret name Colored girls (very lyrically): That's probably the problem. Fill in and move on…

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2022-10-06 07:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My preferred way to holiday/vacation is:











    Results (26 votes). Check out past polls.

    Notices?