Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

guidelines for inline coding

by misterperl (Pilgrim)
on Sep 25, 2014 at 15:30 UTC ( [id://1101983]=perlquestion: print w/replies, xml ) Need Help??

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

I don't see a lot of documentation on inline coding like these
1 statement if condition; 2 statement for array; 3 { statement1; statement2; .. statementN; } for array; 4 ( statement for array ) if condition; 5 statement if condition else other_statement; 6 statement while condition;

* * * The last 3 would be particularly useful. I've tried them with various parens but they always seems to syntax error. Same with most others except a single if for or while.

Camel and Panther and Jackyl have very little to say about these constucts, but they are very useful and can yield extreme code-compression and readability.

Is there a tutorial or large set of examples, or guidelines and rules, somewhere on inline coding?

Just the other day I reduced someone's code by 1/2 then Mr suicidejunkie reduced it like 80% with this approach. Very elegant, very efficient, and easy to read (like English)..

Haters please do not reply. I'm just asking....

Replies are listed 'Best First'.
Re: guidelines for inline coding
by choroba (Cardinal) on Sep 25, 2014 at 15:33 UTC
    As you can find in perlsyn, post-position modifiers are only possible with "simple statements". Block or a statement with a modifier are not simple statements.

    To turn a block into a simple statement, wrap it in a do:

    do { statement1; statement2 } for @array;

    But I'm not sure it still buys you anything.

    Also, note that  do { ... } while (condition) checks the condition after the first iteration of the loop.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: guidelines for inline coding
by Laurent_R (Canon) on Sep 25, 2014 at 17:25 UTC
    If you are looking for something like this, you can see that it works:
    $ perl -e 'my $i = 0; print $i++, " " while $i < 10;' 0 1 2 3 4 5 6 7 8 9 ~ $ perl -e 'my @array = 1..10; print 2*$_, " " for @array;' 2 4 6 8 10 12 14 16 18 20 ~
    you can also do things like this:
    for (@array) { print $ERRORS "Error: value $_ is negative\n" and next if $_ < 0; push @valid_vals, $_; }
    But you cannot do this:
    5 statement if condition else other_statement;
    You can't use an other clause when if is used as a statement modifier (i.e. after the statement).

      I like the additions. I feel like print "xyz" and… is a Heisenbug waiting to happen though. As rare and weird as it is, print can return false. Can’t remember who but some monk was so concerned about it they advocated checking its return on each call.

        Hi Your Mother,

        I agree that all my three examples are somewhat simplistic, I just wanted to convey the idea of the syntax that the OP was apparently looking for. In the third case, it is true that if print fails, the next statement will not be executed and the next line of code will be executed, which is presumably not what you want. But, OTOH, if the print statement fails, we have much deeper trouble than this possible Heisenbug, so that the random bug is really not the major concern.

        Having said that, I fully agree that the do_some_statement() and do_some_other_statement() if something_is_true is nice for writing concise code, but can be dangerous if you are not cautious enough.

        I once made the mistake of writing some code basically looking like that:

        $nb_errors++ and next if some_condition(); # wrong, don't do it
        That worked perfectly for most of the cases, except the first time when an error occurs through the loop, because $nb_errors was false (either 0 or undef) the first time through the loop. Changing it to:
        ++$nb_errors and next if some_condition();
        is sufficient to correct the issue. But it shows that such a construct can be dangerous and must be carefully considered.
        As rare and weird as it is, print can return false. Can’t remember who but some monk was so concerned about it they advocated checking its return on each call.

        Completely pointless. What are you going to do if it returns false? print an error message?


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: guidelines for inline coding
by SuicideJunkie (Vicar) on Sep 25, 2014 at 18:04 UTC

    I think it mostly comes down to what looks simple to humans.

    Something like do{do{print $_.',' if $_/2 == int($_/2)} for ($_..$_+4); print ' :: '} for (1..50) works, but would be far better as a multiline block.

    do {print "K=$_, V=$hr->{$_}\n" if sensibleToDo($_)} for keys %$hr; is still quite a large mouthful.

    The do{} can be dropped if you use an and/or in place of the if.
    EG:isSensible($_) or send_alert("Help: $_ : $!\n") for (@files).
    The niceness depends a lot on what you're actually doing and how well your functions and variables are named. The more the actual statements read like an English sentence, the less there is to complain about.

    In general, if you feel a desire to nest post-conditionals, you should consider the option of making the whole line a subroutine instead.

Re: guidelines for inline coding
by BrowserUk (Patriarch) on Sep 25, 2014 at 21:04 UTC

    My top tip for using statement modifiers is this:

    print, sum += $_ for @array;

    That is, if you find yourself wanting to trace the loop, don't go through the pain of reformatting the loop as block scoped in order to print the iteration, just add the print with a comma as a line preceding the modified loop.

    Then comment the added line out or just blow it away when your done debugging.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks monks for all of the insight and advice, it's all most appreciated. I guess bottom-line is as advised, the inline statements are only for simple cases. In general I want my code to look more like an sentance than code, like Englishizing:
      if ( $cat ) { $dog='onALert'; }
      to
      $dog='onALert' if $cat;
      its so much cleaner, easier to read. It would be even nicer if "is" could substitute for =", (sort of like SQL "is NULL") then:
      $dog is 'onALert' if $cat; $dog is 'sleeping' unless $cat;
      Nice! Thanks guys for the insight- I'm just syntax-surfing techniques to pretify my code...
Re: guidelines for inline coding
by Anonymous Monk on Sep 25, 2014 at 17:29 UTC

    Note it's also possible to combine statements with and, or, &&, ||, and even xor. So e.g. something() and otherthing() if $condition; (assuming you know something() will be true). B::Deparse can be helpful in figuring out how your stuff is being parsed:

    $ perl -MO=Deparse,-p -e 'something() xor otherthing() if $condition;' ($condition and (something() xor otherthing()));

    Whether or not that's more readable or not is a matter of taste, and a matter of whether the coders maintaining it know their precedence tables :-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-24 07:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found