ww has asked for the wisdom of the Perl Monks concerning the following question:

This newbie got major help from ikegami (++!) in making this question coherent. In fact, the good Friar also came up with an elegant script to achieve the original intent.

BUT, reviewing his work, my mess, the perl documentation, owl, llama, and supersearching... I still am missing something (and very possibly, something very obvious to many of you)... to wit; why doesn't the split /$splBRK/ in &splBRK remove the "~~" in the $aphors?

#! c:/perl/bin -w use strict; # vars use vars qw( $aphor $new @new $max $min $splBRK $rest $subscript); $aphor = ""; # the selected "fortune" $new = ""; # $aphor after $splBRKs are s///to '\n\t' $max = 65; # var for position inside substr at which breaki +ng is more strongly needed than at $min $min = 52; # $min, which is actually used for s/// $splBRK="~~"; # char pair in aphor.asc to mark positions of man +datory newlines (ie, at the end of each # quote in aphor.asc that needs, on rendering, + to be set off with a newline $rest =""; my $aphor1 = "This is a short line ~~ with a splBRK."; my $aphor2 = "Q: How many shrinks does it take to change a lightbulb?~ +~A: One ...but the lightbulb has to want to change."; my $aphor3 = "This is a short line followed by space-dbltilde-space ~~ + This should be printed on a newline."; my $aphor4 = "Test line with double-tilde here~~and more stuff that is + more than var_max chars in length so that we also get a test of the +line splitting after approx 60 characters after which there's some le +ft over."; my $aphor5 = "Variant with space-double-tilde (after the space) ~~and +enuf more chars that the total length is more than var_max chars in l +ength so that we also get a test of the line splitting after approx 6 +0 characters after which there's some left over."; my $aphor6 = "No splBRKs in this: Now is the time for all good men to +come to the aid of their country while the quick red fox jumps over t +he lazy brown dog's back and the fork runs away with the spoon."; my $aphor7 = "This is a short line (but more than min) with no splBRKs +."; # main if ( $ARGV[0] && ( $ARGV[0] > 0 ) && ($ARGV[0] < 8 ) ) { $subscript = $ARGV[0]; print "\nSELECTING \$aphor$subscript \n"; } else { die "No ARGV or ARGV out of range! Useage: perl cli2.pl 1..7"; } if ($subscript == 1) { $aphor = $aphor1 } elsif ($subscript == 2) { $aphor = $aphor2 } elsif ($subscript == 3) { $aphor = $aphor3 } elsif ($subscript == 4) { $aphor = $aphor4 } elsif ($subscript == 5) { $aphor = $aphor5 } elsif ($subscript == 6) { $aphor = $aphor6 } elsif ($subscript == 7) { $aphor = $aphor7 } else { die "ARGV out of range"; # belt & suspenders } if (length($aphor) > ($max+6) || $aphor =~ /~~/ ) { # plus six is a +n ARBITRARY ALLOWED OVERRUN &splBRK; } else { $new = "\n\t" . $aphor; &out; exit(58); }
# sub splBRK -- breaks a line of undefined length by replacing each + $splBRK with a \n\t # # BUT the split /$splBRK/... (with or w/o parens) is NOT removing all + splBRKs # NOR does it work with "/~~/" sted "/$splBRK/" sub splBRK { $_ = $aphor; if (/$splBRK/) { # are there any $splBRK??? print "\n\tFrom sub_splBRK: splBRK found\n"; # DEBUG stmnt } else { print "\n\n\t NO splBRK found\n"; &shortenlines; exit(75); } my @sect = split /$splBRK/; $new= join "\n\t", @sect; &shortenlines; }
# SUB shortenlines -- breaks a line of undefined length by replacing + # a space with a \n at least every $max chars # Match is not yet capable of dealing correctly w/the likes of "...yak +ity yak (blah, blah.)" sub shortenlines { use vars qw($post); $rest = "\n\t" . $aphor; @new = $rest =~ m/\G(.{$min,$max}[\x20.])?/gsx; if ($') { $post=$'; $new[$#new] = $post; } print "\n\n\t----- 100 (after splt and jn) --------\n\n"; foreach my $item (@new) { if ($item) { print "\t$item \n"; } } print "\n\n\t------------------------------------\n\n"; exit(108); } # SUB out # alternate print for short lines w/no splBRKs sub out { print "\n\n\t----- SUB OUT 116---------------------\n\n"; print "$new"; print "\n\n\t ---- DONE: FROM SUB out ---------- \n"; exit(121); }

Replies are listed 'Best First'.
Re: unexpected behavior with split
by ikegami (Patriarch) on Aug 31, 2004 at 18:35 UTC

    Actually, I'm pretty sure that it is working. It's just that you are discarding your changes by sometimes using $new, sometimes using $aphor. Specifically:

    $new= join "\n\t", @sect; &shortenlines; # uses $amphor for input instead of $new.

    You'll gain so much by using proper parameters and return values. It is much harder to make a good program that uses globals and exit() all over the place (but not impossible, says Wassercrats).

      ikegami:
      Bingo! ...and thank you!

      $rest = "\n\t" . $new; #see ikegami's reply; was ". $aphor"

      Now I will give both your alt solutions the study they deserve (something, I've been holding off on in hopes I could find my own errors).

      I think I understand the underlying difference in approach lies in your design of REMOVING the matches from the front of $new, so each iteration has to start the count at an appropriate point while my

      @new = $rest =~ m/\G(.{$min,$max}[\x20.])?/gsx;

      is either
      a) an abuse of \G (owls, p15 sez "Beginning of current search" (emphasis supplied) whereas I (mis)read other docs to imply that it reset the start of the search
      or...
      b) use of the "?" quantifier is wrong.

      And even if neither of those proves out, many thanks, both for the wisdom imparted and the implicit encouragement.

        I didn't use \G as a way of avoid using $'. I could have come up with a way of using \G and not using $', but I chose this way.

        I did get rid of $max+6. It makes no sense. I think it was added as a hack to make $min look like it's working better than it really does. In fact, $min is totally useless unless you force a break mid-word whern there is no space between pos $min and $max (which you don't do). Until $min's function is better defined, I just dropped it completely from my version. I suppose s/^(.{$min,$max2}\S)\s+//s would probably do what you have in mind, because of the else clause.

Re: unexpected behavior with split
by Not_a_Number (Prior) on Aug 31, 2004 at 22:01 UTC

    Oh dear.

    Allow me to quote from talexb's reply to a post earlier today:

    I'm guessing that you won't get much (serious) help on this -- you're asking us to spend significant time to debug a piece of code. You've come to the wrong site for that. Here's what this site (and community) is about: you bring your boiled-down, condensed, pithy Perl question to us, and we give you lots of varied answers and different approaches. You learn something, and perhaps we do too. I suggest you go away and do some work on your question, and come back when you've narrowed it down a bit...

    We don't want to see your entire code (in particular, when you've learned a little more about Perl, you'll be ashamed about stuff such as:

    if ($subscript == 1) { $aphor = $aphor1 } elsif ($subscript == 2) { $aphor = $aphor2 #... up to and including elsif (subscript == 7) { .. }

    but as you're learning, at present, that's OK).

    But what's not OK is to post the whole mess here. Note my emphasis of talexb's 'boiled-down, condensed, pithy' (if you don't know what 'pithy' means, well, er... it's pretty much the same as 'condensed' (or 'boiled-down' :) ).

    I simply don't have the time to look through all of your 135 lines (in my editor) of code, and I imagine that most other Monks don't, either.

    The moral is: Condense it! Boil it down! Extract the pith!

    First, for example, your question has nothing to do with command-line processing, so take out all the stuff about @ARGV.

    Second, we don't need to know how you define and select your aphorisms according to user input. If you have a problem with parsing user input, make it the subject of a separate post, not one entitled 'unexpected behavior with split'. This means that you could replace 43 lines (in my editor) of code (including the @ARGV stuff) - from if ($subscript == 1) { to the '}' just after die "ARGV out of range"; - with just one line, namely:

    my $aphor = 'whatever';

    where 'whatever' corresponds to one of the aphorisms that you are having problems with.

    How to post condensed (boiled-down, pithy) code: Let's say I write some code that Perl doesn't want to compile (a regular occurrence, I assure you). After examining the error messages, and correcting my most ridiculous mistakes, and other stuff, if it still doesn't do what I want, I postulate that there might be an error in the line:

    my @sect = split /$splBRK/;

    So, I create a new perl file (I call it 'test.pl', YMMV):

    use strict; use warnings; my $str = 'aa~~bb'; my $splBRK = '~~'; my @sect = split /$splBRK/, $str; print "<$_>\n" for @sect;

    Well, it seems that test.pl (after trying as many test cases as I can think of) works as expected , implying that the problem is elsewhere in my code. So, ikegami++ (how I envy his/her patience!) is probably right.

    I could go on, but I think that a Tutorial entitled 'Basic Debugging' (or something...) might be in order. A lot of interesting stuff has already been posted in PM, such a tutorial could be mainly just be a synthesis of these nodes, but time (as ever) is not extensible...

    dave

      Dave:

      Thank you too. ikegami did me the kindness of offering many corrections/suggestions/tactics on the original code... of which, even as a learner, I was well and truly ashamed once I understood his points. I'm similarly chastened, but also more educated, thanks to your pointers.

      And as my last reply noted, I now know the title was hopelessly hapless. For that too, apologies to you and all others who stumble upon it.

      I would welcome a reference to any tutorial you care to recommend on useing a debugger effectively. print statements (only a few of which made it into the posted code) go only so far... and regrettably, I'm still finding the docs for activestate's debugger almost impenetrable.