• (disco) in reply to ben_lubar

    It also doesn't quite do exactly the same thing, so if you really needed array_key_exists(), you better not try to subsititute isset() for it.


    Filed Under: not that we've been burned by that shit where I work.... that's totally not why I know this.
  • (disco) in reply to darkmatter
    darkmatter:
    It also doesn't quite do exactly the same thing, so if you really needed array_key_exists(), you better not try to subsititute isset() for it.

    isset returns false in all cases that array_key_exists returns false, so you could just do if isset || array_key_exists to get the performance without making your code easy to read or changing its meaning.

  • (disco) in reply to ben_lubar

    Except in the one circumstance that I recall, that specifically wasn't what we wanted. We needed the true case, which only array_key_exists would tell us. (or the other way around.... I'm not going to try to go look it up, it wasn't even my project, I just got asked the question by someone else saying "wtf is going on?")

    edit - though that is interesting to think about - i'll have to keep in mind the next time I'm in PHP. Thankfully we're moving towards all .NET (C#)

  • (disco) in reply to ben_lubar

    Hm. Further thinking makes me wonder, if it's 10x better to do isset() than array_key_exists(), then perhaps I should have my colleague use your logic every time, in the cases where the isset() is expected to take precedence at least 10%+ of the time.

    I always used isset() anyways, because I didn't allow the 1 case that array_key_exists() works instead to even happen.

  • (disco) in reply to darkmatter
    package main
    
    import "testing"
    
    const size = 100000
    
    var array = make(map[int]*struct{})
    
    func init() {
            for i := 0; i < size; i++ {
                    switch i % 3 {
                    case 0:
                            array[i] = nil
                    case 1:
                            array[i] = new(struct{})
                    case 2:
                            // not set
                    }
            }
    }
    
    func isset(i int) bool {
            return array[i] != nil
    }
    
    func array_key_exists(i int) bool {
            _, ok := array[i]
            return ok
    }
    
    func BenchmarkIsset(b *testing.B) {
            for i := 0; i < b.N; i += size {
                    for j := 0; j < size; j++ {
                            _ = isset(j)
                    }
            }
    }
    
    func BenchmarkAKE(b *testing.B) {
            for i := 0; i < b.N; i += size {
                    for j := 0; j < size; j++ {
                            _ = array_key_exists(j)
                    }
            }
    }
    
    func BenchmarkIAKE(b *testing.B) {
            for i := 0; i < b.N; i += size {
                    for j := 0; j < size; j++ {
                            _ = isset(j) || array_key_exists(j)
                    }
            }
    }
    
    func BenchmarkAKEI(b *testing.B) {
            for i := 0; i < b.N; i += size {
                    for j := 0; j < size; j++ {
                            _ = array_key_exists(j) || isset(j)
                    }
            }
    }
    
    BenchmarkIsset  50000000                57.6 ns/op
    BenchmarkAKE    50000000                57.0 ns/op
    BenchmarkIAKE   20000000                83.6 ns/op
    BenchmarkAKEI   50000000                69.8 ns/op
    

    In Go, isset and array_key_exists are equivalent in speed, and 57.6ns is probably about the time it takes to execute a comment in PHP.

  • (cs) in reply to foo AKA fooo
    foo AKA fooo:
    CigarDoug:
    2. Please provide a one line example that is BETTER at expressing "0 carrots", "1 carrot", "2 carrots". Seriously. I really want to know a better way to do this. Ternary solutions, used sparingly, can be quite elegant.
    printf (ngettext ("%i carrot", "%i carrots", n), n);
    But what if you have a negative or fractional number of carrots?
  • (disco) in reply to darkmatter
    darkmatter:
    Thankfully we're moving towards all .NET (C#)

    You could be happy if you use Python or RoR. Personally I am making preference of python, but I have heard that RoR is equally good if not better.

  • (disco) in reply to Nagesh

    Which framework are you using? I like Ruby, the language, better. But Python is a fine language. Ruby on Rails is definitely full of good features. Django is pretty good too.

  • (disco) in reply to Captain

    I am working in ASP .NET with C#. Some good day I am using MVC. Right now my assignment is related to Salesforce.com I have ot create some stuff in Salesforce.com I am learning to insert jquery in my Visual Force page.

    Almost missed java servlets. That is where the reporting application is.

  • (disco) in reply to Nagesh
    Nagesh:
    I am working in ASP .NET with C#. Some good day I am using MVC. Right now my assignment is related to Salesforce.com I have ot create some stuff in Salesforce.com I am learning to insert jquery in my Visual Force page.

    Almost missed java servlets. That is where the reporting application is.

    Why do I get the feeling that the project at my last company is being outsourced to you?

  • (disco) in reply to chubertdev

    Because you work with extremely common tools in a well understood domain and are therefore a fungible commodity.

  • (disco) in reply to Captain
    Captain:
    Because you work with extremely common tools in a well understood domain and are therefore a fungible commodity.

    Yeah, but some of the specifics to SFDC have hit home (not just limited to the above comment).

  • (disco) in reply to chubertdev
    chubertdev:
    Yeah, but some of the specifics to SFDC have hit home (not just limited to the above comment).

    Scary scary scary. PM me with your real life name and client name.

  • (disco) in reply to Nagesh
    Nagesh:
    Scary scary scary. PM me with your real life name and client name.

    There should be only one San Diego company that would outsource its SFDC work.

  • Steve (unregistered)

    "The only practical application of ternary operator is to either intentionally obfuscate your code or use it as a soapbox to brag about how "l33t" you are."

    This could be said of pretty much any element of any programming language, if you don't ever use that element. While I agree that this particular instance is hard to read, it doesn't invalidate the code itself. Besides, I fail to see how this is any better:

    if (FailSafe == 0) {
    	return 'No technical alarms';
    } elsif ((FailSafe & 1) != 0 && (FailSafe & 2) != 0 && (FailSafe & 4) != 0 && (FailSafe & 8) != 0) {
    	return 'Detection zones staying in a given state; Bad visibility; Initialization; Bad configuration';
    } elsif ((FailSafe & 1) != 0 && (FailSafe & 2) != 0 && (FailSafe & 4) != 0) {
    	return 'Detection zones staying in a given state; Bad visibility; Initialization';
    } elsif ((FailSafe & 1) != 0 && (FailSafe & 2) != 0 && (FailSafe & 8) != 0) {
    	return 'Detection zones staying in a given state; Bad visibility; Bad configuration';
    } elsif ((FailSafe & 1) != 0 && (FailSafe & 4) != 0 && (FailSafe & 8) != 0) {
    	return 'Detection zones staying in a given state; Initialization; Bad configuration';
    } elsif ((FailSafe & 2) != 0 && (FailSafe & 4) != 0 && (FailSafe & 8) != 0) {
    	return 'Bad visibility; Initialization; Bad configuration';
    } elsif ((FailSafe & 1) != 0 && (FailSafe & 2) != 0) {
    	return 'Detection zones staying in a given state; Bad visibility';
    } elsif ((FailSafe & 1) != 0 && (FailSafe&4) != 0) {
    	return {'Detection zones staying in a given state; Initialization';
    } elsif ((FailSafe & 1) != 0 && (FailSafe & 8) != 0) {
    	return { 'Detection zones staying in a given state; Bad configuration';
    } elsif ((FailSafe & 2) != 0 && (FailSafe & 4) !=0) {
    	return 'Bad visibility; Initialization';
    } elsif ((FailSafe & 2) != 0 && (FailSafe & 8) != 0) {
    	return 'Bad visibility; Bad configuration';
    } elsif ((FailSafe & 4) != 0 && (FailSafe & 8) != 0) {
    	return 'Initialization; Bad configuration';
    } elsif ((FailSafe & 1) != 0) {
    	return 'Detection zones staying in a given state';
    } elsif ((FailSafe & 2) != 0) {
    	return 'Bad visibility';
    } elsif ((FailSafe & 4) != 0) {
    	return 'Initialization';
    } elsif ((FailSafe & 8) != 0) {
    	return 'Bad configuration';
    } else {
    	return 'Unknown';
    }
  • (disco)

    There are several places that need ternaries where a plain old if won't do; constexpr functions and member initialisers come to mind. One of the most esoteric uses I heard of though was in macro programming where you wrote f(true ? any_type() : ARG) which resulted in templating f over the type of ARG without actually evaluating ARG. (Nowadays you probably just write f<decltype(ARG)>() instead.)

    If I really wanted to use ternary operators, rather than the neat array that @Zecc used, I would write it something like this:

    FailSafe & 8 ?
      FailSafe & 4 ?
         FailSafe & 2 ?
            FailSafe & 1 ?
              'Detection zones staying in a given state; Bad visibility; Initialization; Bad configuration' :
              'Bad visibility; Initialization; Bad configuration' :
            FailSafe & 1 ?
              'Detection zones staying in a given state; Initialization; Bad configuration' :
              'Initialization; Bad configuration' :
         FailSafe & 2 ?
            FailSafe & 1 ?
              'Detection zones staying in a given state; Bad visibility; Bad configuration' :
              'Bad visibility; Bad configuration' :
            FailSafe & 1 ?
              'Detection zones staying in a given state; Bad configuration' :
              'Bad configuration' ?
      FailSafe & 4 ?
         FailSafe & 2 ?
            FailSafe & 1 ?
              'Detection zones staying in a given state; Bad visibility; Initialization' :
              'Bad visibility; Initialization' :
            FailSafe & 1 ?
              'Detection zones staying in a given state; Initialization' :
              'Initialization' :
         FailSafe & 2 ?
            FailSafe & 1 ?
              'Detection zones staying in a given state; Bad visibility' :
              'Bad visibility' :
            FailSafe & 1 ?
              'Detection zones staying in a given state' :
              'No technical alarms'
    
  • (disco) in reply to urkerab

    Um, ? is right associative.

  • (disco) in reply to Captain

    Works for me in both JS and C (after replacing the quotes).

  • (disco) in reply to Zecc

    Yes, it would "work". But it's utterly unreadable. It effectively treats the operator as left associative. In that case, you might as well collapse it to:

    if (FailSafe & 8) { (errors.append "error 8"); }
    if (FailSafe & 4) { (errors.append "error 4"); }
    if (FailSafe & 2) { (errors.append "error 2"); }
    if (FailSafe & 1) { (errors.append "error 1"); }
    

    and use some sensible data structures.

  • (disco) in reply to Captain

    http://what.thedailywtf.com/badges/128/someone-didn-t-get-the-joke

  • (disco) in reply to ben_lubar

    Oh, alright then...

  • (disco) in reply to ben_lubar

    Who among us has not deserved this at some time?

  • (disco) in reply to boomzilla
    boomzilla:
    Who among us has not deserved this at some time?

    Given the likes of @Nagesh and @SpectateSwamp on this forum, perhaps we all do.

    Me, I'm still waiting for mine.

  • (disco) in reply to Maciejasjmj
    Maciejasjmj:
    Me, I'm still waiting for mine.

    I'm waiting for feedback from upstream.

  • (disco) in reply to Maciejasjmj
    Maciejasjmj:
    Me, I'm still waiting for mine.

    Damn you... I never got one, I assume because it was too easy for @PJH to fix the CSS, making it a weak Dicsourse configuration flaw.

  • (disco) in reply to darkmatter

    Speaking of Discourse...

    https://meta.discourse.org/t/invisible-topic-is-not-invisible/17603

    Find one bug, get one free!

  • (disco) in reply to darkmatter
    darkmatter:
    Damn you... I never got one, I assume because it was too easy for @PJH to fix the CSS, making it a weak Dicsourse configuration flaw.

    I do get distracted occasionally...

  • (disco) in reply to PJH
    PJH:
    I do get distracted occasionally...
    oo badger badger... Thanks for validating my existence!
  • (disco) in reply to PJH

    My proudest TDWTF moment.

  • (disco)

    Which is easier to read?:

    my $salute;
    if ($name eq $EMPTY_STR) {
        $salute = 'Dear Customer';
    }
    elsif ($name =~ m/\A ((?:Sir|Dame) \s+ \S+)/xms) {
        $salute = "Dear $1";
    }
    
    elsif ($name =~ m/([^\n]*), \s+ Ph[.]?D \z/xms) {
        $sa1ute = "Dear Dr $1";
    }
    else {
        $salute = "Dear $name";
    }
    

    Versus a "tabular ternary" (note the comments):

    
               # Name format...                            # Salutation...
    my $salute = $name eq $EMPTY_STR                       ? 'Dear Customer'
               : $name =~ m/ \A((?:Sir|Dame) \s+ \S+) /xms ? "Dear $1"
               : $name =~ m/ (.*), \s+ Ph[.]?D \z     /xms ? "Dear Dr $1"
               :                                             "Dear $name"
               ;
    

    Just another example of how people can't write legible or maintainable code.

  • (disco) in reply to M_Adams

    Don't get started on British PHP:

    perchance (£name is equal to £EMPTY_STR) {
        £salute = 'Dear Customer';
    } otherwise, perchance (perl_regular_expression_match(..toolazy.., £matches) {
        £salute = 'Dear ' . £matches[1];
    }
    
  • (disco) in reply to M_Adams

    Just realized I bufu'd the "Dear Dr" regex on the rewrite to the tabular version:

                      : $name =~ m/ (.*), \s+ Ph[.]?D \z /xms ? "Dear Dr $1"
    Should be:
                      : $name =~ m/ ([^\n]*), \s+ Ph[.]?D \z /xms ? "Dear Dr $1"

    the (.*) under /s grabs newlines where the ([^\n]*) grabs anything but newlines...

    Moral : Definitely require code reviews after refactoring!

  • (disco) in reply to M_Adams

    How many strokes is that in golf exactly?

  • (disco) in reply to Arantor

    Weeell... removing extraneous (auto-format-able type) white space: 262→215 = -47 :)

  • (disco) in reply to M_Adams
    M_Adams:
    ```perl $sa1ute```
    Nice try.

    Filed under: broken quote

  • (disco) in reply to Zecc

    Ding Ding Ding! We have a winner on the "Easter Egg" hunt :)

  • (disco) in reply to Captain

    Yes, I was assuming a sane language. I suppose in PHP I would have had to wrap everything in parentheses making it as ugly as the original article.

Leave a comment on “One Bad Ternary Operator Deserves Another”

Log In or post as a guest

Replying to comment #:

« Return to Article