Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

logical non-short-circuit operators

by december (Pilgrim)
on Nov 02, 2011 at 18:22 UTC ( [id://935464]=perlquestion: print w/replies, xml ) Need Help??

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

Hello, fellow monks,

I've got a silly question regarding the use of short-circuit operators in assignments. I want to do something like this (in my code there's actually and instead of or – but I'd like to change it):

if (my $num = $recFono->field_as_text('102') or my $type = $recFono->f +ield_as_text('104')) { something(); }

The problem is of course that the second assignment isn't executed if the first one succeeds. I'd like both assignments to be executed and only then evaluated so the code in the conditional runs if either one or both of those variables are set. A non-short-circuiting or, so to speak.

I've been looking into using the comma operator for the assignments then re-evaluating the assigned variables with or – all in one long chain, but apparently those variables aren't in scope yet at that point.

Is what I'm doing here silly or am I overlooking a simple logical trick? Is it a bad idea to execute, assign and do logical evaluation in one go?

Thanks!

Replies are listed 'Best First'.
Re: logical non-short-circuit operators
by moritz (Cardinal) on Nov 02, 2011 at 18:34 UTC
    my $num = $recFono->field_as_text('102'); my $type = $recFono->field_as_text('104'); if ($num && $type) { something(); }

    This has the benefits of

    • Letting the assignments standing out clearly
    • Shortening the individual lines, making them easier to read
    • Clearly conveys that you want the arguments of the logical operator evaluated independent of truth/falsehood of the first one

    If you really want it on one line, you can write your own logical function:

    sub myor { $_[0] or $_[1]; } if (myor( ..., ...)) { }
      ++, looks good.

      But I think you mean

      if ($num || $type) { # (|| rather than &&) something(); }

      Mike

      You're right, of course. The reason I avoided the former approach was because I have a lot of similar statements and I was hoping to keep the assignments in the scope of the conditional so as not to pollute the namespace or by accident reuse an old variable.

        If you have many similar statements, maybe you could refactor them to use a table for the conditions and a loop (or so), or in some other way. Code duplication or near-duplication is usually a sign that you can do it better somehow.

        If you want to avoid the variables leaking out, you can just put another block around the whole thing (variable declarations and if block).

      I strongly agree.   When I read this code, it is immediately obvious that “the designer’s intent” is that both function calls will be and should always be executed.

      Years ago, the manufacturers of a debugging tool would publish in Dr. Dobb’s Journal a short excerpt of “C” code with the challenge to figure out what the code actually did.   My impression was always, “gee, I can’t afford to use a language like that encounter code written like that.”   (Note that I’m not talking about the debugger tool that was being advertised.)   Code has to be clear and obvious above all other things, such that anyone who might be reading the unfamiliar code (perhaps under conditions of pressure and great haste) can instantly and correctly understand it.   The compiler can take care of itself.   (A tiny scrap of code, written by persons unknown, a mere four lines long but buried out of sight, once cost me $10,000 in real money.)

        Code has to be clear and obvious above all other things, such that anyone who might be reading the unfamiliar code (perhaps under conditions of pressure and great haste) can instantly and correctly understand it.

        Let' s posit a few equivalent scenarios.

        1. Every legal document has to be clear and obvious so that any newly qualified lawyer that just barely scraped through law school can immediately apply it to every possible situation to which it might be applicable.
        2. Every music score should be so simple and obvious that any school kid with a tin whistle should be able to render it with same fidelity as a full orchestra.
        3. Every engineering blueprint should be so clear and obvious that any half-competent DIY enthusiast with a Swiss Army knife and a Leatherman will be able to produce the component over a weekend.
        4. Every electronics schematic should be so clear and obvious that anyone with a soldering iron can knock one up in a couple of hours.
        5. Every annotation of the Human Genome should be so clear and obvious that any kid with a Junior Chemistry kit can whip themselves up a little brother or sister once they've finished their homework.

        Just because the world and his dog can pick up a copy of "Sams Teach Yourself HTML 4 in 24 Hours" and put together a web page with lurid fonts, pretty pictures, a hit counter and bunch of social site click buttons in a weekend, it doesn't mean that professional programmers should dumb down their code in the vain hope that: anyone who might be reading the unfamiliar code (perhaps under conditions of pressure and great haste) can instantly and correctly understand it."

        Programming is one of the most complex endeavours man undertakes. Doing it well requires knowledge of such a range of diverse and ever changing algorithms and disciplines; and it can be applied to a huge range of problems. The very expectation that even highly competent and experienced programmers coming from different disciplines or backgrounds should be able to instantly and correctly understand another's programs is ludicrous.

        It is like suggesting that an aroma therapist should be able to take over from a heart specialist or a brain surgeon at a moments notice.

        In no other professional discipline do its exponents make such claims. When will programmers stop devaluing the skill, expertise and learning required to perform their trade by making such puerile and facile claims?


        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: logical non-short-circuit operators
by ikegami (Patriarch) on Nov 02, 2011 at 18:59 UTC

    Why? Does field_as_text have a side effect? If so, it's poorly named.

    If the assignments are the side effects you want to perform unconditionally, then move them out of the condition.

    my $num = $recFono->field_as_text('102'); my $type = $recFono->field_as_text('104'); if ($num || $type) { ... if ($type) { ... } ... }

    If it's a scoping issue, create a scope.

    { my $num = $recFono->field_as_text('102'); my $type = $recFono->field_as_text('104'); if ($num || $type) { ... if ($type) { ... } ... } }
Re: logical non-short-circuit operators
by hbm (Hermit) on Nov 02, 2011 at 18:55 UTC

    Is it too unwieldy without placeholder variables, like this?

    if ($recFono->field_as_text(102) or $recFono->field_as_text(104)) { something(); }

    If so, can your data structure be more concise? Perhaps if ($Fono->text(102) or $Fono->text(104)) {

    Otherwise, as moritz says.

      Hmm... I need the variables inside the conditional's code. I was just hoping to avoid having to make the assignments outside of the conditional block (and hence outside of its local namespace).

Re: logical non-short-circuit operators
by JavaFan (Canon) on Nov 02, 2011 at 21:33 UTC
    Assuming that field_as_text doesn't return objects with weird overloaded bool logic:
    no warnings 'uninitialized'; if (!!(my $num = $recFono->field_as_text('102') + !!(my $type = $recFono->field_as_text('104')) { something(); }
    Although I would just write multiple statements:
    my $num = $recFono->field_as_text('102'); my $type = $recFono->field_as_text('104'); if ($num || $type) { something(); }
Re: logical non-short-circuit operators
by Anonymous Monk on Nov 02, 2011 at 19:48 UTC
    if (grep $_, my $num = $recFono->field_as_text('102'), my $type = $recFono->field_as_text('104'), ) { ... }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-04-19 14:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found