• aliceif (disco)
    tdwtf.postComment(post_is_frist_post == true ? "frist!" : post_is_not_sceond_post ? post_is_thrid_post ? "thrid!" : /*Todo: Add good comment text*/ "forth?" : "sceond!");
    
  • VinDuv (disco)

    This developer needs to learn about local variables... Code like is is probably why some code quality checkers, like the one I’m using at work, completely forbid the ternary operator. And that’s too bad because in some cases a ternary operator can actually improve code legibility.

  • Hannes (unregistered)

    bool? frist = ( postcount > 0 ? false : postcount.HasValue ? false : null );

  • drbeat (unregistered)

    Equivalent:

    string title = string.Format("{0:dd/MM/yyyy} to ", payRecord.DateStarted);
    title += payRecord.DateLeft == null ? "Present" : string.Format("{1:dd/MM/yyyy}", payRecord.DateLeft);
    title += string.Format(" : {0} ({1})", payRecord.Department.PayrollCompany.CompanyName, payRecord.PayFrequency));
    if (includePayrollIDinResult) {
        title += "|" +payRecord.Department.PayrollCompanyID;
    }
    payRecordsList.Add(title, payRecord.ID);
  • [Put Name Here] (unregistered) in reply to drbeat
    drbeat:
    Equivalent:
    string title = string.Format("{0:dd/MM/yyyy} to ", payRecord.DateStarted);
    title += payRecord.DateLeft == null ? "Present" : string.Format("{1:dd/MM/yyyy}", payRecord.DateLeft);
    title += string.Format(" : {0} ({1})", payRecord.Department.PayrollCompany.CompanyName, payRecord.PayFrequency));
    if (includePayrollIDinResult) {
        title += "|" +payRecord.Department.PayrollCompanyID;
    }
    payRecordsList.Add(title, payRecord.ID);

    Or:

    string to = payRecord.DateLeft == null ? "Present" : string.Format("{1:dd/MM/yyyy}", payRecord.DateLeft);
    string title = string.Format("{0:dd/MM/yyyy} to {1} : {2} ({3})", payRecord.DateStarted, to, 
    payRecord.Department.PayrollCompany.CompanyName, payRecord.PayFrequency));
    if (includePayrollIDinResult) {
        title += "|" +payRecord.Department.PayrollCompanyID;
    }
    payRecordsList.Add(title, payRecord.ID);
    
  • Jeddix (disco)

    That's actually not THAT bad if you intend it right.

    (Done via Resharper because I'm too lazy after my break)

    payRecordsList.Add(
      payRecord.DateLeft == null
        ? includePayrollIDinResult == false
            ? string.Format(
              "{0:dd/MM/yyyy} to Present : {1} ({2})",
              payRecord.DateStarted,
              payRecord.Department.PayrollCompany.CompanyName,
              payRecord.PayFrequency)
            : string.Format(
              "{0:dd/MM/yyyy} to Present : {1} ({2})",
              payRecord.DateStarted,
              payRecord.Department.PayrollCompany.CompanyName,
              payRecord.PayFrequency) + "|" + payRecord.Department.PayrollCompanyID
        : includePayrollIDinResult == false
            ? string.Format(
              "{0:dd/MM/yyyy} to {1:dd/MM/yyyy} : {2} ({3})",
              payRecord.DateStarted,
              payRecord.DateLeft,
              payRecord.Department.PayrollCompany.CompanyName,
              payRecord.PayFrequency)
            : string.Format(
              "{0:dd/MM/yyyy} to {1:dd/MM/yyyy} : {2} ({3})",
              payRecord.DateStarted,
              payRecord.DateLeft,
              payRecord.Department.PayrollCompany.CompanyName,
              payRecord.PayFrequency) + "|" + payRecord.Department.PayrollCompanyID,
      payRecord.ID);
    

    But I wouldn't do this in real code.

  • aliceif (disco) in reply to Jeddix

    It's not really the Ternary Operator, but rather the fact that some idiot uses String.Format inside a function call that makes this a WTF. Although, the whole includePayrollIDinResult thing could be made better by using the Ternary Operator less stupidly: you could use it to switch the suffix itself on and off, instead of duplicating the entire goddamn thing.

  • Eldelshell (disco) in reply to Jeddix

    That is so functional.

  • aliceif (disco) in reply to aliceif

    A little less braindead edition:

    payRecordsList.Add(
      payRecord.DateLeft == null
        ? string.Format(
          "{0:dd/MM/yyyy} to Present : {1} ({2})",
          payRecord.DateStarted,
          payRecord.Department.PayrollCompany.CompanyName,
          payRecord.PayFrequency) +
          includePayrollIDinResult == false ? "" : "|" + payRecord.Department.PayrollCompanyID
        : string.Format(
          "{0:dd/MM/yyyy} to {1:dd/MM/yyyy} : {2} ({3})",
          payRecord.DateStarted,
          payRecord.DateLeft,
          payRecord.Department.PayrollCompany.CompanyName,
          payRecord.PayFrequency) +
          includePayrollIDinResult == false ? "" : "|" + payRecord.Department.PayrollCompanyID,
      payRecord.ID);
    
  • aliceif (disco)

    WTF am I even doing. TRRWTF is using == false.

  • Someone_Else (disco) in reply to aliceif

    Since 99% of the String.Format is the same, couldn't you un-stupify that even more?

    payRecordsList.Add(
        string.Format(
            "{0:dd/MM/yyyy} to {1} : {2} ({3})",
            payRecord.DateStarted,
            payRecord.DateLeft == null ? "Present" : payRecord.DateLeft.ToString("dd/MM/yyyy"),
            payRecord.Department.PayrollCompany.CompanyName,
            payRecord.PayFrequency) +
            !includePayrollIDinResult ? "" : "|" + payRecord.Department.PayrollCompanyID,
        payRecord.ID);
    
  • aliceif (disco) in reply to Someone_Else

    Nice! That looks a lot less awful, with only two little changes. And only one ternary operator less than what we had in the beginning! I was too lazy to go all the way, so I guess this one's for you: + :cookie:

  • BdotC (disco) in reply to Someone_Else

    This could be a method on the PayRecord class, so you could do:

    payRecordsList.Add(payRecord.ToString(includePayrollIDinResult), payRecord.ID);
    

    The method itself could be:

    public string ToString(bool includePayrollIDinResult)
    {
      return string.Format(
            "{0:dd/MM/yyyy} to {1} : {2} ({3}){4}",
            DateStarted,
            DateLeft == null ? "Present" : DateLeft.ToString("dd/MM/yyyy"),
            Department.PayrollCompany.CompanyName,
            PayFrequency,
    	includePayrollIDinResult ? "|" + payRecord.Department.PayrollCompanyID : "");
    }
    
  • cliffc (disco)
    spelling = (rand()<0.5 ? "ternary" : rand()<0.5 ? "terinary" : "terninary");
    
  • Dogsworth (disco)
    Mark Bowytz:
    terinary
    Mark Bowytz:
    terninary
    Mark Bowytz:
    ternary

    Third time's a charm, I guess.

  • VinDuv (disco) in reply to Dogsworth
    Dogsworth:
    Third time

    Well, it’s not called “ternary” for nothing, after all...

  • Steve_The_Cynic (disco)
    nested within the call to "payRecordsList.Add", almost every parameter passed has its own ternary operator added.
    Sadly, no. payRecordsList.Add() has only one parameter(1), so the single argument(1) is a huge compound ternary-of-ternaries. None of the non-format-string arguments to string.Format() are ternaries themselves (but probably should be).

    (1) These might not be the correct terminology for C# (string with small S(2), so it's C# if I have this right), and I can't be bothered to look it up, but the distinction is useful. In the land of C, "parameter" corresponds to the Pascal term "formal parameter" - the doodad in the function prototype - while "argument" corresponds to the Pascal term "actual parameter" - the thing passed in during a function call.

    (2) Yes, a small S. Terminology chosen to derail the reader's brain a bit, like writing the word 'red' in blue and then asking the reader to tell you what colour the word is...

    EDIT: Fixed up the bogus markup interpretation that this stupid wanked fucked-up forum software insists on applying to asterisks. No. I don't like it.

  • Paul Neumann (unregistered)

    bah

    payRecordsList.AddRange(payRecords.Select(record => record.ToString(includePayrollIDinResult)));
    
    ...
    
    public static class PayRecordExtensions {
      public static string ToString(this PayRecord payRecord, bool IncludePayrollIDInResult) {
        return string.Format("{0:dd/MM/yyyy} to {1} : {2} ({3}){4}",
                              payRecord.DateStarted,
                              payRecord.DateLeft.HasValue ? payRecord.DateLeft.ToString("dd/MM/yyyy") : "Present",
                              payRecord.Department.PayrollCompany.CompanyName,
                              payRecord.PayFrequency,
                              IncludePayrollIDInResult ? "|" + payRecord.Department.PayrollCompanyID : string.Empty);
      }
    }
  • CoyneTheDup (disco)

    "Maintainable? Our programs are perfect and never need to be maintained."

    The worst WTF is that the the first part of each ternary result is constant, and could have been broken out to a predecessor string. But I guess temporary strings are harmful or something.

  • devmonkey (disco) in reply to Jeddix

    No, totally disagree. it is still very bad - even with formatting.

    1. Readability: you cannot easily tell what the parameters of the Add method are
    2. Debugging: it is not possible to check when debugging what the values were computed to, unless you step into the Add method as well

    I would cite this as a code smell and require it was refactored.

  • cartman82 (disco)

    When you indent things correctly, ternary is actually perfectly legible.

    Example: what does this mean?

    var x = settings ? settings.widgets ? settings.widgets.name: settings.name: GLOBAL["widgets"] ? GLOBAL["widgets"].name: DEFAULT_WIDGETS_NAME;
    

    Who knows, right?

    How about now?

    var x = settings
    	? settings.widgets
    		? settings.widgets.name
    		: settings.name
    	: GLOBAL["widgets"]
    		? GLOBAL["widgets"].name
    		: DEFAULT_WIDGETS_NAME;
    

    Ahh, it's getting a setting value from multiple possible locations. Got it.

    I don't think you could make it clearer with ifs.

  • aliceif (disco) in reply to cartman82
    Comment held for moderation.
  • LorenPechtel (disco) in reply to Someone_Else

    Yup, the real problem here was common subexpressions, not the ternary operator. I consider duplicated code to be the worst enemy of clarity.

  • cellocgw (disco) in reply to Dogsworth

    And here I was, thinking a "terninary operator" was something to use on migratory shorebirds who nest in dunes like on Plum Island, MA!

  • DrPepper (disco)

    What gets pushed onto the list is a string.

    We all know how to do this -- there is a payRecord object. I'd create a collection of subclasses of payRecord; one for a person who is still employed (payRecords.DateLeft); then create a ToString() method on each. ToString would take a parameter (includePayrollIdInResult); internally ToString() would call one of two methods to generate the actual string.

    Basically, the idea is -- ask the object for a string representation of itself, and push that onto the list. Clean, self-contained, and testable methods on the object.

  • chubertdev (disco)

    It's a ternary operator article, let me show you how it's done!

  • blakeyrat (disco) in reply to VinDuv
    Comment held for moderation.
  • Zylon (disco)

    Dear Mr. Bowytz,

    Your opinion on this matter might carry a smidge more weight if you were capable of spelling ternary correctly more than 1/3 of the time.

  • David_C (disco) in reply to cartman82

    True. But you must make sure your indentation is correct. Auto-indent tools (possibly just pressing <TAB> a lot in emacs) are important. If you mis-indent expressions like that, then most readers will trust the indentation for the semantic hints and guess wrong about what the code does.

  • aliceif (disco) in reply to David_C

    But every "proper programmer" according to popular opinion uses a proper IDE anyways, which makes identing as easy as Ctrlk,Ctrld! Or CtrlShiftf or whatever else there is ...

  • chubertdev (disco) in reply to aliceif

    $formattingKeystrokes

  • Arantor (disco) in reply to aliceif

    CtrlK, CtrlD in Notepad++ makes the entire thing you've selected a block, and then duplicates it.

    It's... interesting to watch what happens.

  • Boris Kenchovik (unregistered)

    The programmer who wrote that would've been absolutely at home with Lisp. One languages's WTFs are another languages' modus operandi.

  • cbretana (disco)

    Altough any code looks horrible when NO formatting is applied, this is actually pretty good (although it could be improved a bit) if it was formatted appropriately:

    payRecordsList.Add(
         payRecord.DateLeft == null ? 
            includePayrollIDinResult == false ? 
            	string.Format("{0:dd/MM/yyyy} to Present : {1} ({2})", 
            		payRecord.DateStarted,
                            payRecord.Department.PayrollCompany.CompanyName, payRecord.PayFrequency) : 
            	string.Format("{0:dd/MM/yyyy} to Present : {1} ({2})", 
            		payRecord.DateStarted, payRecord.Department.PayrollCompany.CompanyName, 
                            payRecord.PayFrequency) + "|" + payRecord.Department.PayrollCompanyID : 
            includePayrollIDinResult == false ? 
            	string.Format("{0:dd/MM/yyyy} to {1:dd/MM/yyyy} : {2} ({3})", 
            		payRecord.DateStarted, payRecord.DateLeft, 
                            payRecord.Department.PayrollCompany.CompanyName, payRecord.PayFrequency) : 
            	string.Format("{0:dd/MM/yyyy} to {1:dd/MM/yyyy} : {2} ({3})", 
            		payRecord.DateStarted, payRecord.DateLeft, 
                            payRecord.Department.PayrollCompany.CompanyName, payRecord.PayFrequency) + "|" + 
            	        payRecord.Department.PayrollCompanyID, payRecord.ID
            	);
    

    much better however, would be:

    payRecordsList.Add(
         string.Format("{0:dd/MM/yyyy} to {1:dd/MM/yyyy} : {2} ({3}){4}".
              payRecord.DateStarted, 
              payRecord.DateLeft == null? "Present": payRecord.DateLeft,
              payRecord.Department.PayrollCompany.CompanyName, 
              payRecord.PayFrequency,
              includePayrollIDinResult ? "|" + payRecord.Department.PayrollCompanyID, 
         payRecord.ID)
    
  • Watson (disco)

    Of course, a better name for it would be "conditional operator" anyway. All "ternary" does is say that it takes three operands; nothing about what it does with them.

  • trithne (disco) in reply to Watson

    Old VB called it "Inline If", which I found pretty self-explanatory.

  • Nagesh (cs) in reply to Hannes
    Hannes:
    bool? frist = ( postcount > 0 ? false : postcount.HasValue ? false : null );

    This is impact of using too much Resharper tool

  • eViLegion (disco)

    Do you all mean "the conditional operator"?

  • nmclean (disco) in reply to Steve_The_Cynic

    If we're being technical about the definitions, then the "huge compound ternary-of-ternaries" isn't an argument either. The function declaration variable is the parameter, the ternary-mess is an expression, and the resulting string object is the argument.

  • Steve_The_Cynic (disco) in reply to nmclean
    nmclean:
    If we're being technical about the definitions, then the "huge compound ternary-of-ternaries" isn't an argument either. The function declaration variable is the parameter, the ternary-mess is an *expression*, and the resulting string object is the argument.
    Yes, indeed, and well done for out-pedanting me!
  • HardwareGeek (disco) in reply to Steve_The_Cynic
    Steve_The_Cynic:
    well done for out-pedanting me!

    Nominated for pendantry badgification.

  • FrostCat (disco) in reply to HardwareGeek
    HardwareGeek:
    pendantry

    Hee hee hee

  • Hannes (unregistered) in reply to Nagesh
    Nagesh:
    Hannes:
    bool? frist = ( postcount > 0 ? false : postcount.HasValue ? false : null );

    This is impact of using too much Resharper tool

    In fact, I haven't really used Resharper so far. Only had a quick look at it.

    But I was amused (more like "shocked") when I found out you could use a nullable bool in C#. And worst of all: "File not found!" isn't a valid state for a nullable bool! :(

  • X (unregistered)

    Terinary? Terninary? If you are going to make fun of people using ternary operators, you should at least know how to spell it.

  • urkerab (disco) in reply to cbretana
    cbretana:
    much better however, would be:

    payRecordsList.Add( string.Format("{0:dd/MM/yyyy} to {1:dd/MM/yyyy} : {2} ({3}){4}". payRecord.DateStarted, payRecord.DateLeft == null? "Present": payRecord.DateLeft, payRecord.Department.PayrollCompany.CompanyName, payRecord.PayFrequency, includePayrollIDinResult ? "|" + payRecord.Department.PayrollCompanyID, payRecord.ID)

    How do you format "Present" with a dd/MM/yyyy format? I'd try this:

    payRecordsList.Add(
         string.Format(payRecord.DateLeft == null ?
                  "{0:dd/MM/yyyy} to Present : {2} ({3}){4}" :
                  "{0:dd/MM/yyyy} to {1:dd/MM/yyyy} : {2} ({3}){4}",
              payRecord.DateStarted, 
              payRecord.DateLeft,
              payRecord.Department.PayrollCompany.CompanyName, 
              payRecord.PayFrequency,
              includePayrollIDinResult ? "|" + payRecord.Department.PayrollCompanyID : "",
         payRecord.ID)
    
  • mark_bowytz (disco) in reply to Zylon
    Comment held for moderation.
  • FrostCat (disco) in reply to mark_bowytz

    At least he gets it right one triceth of the time.

Leave a comment on “Ternary Operator Nesting Syndrome”

Log In or post as a guest

Replying to comment #:

« Return to Article