Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is glob in scalar context a lazy iterator?

Tags:

perl

I quite like glob's often overlooked iterator-esque functionality.

What's not clear to me is whether it computes/loads the entire list into memory even when used in scalar context. In this example code, the while loop does not print anything to screen (4**24 is not a small number):

use strict;
use warnings;
use feature 'say';

my $opt = "{A,B,C,D}" x 24;
say while glob $opt;

Things I've tried/observed:

  • I tried to eliminate the possibility of buffering being an issue by writing 1 while glob $opt;, but it still takes forever and I end up Ctrl+C'ing out.

  • Inspection of my memory usage via Windows Task Manager doesn't seem to show any difference when I run the script.

  • Running perl -MO=Deparse only confirms that glob is being used in scalar context without indicating anything about memory usage.

  • Running perl -MO=Concise results in the following output, which I don't know how to decipher:

    m  <@> leave[1 ref] vKP/REFC ->(end)
    1     <0> enter ->2
    2     <;> nextstate(main 49 -:5) v:%,*,&,{,x*,x&,x$,$,469762048 ->3   
    7     <2> sassign vKS/2 ->8
    5        <2> repeat[t2] sK/2 ->6
    3           <$> const[PV "{A,B,C,D}"] s ->4
    4           <$> const[IV 24] s ->5
    6        <0> padsv[$opt:49,74] sRM*/LVINTRO ->7
    8     <;> nextstate(main 74 -:6) v:%,*,&,{,x*,x&,x$,$,469762048 ->9
    l     <@> leave vK* ->m
    9        <0> enter v ->a
    -        <1> null vKP/1 ->l
    g           <|> and(other->h) vK/1 ->l
    f              <1> defined sK/1 ->g
    e                 <2> sassign sK/2 ->f
    c                    <@> glob[t5] sK/1 ->d
    -                       <0> ex-pushmark s ->a
    a                       <0> padsv[$opt:49,74] s ->b
    b                       <#> gv[*_GEN_0] s ->c
    -                    <1> ex-rv2sv sKRM*/3 ->e
    d                       <#> gvsv[*_] s ->e
    -              <@> lineseq vK ->-
    j                 <@> say vK ->k
    h                    <0> pushmark s ->i
    -                    <1> ex-rv2sv sK/3 ->j
    i                       <#> gvsv[*_] s ->j
    k                 <0> unstack v ->a
    - syntax OK
    

I'm running ActivePerl 5.16.3.

like image 768
Zaid Avatar asked Dec 20 '25 14:12

Zaid


1 Answers

It does not appear to be lazy when you observe a delay between first glob invocation and first print of the result. This is further corroborated by the time it takes to execute a glob in the scalar context not in a loop (in my example I used smaller exponent so that delay is still noticeable but not too long):

use strict;
use warnings;
use feature 'say';
use Time::HiRes;

$| = 1;

my $opt = "{A,B,C,D}" x 10;
say Time::HiRes::time;
my $x = glob $opt;
say $x;
say Time::HiRes::time;
say while glob $opt;
say Time::HiRes::time;
like image 177
Grrrr Avatar answered Dec 23 '25 00:12

Grrrr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!