in reply to how do I line-wrap while copying to stdout?

Could this code be good?
chomp; while (length($_) > 80) { print substr( $_, 0, 80) . "\n"; $_ = substr( $_, 80, length($_) - 80); } print;
or am I missing something?

Replies are listed 'Best First'.
Re: Re: how do I line-wrap while copying to stdout?
by jeroenes (Priest) on Apr 20, 2001 at 12:08 UTC
    We can condense that a little bit:
    print substr( $_, 0, 80, '')."\n" while length >80; print;
    I left out the chomp to keep the newline....

    Jeroen
    "We are not alone"(FZ)

    Update: Removed two redundant characters.
    2: substr isn't that bad.... see thread below

      You might also benchmark a version that's not destructive to the string, which could possibly win for long strings:
      print "$1\n" while /\G(.{1,80})/gs;
      The advantage here is that the long string in $_ can remain idle and yet scanned, while the substr version requires constant shifting and shortening. And just to factor out the multiple prints, also try:
      print map "$_\n", /\G(.{1,80})/gs;

      -- Randal L. Schwartz, Perl hacker

        Well, why not?
        use Benchmark; undef $/; open DATA, "/home/jeroen/texs/review/reviewnew.tex" or die $!; #just s +ome lengthy manuscript $str = <DATA>; open DUMP, ">/dev/null"; timethese( -1, {'regex' => sub { $a = $str; print DUMP map "$_\n", $a=~/\G(.{1,80})/gs; }, 'substr' => sub { $a = $str; $b=''; $b .= substr( $a, 0, 80, '')."\n" while length($a) >80; print DUMP "$b$a"; } }); #givesBenchmark: running regex, substr, each for at least 1 CPU second +s... regex: 1 wallclock secs ( 1.05 usr + 0.01 sys = 1.06 CPU) @ 28 +7.74/s (n=305) substr: 1 wallclock secs ( 1.26 usr + 0.01 sys = 1.27 CPU) @ 55 +6.69/s (n=707) #This changes a bit when leaving the map out: Benchmark: running regex, substr, each for at least 1 CPU seconds... regex: 2 wallclock secs ( 1.06 usr + 0.00 sys = 1.06 CPU) @ 39 +6.23/s (n=420) substr: 2 wallclock secs ( 1.04 usr + 0.02 sys = 1.06 CPU) @ 54 +7.17/s (n=580) #I left the print out@substr at first (didn't want to test # print), but putting it back in gives: Benchmark: running regex, substr, each for at least 1 CPU seconds... regex: 1 wallclock secs ( 1.30 usr + 0.01 sys = 1.31 CPU) @ 36 +6.41/s (n=480) substr: 1 wallclock secs ( 1.06 usr + 0.02 sys = 1.08 CPU) @ 47 +3.15/s (n=511) #I added a better comparison: Rate regmap regex fixreg substr regmap 285/s -- -19% -22% -56% regex 350/s 23% -- -4% -46% fixreg 364/s 28% 4% -- -44% substr 650/s 128% 86% 78% --
        Apparently, the substr is just too efficient compared to regex. End the print is only a bit inefficient compared to storing stuff in memory.

        Jeroen
        "We are not alone"(FZ)

        As above (in merlyn's code) but with a swap
        s/\G(.{1,80})/$1\n/gs; print;
        Maybe I should benchmark that. This doesn't have the advantage of not affecting long strings and it does put multiple lines into one variable, but that might be OK.

        Couldn't help but benchmark this thing...
        use Benchmark qw(cmpthese); open(STDERR,">/dev/null"); cmpthese (10000, { match => sub { local $_ = "abcde " x 100; print STDERR "$1\n" while /\G(.{1,80})/gs +; }, swap => sub { local $_ = "abcde " x 100; s/\G(.{1,80})/$1\n/gs; print STDERR $_; }, });
        Produces
        Benchmark: timing 10000 iterations of match, swap... match: 1 wallclock secs ( 1.26 usr + 0.01 sys = 1.27 CPU) @ 78 +74.02/s (n=10000) swap: 1 wallclock secs ( 1.01 usr + 0.01 sys = 1.02 CPU) @ 98 +03.92/s (n=10000) Rate match swap match 7874/s -- -20% swap 9804/s 25% --
        So the swap will save you time (if you are nitpicky about speed).
Re: Re: how do I line-wrap while copying to stdout?
by ams (Initiate) on Apr 20, 2001 at 11:48 UTC
    thanks. much clearer. I was originally looping on (length($_) gt 0) but then the substr expression gave be run-time warnings. looping on (length gt 80) simplifies it.
    -allan