Stringing a Replacement

« Return to Article
  • Dogsworth 2013-07-11 06:48
    This looks oddly familiar. We have a class by the same name that also reinvents the wheel.
  • QJo 2013-07-11 06:49
    I used to maintain a codebase wherein we had a "StringUtils" class, but this was mainly to allow us to conveniently catch null strings. Also, the string manipulation routines in java 1.3 was limited compared to more recent versions. Hence it was necessary.

    Note the "toRepalce" in the codebase. Dyseliaxa needs to be rmevoeed from all cdboeases.
  • ubersoldat 2013-07-11 06:54
    Well, I guess Freemarker, MVEP or Velocity were very hard to understand for this so called architect.
  • RFoxMich 2013-07-11 07:10
    Re the comment in the source...1.
  • Lothar 2013-07-11 07:19
    String.replaceAll expects a regular expression, so the given helper method is not a real reinvention of the wheel.
  • eViLegion 2013-07-11 07:26
    Repalce.

    Also... who the hell uses the indefinite article at the start of variable/parameter names? Baffling.
  • Robyrt 2013-07-11 07:30
    So replaceAll("","","Bob") returns "Bob"? That's pretty Zen.
  • Erik 2013-07-11 07:33
    String.replaceAll do expect a regexp, and as such is the wrong function for when you are replacing literal substrings.
    The function you want is String.replace.
  • Strolskon 2013-07-11 07:42
    So what's the recommended way to do this?

    String.replaceAll wants a regex => does not fit

    String.replace only replaces the first => does not fit

    Calling replace multiple times? Would replace the searched string in the replacement string => does not work

  • pjt33 2013-07-11 07:52
    Strolskon:
    String.replace only replaces the first => does not fit

    That's not what the API doc says.
  • Remy Porter 2013-07-11 07:57
    String.replace replaces all instances of a Char or CharSequence (Strings implement CharSequence). String.replaceFirst replaces only the first instance.
  • Mikael 2013-07-11 07:58
    So what's the recommended way to do this?

    Pattern.compile(regex, LITERAL).matcher(str).replaceAll(repl)
  • Anon 2013-07-11 08:04
    The recommended way to replace all instance of a literal substring with a different literal substring is:

    targetString.replace(toReplace, replacemnt);

    No patterns/matchers/regex involved.
  • EvilSnack 2013-07-11 08:12
    Just to get the obligatory posts out of the way:

    1. TRWTF is Java.

    2. I'm Philip.

    3. I'm Philip, and so's my wife!

    Captcha letatio: "The mayor has denied rumors that he received letatio from his secretary."
  • Mikael 2013-07-11 08:20
    Anon:
    The recommended way to replace all instance of a literal substring with a different literal substring is:

    targetString.replace(toReplace, replacemnt);

    No patterns/matchers/regex involved.



    public String replace(CharSequence target, CharSequence replacement) {
    return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
    this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
    }


    http://hg.openjdk.java.net/jdk7u/jdk7u40/jdk/file/ed809dc4f278/src/share/classes/java/lang/String.java row 2179
  • zennnnnn 2013-07-11 08:29
    Robyrt:
    So replaceAll("","","Bob") returns "Bob"? That's pretty Zen.


    Zen would be replaceAll("abc", "", "Bo" returns "BoaBobBocBo"
  • Pock Suppet 2013-07-11 09:11
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!

    A Yoda-style
    = null anOldString =
    would be perfectly acceptable, however.
  • Chaarmann 2013-07-11 09:14
    I can't see a WTF here.
    The replace method could be written with less code lines and not allow empty string argument, but it seems to work fine.

    Sometimes you must use old java versions like JDK1.3, especially if you are programming for embedded systems where you are limited in memory, which means: You cannot upgrade to a newer Java version, and you can add a method, but not include an additional library like the jakarta-commons-*.jar!

    In JDK1.3 there is only a single replace-method available:
    replace(char oldChar, char newChar)
  • foo 2013-07-11 09:31
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!

    A Yoda-style
    = null anOldString =
    would be perfectly acceptable, however.


    return null; unless (null != aReceiver);

  • Andrew 2013-07-11 09:49
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug, but
    null = aReceiver
    is a compiler error. Grammatical word order be damned.
  • foo 2013-07-11 09:52
    Andrew:
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug
    Which modern compiler doesn't warn about this (when used in a conditional).
  • JC 2013-07-11 09:58
    Andrew:
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug, but
    null = aReceiver
    is a compiler error. Grammatical word order be damned.


    I don't know about Java, but in C#
    if (aReceiver = null)
    {
    stuff
    }

    would be a compiler error as the expression doesn't result in a boolean.
  • EuroGuy 2013-07-11 10:00
    Andrew:
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug, but
    null = aReceiver
    is a compiler error. Grammatical word order be damned.

    Any programmer who is pedentic enough to use the Yoda style, is probably also professional enough not to confuse = and ==.

    So the people who use "normal" style are the suspicious ones. However, the Yoda programmers are unsufferable know-it-alls. I prefer the former types as my coworkers.
  • eViLegion 2013-07-11 10:03
    Andrew:
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug, but
    null = aReceiver
    is a compiler error. Grammatical word order be damned.


    Much nicer in C++:


    SomeStringClassThing* aReciever;
    if (!aReciever || (!anOldString || !aNewString))
    {
    return aReceiver;
    }


    No bugs or compiler errors.
  • WernerCD 2013-07-11 10:04
    Unicorns and Rainbows! Who cares about anything else? Quick... someone call the BATFE!

    Edit: Clicking [Expand Full Text] then clicking on "orientation" works in the comments section as well... didn't expect that... Trippy...
  • Tasty 2013-07-11 11:04
    foo:
    Andrew:
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug
    Which modern compiler doesn't warn about this (when used in a conditional).


    Which modern compiler doesn't warn about 1,000 things at a time? Why search for a needle in a haystack when you can just find the real errors?
  • Tasty 2013-07-11 11:07
    EuroGuy:
    Andrew:
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug, but
    null = aReceiver
    is a compiler error. Grammatical word order be damned.

    Any programmer who is pedentic enough to use the Yoda style, is probably also professional enough not to confuse = and ==.

    So the people who use "normal" style are the suspicious ones. However, the Yoda programmers are unsufferable know-it-alls. I prefer the former types as my coworkers.


    Yoda followed Altaic grammar, topic-comment-verb, not object-verb-subject. It's a hidden refernce to Japanese martial artists. Now, this is being a know-it-all!
  • Bring Back TopCod3r 2013-07-11 11:10
    Tasty:
    foo:
    Andrew:
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug
    Which modern compiler doesn't warn about this (when used in a conditional).


    Which modern compiler doesn't warn about 1,000 things at a time? Why search for a needle in a haystack when you can just find the real errors?


    Nice trolling there.
  • Evan 2013-07-11 11:13
    Erik:
    String.replaceAll do expect a regexp, and as such is the wrong function for when you are replacing literal substrings.
    The function you want is String.replace.

    Remy Porter:
    String.replace replaces all instances of a Char or CharSequence (Strings implement CharSequence). String.replaceFirst replaces only the first instance.

    That is a terrible naming scheme.

    JC:
    I don't know about Java, but in C#
    if (aReceiver = null)
    {
    stuff
    }

    would be a compiler error as the expression doesn't result in a boolean.
    Same in Java, and similar in C and C++ because you're compiling with -Wall and compiling cleanly. Aren't you?

    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    
    ...
    if (a = b) { ... }

    is, without checking, I think legal C# and Java.
  • trtrwtf 2013-07-11 11:25
    EuroGuy:

    Any programmer who is pedentic enough to use the Yoda style, is probably also professional enough not to confuse = and ==.


    And experienced enough to have moderate RSI. Typos do happen, and when your hands hurt, they happen more.

    CAPTCHA: incassum - incassum not here, I'll leave the side door open.
  • C-Derb 2013-07-11 11:41
    Evan:
    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    
    ...
    if (a = b) { ... }

    is, without checking, I think legal C# and Java.
    This ignores the original complaint, which was
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
  • xaade 2013-07-11 11:50
    Evan:

    Remy Porter:
    String.replace replaces all instances of a Char or CharSequence (Strings implement CharSequence). String.replaceFirst replaces only the first instance.

    That is a terrible naming scheme.


    No it's not.

    Having "replace" manage to only replace the first instance is not intuitive at all.

    What if someone asked you to buy a dozen eggs, but replace broken eggs, and you only replaced the first broken egg?

    replace"All" should be implied.

    replace"First/Last/Count" should be a specification.
  • Matt Westwood 2013-07-11 11:53
    C-Derb:
    Evan:
    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    
    ...
    if (a = b) { ... }

    is, without checking, I think legal C# and Java.
    This ignores the original complaint, which was
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?


    In Java, doing something like:

    if ("TestString".equals(variable)) {
    :
    :
    etc.

    saves on having to test whether variable is null. Do it the other way round and you have to try-catch NullPointerExceptions.
  • Jeremy 2013-07-11 11:53
    xaade:
    Evan:

    Remy Porter:
    String.replace replaces all instances of a Char or CharSequence (Strings implement CharSequence). String.replaceFirst replaces only the first instance.

    That is a terrible naming scheme.


    No it's not.

    Having "replace" manage to only replace the first instance is not intuitive at all.

    What if someone asked you to buy a dozen eggs, but replace broken eggs, and you only replaced the first broken egg?

    replace"All" should be implied.

    replace"First/Last/Count" should be a specification.


    Absolutely.
  • xaade 2013-07-11 11:53
    C-Derb:
    Evan:
    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    
    ...
    if (a = b) { ... }

    is, without checking, I think legal C# and Java.
    This ignores the original complaint, which was
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?


    Not really.

    Using a compiler that only accepts boolean values for the result of an if statement is the best option.

    Continuing to place the constant on the left in such a language is TRWTF.
  • Matt Westwood 2013-07-11 11:54
    Tasty:
    foo:
    Andrew:
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!
    No, we can't stop doing this. There is less room for sneaky failures, because leaving out an = means
    aReceiver = null
    might be a bug
    Which modern compiler doesn't warn about this (when used in a conditional).


    Which modern compiler doesn't warn about 1,000 things at a time? Why search for a needle in a haystack when you can just find the real errors?


    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.
  • xaade 2013-07-11 11:55
    Matt Westwood:
    C-Derb:
    Evan:
    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    
    ...
    if (a = b) { ... }

    is, without checking, I think legal C# and Java.
    This ignores the original complaint, which was
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?


    In Java, doing something like:

    if ("TestString".equals(variable)) {
    :
    :
    etc.

    saves on having to test whether variable is null. Do it the other way round and you have to try-catch NullPointerExceptions.


    Or you could do what I did and make an extension method on object that checks for null.

    Then you just have variable.EqualsNullSafe("TestString"). And if variable is null it returns false.
  • eViLegion 2013-07-11 12:00
    Matt Westwood:
    Tasty:
    Which modern compiler doesn't warn about 1,000 things at a time? Why search for a needle in a haystack when you can just find the real errors?


    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.


    Beware the Ides of March.
  • Paul Neumann 2013-07-11 12:00
    String aReceiver, toReplace, replaceWith;
    

    aReceiver = "Useful text. /*Remove me*/ More usefulText.";
    toReplace = "/*Remove me*/ ";
    replaceWith = null;

    String result = FunctionLibrary.replaceAll(aReceiver, toReplace, replaceWith);
    Assert.equal(null, result);
  • gnasher729 2013-07-11 12:03
    eViLegion:
    [Much nicer in C++:


    SomeStringClassThing* aReciever;
    if (!aReciever || (!anOldString || !aNewString))
    {
    return aReceiver;
    }


    No bugs or compiler errors.


    I once lost a week of my life because someone who was assumed to be very clever replaced

    if (ptr != NULL)

    with

    if (! ptr)

    without checking the code, without doing a code review, in a place where it caused the maximum possible damage. The reason for the change was that he felt the second way looked more clever. I could have killed him. I should have killed him. Note that unlike the "=" vs. "==" confusion, the compiler has absolutely no chance to give a warning, just like it can't give a warning if you write "ptr == NULL" instead of "ptr != NULL".
  • gnasher729 2013-07-11 12:08
    Tasty:
    Which modern compiler doesn't warn about 1,000 things at a time? Why search for a needle in a haystack when you can just find the real errors?


    Mine doesn't. Because I've turned on the "warning = errors" settings, so any warning gets fixed immediately. Actually, I'd estimate that more than half the warnings turn out to be logic errors which would have been much harder to find if I didn't leave it to the compiler.
  • Paul Neumann 2013-07-11 12:21
    C-Derb:
    Evan:
    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    
    ...
    if (a = b) { ... }

    is, without checking, I think legal C# and Java.
    This ignores the original complaint, which was
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    It is exactly as I expect: "Expected == Actual" which is what I think when I am making an assertion.
  • trtrwtf 2013-07-11 12:21
    eViLegion:
    Matt Westwood:
    Tasty:
    Which modern compiler doesn't warn about 1,000 things at a time? Why search for a needle in a haystack when you can just find the real errors?


    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.


    Beware the IDEs of March.


    FTFY
  • NullIsNotAnObjectBro 2013-07-11 12:23
    So you did an extension method on object that checks for null so you can call object methods on null references in Java ?

    And what you was smoking while doing that ? I want some of your good shit.

    It turns null to an object just with a couple of puffs.

    null is not an Object, is just a special kind of weird type who can't be used to declare or cast anything to it, it only can be referenced.

  • _leonardo_ 2013-07-11 12:25
    xaade:
    Matt Westwood:

    In Java, doing something like:
    if ("TestString".equals(variable)) {
    :
    :
    etc.

    saves on having to test whether variable is null. Do it the other way round and you have to try-catch NullPointerExceptions.


    Or you could do what I did and make an extension method on object that checks for null.

    Then you just have variable.EqualsNullSafe("TestString"). And if variable is null it returns false.


    Matt Westwood is right here.
    If you have a constant TEST_VALUE which is statically defined somewhere, you should always do if(TEST_VALUE.equals(input)){}

    If you instead call the equals() method of the input object, you must first check it for non-null like this:
    if(input != null && input.equals(TEST_VALUE)){}

    doing it in the right order saves the null check.
    The guy who talked about overloading object to handle this is a troll who is trying to create Null Pointer Errors (if 'input' is null, it doesn't have that overloaded method anyway, it's NULL!!).
  • SteveThePirate 2013-07-11 12:30
    xaade:
    Matt Westwood:
    C-Derb:
    Evan:
    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    
    ...
    if (a = b) { ... }

    is, without checking, I think legal C# and Java.
    This ignores the original complaint, which was
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?


    In Java, doing something like:

    if ("TestString".equals(variable)) {
    :
    :
    etc.

    saves on having to test whether variable is null. Do it the other way round and you have to try-catch NullPointerExceptions.


    Or you could do what I did and make an extension method on object that checks for null.

    Then you just have variable.EqualsNullSafe("TestString"). And if variable is null it returns false.

    That doesn't make since. If variable is null it is not an object and therefore that method doesn't exist for it.
  • JC 2013-07-11 12:34
    SteveThePirate:

    That doesn't make since. If variable is null it is not an object and therefore that method doesn't exist for it.


    You can do that with extension methods in C# as he says.
    This runs and prints 'Object is null'


    void Main()
    {
    object obj = null;

    if (obj.IsNull())
    {
    Console.WriteLine("Object is null");
    }
    }

    public static class Extensions
    {
    public static bool IsNull(this object o)
    {
    return o == null;
    }
    }
  • C-Derb 2013-07-11 12:40
    JC:
    SteveThePirate:

    That doesn't make since. If variable is null it is not an object and therefore that method doesn't exist for it.


    You can do that with extension methods in C# as he says.
    This runs and prints 'Object is null'


    void Main()
    {
    object obj = null;

    if (obj.IsNull())
    {
    Console.WriteLine("Object is null");
    }
    }

    public static class Extensions
    {
    public static bool IsNull(this object o)
    {
    return o == null;
    }
    }

    Didn't you mean
    return null == o;
    See how stupid that notation is? Even in a debate about the merits of that pattern, it is just simply more natural to write myVar == conditionalValue.

    Debate over.
  • DaveK 2013-07-11 12:44
    Tasty:
    Yoda followed Altaic grammar, topic-comment-verb, not object-verb-subject. It's a hidden refernce to Japanese martial artists. Now, this is being a know-it-all this being a know-it-all is!
    FTFY :)
  • DaveK 2013-07-11 12:50
    C-Derb:
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    People who get thrown by the order of arguments to a commutative operator are TRWTF.

  • chubertdev 2013-07-11 12:53
    TRWTF is C syntax.

    One of the very few things that VB got right is using a single equal sign as the comparison operator.

    Let the compiler figure out if it's a comparison or assignment based on context.
  • chubertdev 2013-07-11 12:57
    Matt Westwood:
    In Java, doing something like:

    if ("TestString".equals(variable)) {
    :
    :
    etc.

    saves on having to test whether variable is null. Do it the other way round and you have to try-catch NullPointerExceptions.



    String.Equals("TestString", variable)


    Also evaluates to false if variable is null.
  • foo 2013-07-11 13:31
    DaveK:
    Tasty:
    Yoda followed Altaic grammar, topic-comment-verb, not object-verb-subject. It's a hidden refernce to Japanese martial artists. Now, this is being a know-it-all this being a know-it-all isthis being a it-all-know is!
    FTFY :)
    FYTF
  • foo 2013-07-11 13:32
    DaveK:
    C-Derb:
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    People who get thrown by the order of arguments to a commutative operator are TRWTF.

    The operator is commutative. Readability not is.
  • foo 2013-07-11 13:44
    C-Derb:
    Evan:
    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    
    ...
    if (a = b) { ... }

    is, without checking, I think legal C# and Java.
    This ignores the original complaint, which was
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    And, unlike the = vs. == mixup, I don't know of any compiler warning for variable == constant comparisons in case they forget it once. So in fact, it's not only making the code less readable, but also less reliable, provided you heed compiler warnings. I think that's the last straw.

    I can only conclude this pattern is for those who (or whose managers)
    - didn't think it through,
    - ignore/disable compiler warnings,
    - tie a knot in their handkerchief in order to remind them to look at the knot in their other handkerchief, and/or
    - desperately need rules to follow, however pointless
  • NullIsNotAnObjectBro 2013-07-11 13:57
    JC:
    SteveThePirate:

    That doesn't make since. If variable is null it is not an object and therefore that method doesn't exist for it.


    You can do that with extension methods in C# as he says.
    [/code]

    The main problem is we were talking about Java, null in Java is not even an Object.
  • Evan 2013-07-11 14:29
    xaade:
    Evan:

    Remy Porter:
    String.replace replaces all instances of a Char or CharSequence (Strings implement CharSequence). String.replaceFirst replaces only the first instance.

    That is a terrible naming scheme.


    No it's not.

    Having "replace" manage to only replace the first instance is not intuitive at all.

    What if someone asked you to buy a dozen eggs, but replace broken eggs, and you only replaced the first broken egg?

    replace"All" should be implied.

    replace"First/Last/Count" should be a specification.
    I don't really care about all/just the first. (I could argue for "just the first" by way of analogy to find(): do you expect s1.find(s2) to return the index of the first match or an array of all of them? But that's me just being devil's advocate. I might like to use replaceFirst and replaceAll for the two string functions.)

    My complaint is how replaceAll is the *regex* version of replace, rather than being replaceRegex or something.

    C-Derb:
    Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    I'm not a fan of const == var and don't use it, but I do disagree here, quite a bit. You can't really fat-finger 3 == x into x == 3, and even if you did it's a lot easier to notice than x = 3 vs x == 3.
  • Smouch 2013-07-11 14:39
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!

    A Yoda-style
    = null anOldString =
    would be perfectly acceptable, however.


    No ! because it's just too easy to assign a null to a variable accidentally with
    if(anOldString=null)...

    Whereas the compiler will scream if you try this
    if(null=anOldString)...

  • herby 2013-07-11 14:48
    Warnings:
    Warning are a fact of life ("Danger Will Robinson"), and when compiling code, having lots of warnings in a compiler all turned on is akin to having another set of eyes looking at the code. Sure you can program with "rules" and many of us do (formatting, etc.) but some are just plain stupid. If you desire to do the:
    if (1 == q)
    
    construct, feel free. Some of us can do it "both ways". There are some silly rules where "higher ups" want to insure that code doesn't have errors, but while they look good, they frustrate some, and often are unneeded. One such example was to do:
    #define EQ ==
    
    so it look nice in if statements. Of course, one could easily circumvent the intent, and use the proper way, but that would be "wrong".

    It is kinda like measuring productivity using lines of code, or paying bounties for bugs found. Many times such efforts (many articles here!) fail when the participants game the system. That is what is happening here.

    Me: Always a good idea to '-Wall' and see how the chips fall! Unfortunately sometimes it goes a bit far (most compilers are pretty good though!). Just look at a step ladder next time you are in a hardware store and marvel at the warning stickers plastered over the thing. You then remember that EACH one of them was the result of a lawsuit, where a lawyer got rich, and the operator was stupid!

    Moral: Don't be stupid!
  • RocketSigns 2013-07-11 14:53
    Just in case the original author of this WTF is reading this: Is this from the code base of model driven framework developed by a small, German company based in Düsseldorf, Berlin and Stuttgart?
    Because I could swear I've seen this code before, just with a ton of other equally weird StringUtil methods.
  • Doug 2013-07-11 15:16
    The last straw for me was realizing it didn't catch the much more common 'if ( var1 = var2 )' situation (assuming var1 is a modifiable lvalue).

    In other words, the yoda conditional claims to fix a problem, but in reality it only catches a small minority. The correct fix is to:

    1) Train your fingers to put =='s in comparisons and train your eyes to find errors
    2) Teach your compiler to find things when you mess up

    (BTW, those two rules apply to 90% of all debates about code style. Usually, the problem isn't code style; the programmer and the compiler need to grow up a bit.)
  • Nick 2013-07-11 15:17
    gnasher729:
    eViLegion:
    [Much nicer in C++:


    SomeStringClassThing* aReciever;
    if (!aReciever || (!anOldString || !aNewString))
    {
    return aReceiver;
    }


    No bugs or compiler errors.


    I once lost a week of my life because someone who was assumed to be very clever replaced

    if (ptr != NULL)

    with

    if (! ptr)

    without checking the code, without doing a code review, in a place where it caused the maximum possible damage. The reason for the change was that he felt the second way looked more clever. I could have killed him. I should have killed him. Note that unlike the "=" vs. "==" confusion, the compiler has absolutely no chance to give a warning, just like it can't give a warning if you write "ptr == NULL" instead of "ptr != NULL".
    I've programmed in C/C++ for so long that "ptr != NULL" or "ptr == NULL" always makes me look twice, because I'm so used to just "if(ptr)", read as "if ptr", or "if(!ptr)", read as "if no(t) ptr". I've never confused those two but the comparison versions remind me of "if(b == true)" and "if(b != false)" with booleans which is basically the equivalent of ==NULL and != NULL respectively --- huh?
  • eViLegion 2013-07-11 16:03
    gnasher729:
    eViLegion:
    [Much nicer in C++:


    SomeStringClassThing* aReciever;
    if (!aReciever || (!anOldString || !aNewString))
    {
    return aReceiver;
    }


    No bugs or compiler errors.


    I once lost a week of my life because someone who was assumed to be very clever replaced

    if (ptr != NULL)

    with

    if (! ptr)

    without checking the code, without doing a code review, in a place where it caused the maximum possible damage. The reason for the change was that he felt the second way looked more clever. I could have killed him. I should have killed him. Note that unlike the "=" vs. "==" confusion, the compiler has absolutely no chance to give a warning, just like it can't give a warning if you write "ptr == NULL" instead of "ptr != NULL".


    OK, yeah, I guess at a glance that !ptr and ptr != NULL look like they might do that same thing, so could cause problems if people have a tendency to compare the pointer to NULL. The thing about re-factoring is you should make sure you actually do it right, and don't completely invert the meaning of things!

    But my point is that by not having any comparison operator at all (eg, either if(ptr){} or if(!ptr){}) then the condition is always clear, and less prone to typos.

    Now of course, you could easily omit the ! by mistake (though no more easily than any other single-character omission), and by doing so completely invert the meaning of the condition, but the simplicity of the syntax is such that you're much more likely to notice and be able to correct it.

    Also, accidentally changing a true to a false (or vice versa) is sort of swapping-like-for-like (at least the type is the same). Therefore it is likely to result in a more natural bug-symptom... e.g. something simply not happening when it should, or happening when it shouldn't.

    Whereas, imagine a conditional which WOULD evaluate to true if without the typo, but which instead mistakenly performs an assignment operation and THEN happens to return true with the typo. This results in a completely unexpected side effect that isn't immediately obvious until later, but possibly doesn't actually manifest itself within the block of code guarded by that erroneous condition. Bad. Bad bad bad bad bad.
  • PRMan 2013-07-11 16:35
    gnasher729:
    eViLegion:
    [Much nicer in C++:


    SomeStringClassThing* aReciever;
    if (!aReciever || (!anOldString || !aNewString))
    {
    return aReceiver;
    }


    No bugs or compiler errors.


    I once lost a week of my life because someone who was assumed to be very clever replaced

    if (ptr != NULL)

    with

    if (! ptr)

    without checking the code, without doing a code review, in a place where it caused the maximum possible damage. The reason for the change was that he felt the second way looked more clever. I could have killed him. I should have killed him. Note that unlike the "=" vs. "==" confusion, the compiler has absolutely no chance to give a warning, just like it can't give a warning if you write "ptr == NULL" instead of "ptr != NULL".


    Yeah, I did something like that once when I was a beginner (haven't we all?). I have now realized that I only clean up files that I am working in for some other reason. Any file I have not opened for what I am working on does not get touched.
  • HardwareGeek 2013-07-11 16:36
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.
    Please apply for a job at my company immediately. We need you. Your profanity-laden rants would fit right in, too.
  • Public Service Announcement 2013-07-11 16:42
    Smouch:
    Pock Suppet:
    if (null == aReceiver) {
    
    return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
    return aReceiver;
    }

    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!

    A Yoda-style
    = null anOldString =
    would be perfectly acceptable, however.


    No ! because it's just too easy to assign a null to a variable accidentally with
    if(anOldString=null)...

    Whereas the compiler will scream if you try this
    if(null=anOldString)...

    Dear comment poster,

    as a courtesy to all readers, before posting a new comment, please read the comments already posted, to avoid making the same points that have already been made and refuted.

    Thank you for your attention.
  • shmosel 2013-07-11 16:43
    TRWTF is using
    if (null == aReceiver)
    instead of
    if (null.equals(aReceiver))
  • foo 2013-07-11 16:57
    eViLegion:
    OK, yeah, I guess at a glance that !ptr and ptr != NULL look like they might do that same thing, so could cause problems if people have a tendency to compare the pointer to NULL. The thing about re-factoring is you should make sure you actually do it right, and don't completely invert the meaning of things!

    The other thing about refactoring is that you should test afterwards (doh), and the other other thing is to do it automated whenever possible. In this case, it can be done with a regex replace (how fitting today), so if you screw it up, you screw it up everywhere and you'll notice really soon, e.g. (assuming your if-statments are on lines by themselves, as regex can't count parentheses):

    s/if \((.*) != NULL\)$/if (\1)/
    s/if \((.*) == NULL\)$/if (!(\1))/


    In fact, I've done regex replacements for cases I knew there were only a handful of places and manual editing would have been faster, just to reduce the chance of subtle errors.

    But my point is that by not having any comparison operator at all (eg, either if(ptr){} or if(!ptr){}) then the condition is always clear, and less prone to typos.
    Full ack, as Nick #412365 put it best.

    Also, accidentally changing a true to a false (or vice versa) is sort of swapping-like-for-like (at least the type is the same). Therefore it is likely to result in a more natural bug-symptom... e.g. something simply not happening when it should, or happening when it shouldn't.

    Whereas, imagine a conditional which WOULD evaluate to true if without the typo, but which instead mistakenly performs an assignment operation and THEN happens to return true with the typo. This results in a completely unexpected side effect that isn't immediately obvious until later, but possibly doesn't actually manifest itself within the block of code guarded by that erroneous condition. Bad. Bad bad bad bad bad.

    For me, it wouldn't mistakenly perform an assignment operation, as compiling with -Wall -Werror it would never get a chance to run, but I assume you're still talking to those ignoring or disabling warnings (who can't be helped anyway IMHO).
  • qbolec 2013-07-11 17:09
    I remember, that it is quite easy to call a method on null in C++. The only problem is that null obviously has no vtable, so you can not use any virtual method on it. It can be quite useful.
    Consider how short is a DFS in a BST then:
    struct Node{
    Node * left,right;
    void dfs(IVisitor * visitor){
    if(this){
    visitor->visit(this);
    left->dfs(visitor);
    right->dfs(visitor);
    }
    }
    };
  • foo 2013-07-11 17:20
    qbolec:
    I remember, that it is quite easy to call a method on null in C++. The only problem is that null obviously has no vtable, so you can not use any virtual method on it. It can be quite useful.
    Consider how short is a DFS in a BST then:
    struct Node{
    Node * left,right;
    void dfs(IVisitor * visitor){
    if(this){
    visitor->visit(this);
    left->dfs(visitor);
    right->dfs(visitor);
    }
    }
    };
    I'm no standards lawyer, so I don't know if it's actually legal or just happens to work with some compilers -- according to SO it seems to be the latter.

    Anyway, I'd consider it very bad style and error-prone -- imagine someone adds something, checking, logging, whatever, to the start of dfs(). If all it gives you is to save one "if" like here, I wouldn't bother. If it occurs more frequently, I'd write a free function (which can do the NULL check and then call the actual method) and its interface would say that its parameter may be NULL.
  • Java? 2013-07-11 17:30
    What java compilers are people using that don't force booleans in if statements?

    The only useful time to do constant == something is in languages where booleans aren't enforced (like C).

    constant.equals is different.

    Captcha: suscipere
    I have a suscipere that people are bad at languages.
  • chubertdev 2013-07-11 17:40
    shmosel:
    TRWTF is using
    if (null == aReceiver)
    instead of
    if (null.equals(aReceiver))


    TRWTF would be an object that is supposed to represent nothingness having a method.
  • shmosel 2013-07-11 17:58
    Then how about
    if (null != null && null.equals(aReceiver))
  • Evan 2013-07-11 17:59
    foo:
    qbolec:
    I remember, that it is quite easy to call a method on null in C++.
    I'm no standards lawyer, so I don't know if it's actually legal or just happens to work with some compilers -- according to SO it seems to be the latter.

    Anyway, I'd consider it very bad style and error-prone -- imagine someone adds something, checking, logging, whatever, to the start of dfs(). If all it gives you is to save one "if" like here, I wouldn't bother. If it occurs more frequently, I'd write a free function (which can do the NULL check and then call the actual method) and its interface would say that its parameter may be NULL.
    Agreed with all of the above. Calling an function on null provokes undefined behavior, and even if that's an unlikely one, it is something that can cause incorrect-according-to-you-but-still-correct optimizations. For instance, in the following:
    int * p = ...;
    
    int x = *p;
    if (!p) {
    ....
    }

    you may find that the compiler will optimize away the if when you turn on optimization. Why? Because the only time the body of the if will run occurs if p is null; but if p is null, then the dereference of it on line 2 will provoke undefined behavior. So it doesn't matter what happens in that case. I think this isn't a terribly popular optimization at this time, but is correct with respect to the standard, which is what you should be writing against unless you have a damn good reason to do otherwise. See this for a description of how this optimization has led to an exploitable security hole in the Linux kernel.

    The compiler could just as correctly optimize other things based on the assumption that this is not null. Either directly -- e.g. it is allowed to assume that your if(this) is redundant and remove the check, always entering the body -- or indirectly, as in the above (which doesn't do anything for your example).

    Doing what qbolec suggests and assuming you can call functions on null is fragile to the addition of virtual, it is fragile to your compiler and optimization settings, it is fragile to other programmers' surprise. Strongly agree it's a bad idea.
  • Matt Westwood 2013-07-11 18:02
    HardwareGeek:
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.
    Please apply for a job at my company immediately. We need you. Your profanity-laden rants would fit right in, too.

    As for the latter, I have usually replaced the telephone receiver back into its cradle before letting rip, in order not to alienate customers (potential or actual).
  • chubertdev 2013-07-11 18:13
    shmosel:
    Then how about
    if (null != null && null.equals(aReceiver))


    Let's get super-WTF-ery


    if (null != null & null.equals(aReceiver))
  • shmosel 2013-07-11 18:36
    chubertdev:
    shmosel:
    Then how about
    if (null != null && null.equals(aReceiver))


    Let's get super-WTF-ery


    if (null != null & null.equals(aReceiver))


    Must. Turn. It. Off.

    if (null != null & null.equals(aReceiver)) {
    return aReceiver & ~null;
    }
  • S 2013-07-11 18:56
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.


    Sounds great in theory. Not so much if you're dealing with a million-line codebase that dates to Java 1.0 - one which triggers warnings on stuff that's since been deprecated, or entire categories of warnings that didn't exist when the code was written. E.g generics in Java 5, or resource cleanups in 7.

    The code may actually be perfectly functional, it just doesn't conform to newer coding standards. The warnings *do* get fixed over time, but at any point, the entire codebase is going to have a *lot* of them, and even single files might have many hundreds...
  • Captain Oblivious 2013-07-11 18:57
    DaveK:
    C-Derb:
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    People who get thrown by the order of arguments to a commutative operator are TRWTF.



    This is what happens when average people program. This is why we can't have nice things.
  • chubertdev 2013-07-11 19:12
    shmosel:
    chubertdev:
    shmosel:
    Then how about
    if (null != null && null.equals(aReceiver))


    Let's get super-WTF-ery


    if (null != null & null.equals(aReceiver))


    Must. Turn. It. Off.

    if (null != null & null.equals(aReceiver)) {
    return aReceiver & ~null;
    }


    Time to end the universe:


    return aReceiver % null;
  • ChorroDulce 2013-07-11 19:13
    AMEN!
  • chubertdev 2013-07-11 19:15
    S:
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.


    Sounds great in theory. Not so much if you're dealing with a million-line codebase that dates to Java 1.0 - one which triggers warnings on stuff that's since been deprecated, or entire categories of warnings that didn't exist when the code was written. E.g generics in Java 5, or resource cleanups in 7.

    The code may actually be perfectly functional, it just doesn't conform to newer coding standards. The warnings *do* get fixed over time, but at any point, the entire codebase is going to have a *lot* of them, and even single files might have many hundreds...


    I believe that that is called "technical debt."

    I've made it a personal rule that when I "inherit" a codebase, that's the cleanup. Don't break anything, but don't hide new warnings because there are so many old ones.
  • foo 2013-07-11 20:33
    S:
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.


    Sounds great in theory. Not so much if you're dealing with a million-line codebase that dates to Java 1.0 - one which triggers warnings on stuff that's since been deprecated, or entire categories of warnings that didn't exist when the code was written. E.g generics in Java 5, or resource cleanups in 7.

    The code may actually be perfectly functional, it just doesn't conform to newer coding standards. The warnings *do* get fixed over time, but at any point, the entire codebase is going to have a *lot* of them, and even single files might have many hundreds...
    And your compiler doesn't have options to turn off specific sets of warnings, even for features that change between language revisions? Pity!
  • foo 2013-07-11 20:33
    Matt Westwood:
    HardwareGeek:
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.
    Please apply for a job at my company immediately. We need you. Your profanity-laden rants would fit right in, too.

    As for the latter, I have usually replaced the telephone receiver back into its cradle before letting rip, in order not to alienate customers (potential or former).
    Just kidding, please keep up the good cursing, it gets really boring here otherwise.
  • DaveK 2013-07-11 22:30
    foo:
    DaveK:
    C-Derb:
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    People who get thrown by the order of arguments to a commutative operator are TRWTF.

    The operator is commutative. Readability not is.
    What you did with that second sentence there is so wrong I am forced to reference <frystare.jpg>:

    - Programs are written in computer languages, not English.
    - The verb "to be" is not an operator and not commutative.
    - Even if it was, what you've done is not equivalent to swapping the "operands", but swapping one operand with the operator. So you haven't done the equivalent of commutating, you've done the equivalent of rewriting in reverse Polish.

    So, nice sarcasm, but completely fails to prove your point.

    In computer programs, which are mathematical constructs, not human language ones, if you are at all thrown by the order of operands to a commutative operator, then it just shows that you don't sufficiently understand the mathematical meaning behind it at a deep level.
  • S 2013-07-11 23:14
    chubertdev:
    I believe that that is called "technical debt."

    I've made it a personal rule that when I "inherit" a codebase, that's the cleanup. Don't break anything, but don't hide new warnings because there are so many old ones.


    You're right - except that doing so simply isn't an option. Partly because of the time it would require - months for a codebase of this size - and partly because of the risk of exposing customers to unnecessary large-scale code changes. Remember what I said about the code going back to Java 1.0, and guess what the test coverage looks like for most of it. Newer parts have automated tests, certainly - but those are the bits least in need of cleanup...


    foo:
    And your compiler doesn't have options to turn off specific sets of warnings, even for features that change between language revisions? Pity!


    Sure it does. But we usually *want* the warnings turned on, so we can see what should be fixed when modifying the file. As I said, we do fix warnings when we can - it's just a very slow process, and every Java release tends to introduce a few more.
  • EuroGuy 2013-07-12 03:20
    DaveK:

    In computer programs, which are mathematical constructs, not human language ones, if you are at all thrown by the order of operands to a commutative operator, then it just shows that you don't sufficiently understand the mathematical meaning behind it at a deep level.

    It's the pot and the kettle. It bothers you that it bothers us which order the operands get, so you clearly do have a strong opinion too about the order of operands to a commutative operator.

    I like to think that I do understand the mathematical magic behind the syntax of the progamming language. But at the same time I also observe that my brain processes code that reads like human language quicker and better. I dare claim that having the operands in the "natural" order prevents more problems than it creates.

    I also dare claim that 90% of the people who use the reverse notation don't do it because they sincerely believe it prevents bugs, but more so because it is another way to show that they are 1337 programmers.

    Also, those that understand the programming language well would never confuse = and ==. It never happened to me; at least it has never been proven! So that returns me to the point I made earlier: the reverse notation might be useful for amateur programmers, but they wouldn't be aware about this trick. The seasoned programmers who know it, most likely don't need it.
  • Mike 2013-07-12 03:49
    foo:
    qbolec:
    I remember, that it is quite easy to call a method on null in C++. The only problem is that null obviously has no vtable, so you can not use any virtual method on it. It can be quite useful.
    Consider how short is a DFS in a BST then:
    struct Node{
    Node * left,right;
    void dfs(IVisitor * visitor){
    if(this){
    visitor->visit(this);
    left->dfs(visitor);
    right->dfs(visitor);
    }
    }
    };
    I'm no standards lawyer, so I don't know if it's actually legal or just happens to work with some compilers -- according to SO it seems to be the latter.

    Anyway, I'd consider it very bad style and error-prone -- imagine someone adds something, checking, logging, whatever, to the start of dfs(). If all it gives you is to save one "if" like here, I wouldn't bother. If it occurs more frequently, I'd write a free function (which can do the NULL check and then call the actual method) and its interface would say that its parameter may be NULL.
    The alternative would be
    struct Node{
    
    Node * left,right;
    void dfs(IVisitor * visitor){
    visitor->visit(this);
    if(this->left)
    left->dfs(visitor);
    if(this->right)
    right->dfs(visitor);
    }
    }
    };
    But in the C world you'd be perfectly fine with
    void dfs(struct Node *this, IVisitor *visitor) {
    
    if(this) {
    visitor->visit(this)
    dfs(this->left, visitor);
    dfs(this->right, visitor);
    }
    }

    and there is probably no C++ compiler in existence (nor will there ever likely be one) in which nonvirtual methods won't work on null object pointers, so maybe the standard should've specified this case explicitly: In p->m(), if m is nonvirtual, p must not be dereferenced. Ditto for p.m. (Although p.x being the offset of x when x is not a method and p is null, might be going a bit too far... despite that being the interpretation taken by almost all compilers too.)
  • vlad 2013-07-12 05:31
    apache commons-lang, version 1.0 (released 2002-10-04) features the method StringUtils.replace(java.lang.String text, java.lang.String repl, java.lang.String with) ("Replace all occurances of a string within another string.")

    http://commons.apache.org/proper/commons-lang/javadocs/api-1.0/org/apache/commons/lang/StringUtils.html#replace(java.lang.String, java.lang.String, java.lang.String)
  • augue 2013-07-12 07:03
    C-Derb:
    Didn't you mean
    return null == o;
    See how stupid that notation is? Even in a debate about the merits of that pattern, it is just simply more natural to write myVar == conditionalValue.

    Debate over.

    JC never argues for that ordering in the first place. You can't claim "debate over" just because one person happens to agree with you.
  • foo 2013-07-12 07:50
    Mike:
    and there is probably no C++ compiler in existence (nor will there ever likely be one) in which nonvirtual methods won't work on null object pointers,
    Unless it's an optimizing compiler, see #412381. This is about C, but can be directly applied to our C++ case.

    so maybe the standard should've specified this case explicitly: In p->m(), if m is nonvirtual, p must not be dereferenced. Ditto for p.m.
    Sure, it could be done, but why make a special exception in the standard for something which still is (IMHO) very bad style in the first place.
  • foo 2013-07-12 07:58
    EuroGuy:
    I like to think that I do understand the mathematical magic behind the syntax of the progamming language. But at the same time I also observe that my brain processes code that reads like human language quicker and better. I dare claim that having the operands in the "natural" order prevents more problems than it creates.
    Well put.

    I do think that I understand the mathematics of programming languages either way, but it's just about better readability. For the same reason, I prefer a function to be called replaceAll rather than x28g756q though mathematically, of course, there's no difference.

    FTR @DaveK, my "Readability not is." was just meant as a quick joke. I didn't expect a rigorous mathematical and ligustic analysis. For thanks, aynway biting.
  • Mozzis 2013-07-12 09:53
    Stupid pedantic objection to a practice that avoids the common error of using '=' when you meant '==', thus avoiding the potential for some devilishly subtle bugs.
  • foo 2013-07-12 10:10
    Mozzis:
    Stupid pedantic objection to a practice that avoids the common error of using '=' when you meant '==', thus avoiding the potential for some devilishly subtle bugs.
    Very subtle, unless you use a modern compiler with warnings, or bother to fucking read the previous comments before making a point already refuted yesterday.
  • Jonathan Wilson 2013-07-12 10:44
    Some code I work on (C++) has its own string class. But that's because C++ strings suck (or they did back when this code was originally created) and because its a project where all the extra overhead and crap in C++ strings (a lot of which is mandated by the C++ standards) would get in the way.
    But unlike the examples I see on TDWTF, our class is the exact opposite of a WTF. Neat. Clean. Uses C & C++ string functions where doing so makes sense.
  • trololo 2013-07-12 11:27
    This is what happens when you come from a C background where you would implement event the most basic function.
  • C-Derb 2013-07-12 11:57
    Mozzis:
    Stupid pedantic objection to a practice that avoids the common error of using '=' when you meant '==', thus avoiding the potential for some devilishly subtle bugs.
    No, using '=' when you meant '==' is not that common. Pay attention to the code you are writing.
    EuroGuy:
    I also dare claim that 90% of the people who use the reverse notation don't do it because they sincerely believe it prevents bugs, but more so because it is another way to show that they are 1337 programmers.
    This!
  • Evan 2013-07-12 12:32
    DaveK:
    In computer programs, which are mathematical constructs, not human language ones, if you are at all thrown by the order of operands to a commutative operator, then it just shows that you don't sufficiently understand the mathematical meaning behind it at a deep level.
    Like I said in my last post, I am not a fan of 'const == var' and don't use it. But I think this argument is dumb too.

    The error the 'const == var' idiom is intended to prevent has nothing to do with commutativity. Commutativity is a red herring. It's trying to prevent you from accidentally substituting (and not noticing the substitution of) a completely different, non-commutative operator.

    In other words, no one is saying that 5 == x is easier to write, read, or understand than x == 5.

    The argument is that, first, x == 5 vs x = 5 is hard to miss and, second, that reversing it to 5 = x is the right way of preventing that bug.

    (I'm not sure how much I agree with the first one and definitely disagree with the second for a bunch of reasons.)
  • Gene Wirchenko 2013-07-12 12:57
    eViLegion:
    Also... who the hell uses the indefinite article at the start of variable/parameter names? Baffling.


    I do. I use it to mean the entity of a particular type that is under consideration. This is useful when there may be others.

    Sincerely,

    Gene Wirchenko
  • Gene Wirchenko 2013-07-12 13:00
    EuroGuy:
    Any programmer who is pedentic enough to use the Yoda style, is probably also professional enough not to confuse = and ==.


    It is not a matter of confusing them. It is just too easy to make a mistake and miss entering one of the equals signs. Why not make it easy to catch the error?

    I think that the reverse style is ugly, but it does do what it has to. C should not have redefined the = operator, but it is the world we live.

    Sincerely,

    Gene Wirchenko
  • chubertdev 2013-07-12 13:10
    S:
    chubertdev:
    I believe that that is called "technical debt."

    I've made it a personal rule that when I "inherit" a codebase, that's the cleanup. Don't break anything, but don't hide new warnings because there are so many old ones.


    You're right - except that doing so simply isn't an option. Partly because of the time it would require - months for a codebase of this size - and partly because of the risk of exposing customers to unnecessary large-scale code changes. Remember what I said about the code going back to Java 1.0, and guess what the test coverage looks like for most of it. Newer parts have automated tests, certainly - but those are the bits least in need of cleanup...


    Fortunately for me, I can choose a job where this isn't an issue. I hate being a code janitor, cleaning up everyone's vomit with sawdust.
  • foo 2013-07-12 15:22
    Gene Wirchenko:
    I think that the reverse style is ugly, but it does do what it has to. C should not have redefined the = operator, but it is the world we live.
    While I agree on an abstract level, I still wonder what's a better practical alternative.

    I've programmed in Pascal for a while, and typing := for assignment (which is by far the most common operator in most programs) is a bit annoying. The Basic way of using a single operator also has drawbacks, as have been discussed here various times.

    So C chose the pragmatic approach of using the simplest token = for the most common operator, even if it resulted in the ugly == for equality. Today, in Unicode, you could probably easily find different suitable characters for both, but if you're limited to ASCII (or characters you can easily type), I still wonder what would be the optimal choice ...
  • chubertdev 2013-07-12 15:38

    int c ۩ getValue("test");
    if(c = 5) {
    ...
    }
  • ACM 2013-07-12 15:59
    foo:
    Very subtle, unless you use a modern compiler with warnings, or bother to fucking read the previous comments before making a point already refuted yesterday.

    Or an alternative which is very useful: have your IDE warn about it. In IDEA its called "nested assignments" and you can select that to be a warning. And it will highlight your code right after making that error.

    Besides, in Java it would only work with booleans and who in his right mind would test booleans using constants?

    I wouldn't do this:

    if(value == true){}
    // or
    if(value == false){}


    I would test them like so:

    if(value){}
    // and
    if(!value){}


    So the main case advocated here in Java is in itself an example of redundant (and thus bad) code ;)

    Even without a highlight on nested assignments, my IDE would still highlight both as being always true or always false (and the variant with == as having being able to simplify).

    With two variables, you'd be never get a compiler error either way. So the only scenario you could save some errors by forcing a compile error would be where one of the sides is a functioncall and the other is a variable.

    if(someCall() = a){} // This would be a error
    // Whereas this might be silent
    if(a = someCall()){} // This would be a error


    But I actually very seldomly compare two booleans with eachother... I rarely want to test whether the booleans are either both false or both true and have that trigger the same blockstatement.
    The case where I want to assign a variable and directly test its outcome is slightly more common in the Java-codebases I work with.
  • Gunslnger 2013-07-13 03:29
    Pock Suppet:
    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!


    No.
  • Gunslnger 2013-07-13 03:47
    EuroGuy:
    I also dare claim that 90% of the people who use the reverse notation don't do it because they sincerely believe it prevents bugs, but more so because it is another way to show that they are 1337 programmers.

    Also, those that understand the programming language well would never confuse = and ==. It never happened to me; at least it has never been proven! So that returns me to the point I made earlier: the reverse notation might be useful for amateur programmers, but they wouldn't be aware about this trick. The seasoned programmers who know it, most likely don't need it.


    You are incorrect. You are assuming smugness simply because you disagree with the reasoning. That's idiotic.

    You misunderstand the issue. It doesn't matter how well you know the language. People make typos. If you always do it in the "unnatural" order, then the compiler finds your typos, whereas if you do it the "natural" way, you have a bug you may or may not find.
  • real-modo 2013-07-13 05:16
    Gunslnger:
    You misunderstand the issue. It doesn't matter how well you know the language. People make typos. If you always do it in the "unnatural" order, then the compiler finds your typos, whereas if you do it the "natural" way, you have a bug you may or may not find.

    Why wouldn't such a bug be caught by a unit test?

    People have been bandying around the phrase "professional programmer" here.

    Professional programmers have the computer catch their bugs.

    Professional programmers also know that code is read hundreds of times more often than it is written, so they write their code for other programmers to read. (Only novices worry about writing code to make the computer do what they want. Of course a professional can do that.)

    As a matter of professional courtesy to their peers, professional programmers write their code so that (1) it can be read quickly, and (2) hasty readers will form a correct impression of what the code does.

    Using a "natural" syntax is part of (1).

    If you're worried about uncaught errors of this sort, you're still at novice level. When code readability is your primary concern, you can call yourself professional.
  • gcc -Wall 2013-07-13 06:57
    chubertdev:

    int c ۩ getValue("test");
    if(c = 5) {
    ...
    }
    foo.c: In function 'main':
    
    foo.c:6:1: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
  • Matt 2013-07-13 08:07
    Proper Yoda style would be "null aReceiver =" (Null, aReceiver is).

  • gnasher729 2013-07-13 10:10
    Nick:
    I've programmed in C/C++ for so long that "ptr != NULL" or "ptr == NULL" always makes me look twice, because I'm so used to just "if(ptr)", read as "if ptr", or "if(!ptr)", read as "if no(t) ptr". I've never confused those two but the comparison versions remind me of "if(b == true)" and "if(b != false)" with booleans which is basically the equivalent of ==NULL and != NULL respectively --- huh?

    bools are bools and pointers are pointers. and, or, not are boolean operators and should be used with bools, not with pointers. Pointers shouldn't be treated as booleans.
  • Meep 2013-07-13 11:11
    Lothar:
    String.replaceAll expects a regular expression, so the given helper method is not a real reinvention of the wheel.


    But String.replace does not take a regex.
  • gcc -Wall 2013-07-13 11:32
    gnasher729:
    Nick:
    I've programmed in C/C++ for so long that "ptr != NULL" or "ptr == NULL" always makes me look twice, because I'm so used to just "if(ptr)", read as "if ptr", or "if(!ptr)", read as "if no(t) ptr". I've never confused those two but the comparison versions remind me of "if(b == true)" and "if(b != false)" with booleans which is basically the equivalent of ==NULL and != NULL respectively --- huh?

    bools are bools and pointers are pointers. and, or, not are boolean operators and should be used with bools, not with pointers. Pointers shouldn't be treated as booleans.
    [citation required]

    I'd go further and say that any object that has meaningful "content exists/doesn't exist" states and where no confusion is possible should be treatable as bool. Fortunately, in C++ I can do that. And you can be happy with your language of choice that doesn't allow it. So we're all happy. ;)
  • randomreader 2013-07-13 17:31
    That's nothing, Lyle made a templating library to generate templates.
  • hhmg560 2013-07-13 18:52
    foo[url="http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html:
    This[/url] is about C, but can be directly applied to our C++ case.
    Their example with the global function pointer takes it too far IMO. Global variables are visible everywhere, so the compiler can't assume where it was last accessed...
  • foo 2013-07-14 05:25
    hhmg560:
    foo[url="http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html:
    This[/url] is about C, but can be directly applied to our C++ case.
    Their example with the global function pointer takes it too far IMO. Global variables are visible everywhere, so the compiler can't assume where it was last accessed...
    It's declared static, so it's only visible in this compilation unit, so a compiler that can see the whole TU at once (which clang apprently does) can perform this optimization. Of course, it doesn't know when it was last set at runtime, but if it's only ever set to null (UB when called) and one single other value (impl), it can assume it must be the latter in a correct program.

    Now, I do wonder where this particular optimization is useful. But please don't take it to mean I claim it's not useful -- I suppose they did have a reason to implement it, they probably don't like wasting their time.
  • Aufgehaben 2013-07-14 06:45
    We used to do that at my old job, using indefinite articles for parameters (aValue), definite values for global variables (theValue) and possesive for for member variables (myValue).
    It worked rather well, it was easy to see where each value came from.
  • chubertdev 2013-07-15 12:50
    gcc -Wall:
    chubertdev:

    int c ۩ getValue("test");
    if(c = 5) {
    ...
    }
    foo.c: In function 'main':
    
    foo.c:6:1: warning: suggest parentheses around assignment used as truth value [-Wparentheses]


    You'd think it wasn't C code, almost as if it was a fictional language...
  • blah 2013-07-15 14:42
    Japanese is not an Altaic language.
  • abjdhoaz 2013-07-16 07:17

    صورمشبات .مشبات . ديكورات مشبات .صورمشبات
    http://shomane.blogspot.com/


    صورمشبات
    http://12abjdhoaz.blogspot.com/


  • Neil 2013-07-16 13:01
    foo:
    return null; unless (null != aReceiver);
    Perl does this sort of thing of course:
    return unless aReceiver;
  • nomdeplume 2013-07-17 03:42
    Gunslnger:
    You misunderstand the issue. It doesn't matter how well you know the language. People make typos. If you always do it in the "unnatural" order, then the compiler finds your typos,

    ...but only in the case where you're comparing a constant to a variable. You'll still have the exact same problem when you're comparing two variables, except now you think you're protected from such errors, and will therefore have an even harder time tracking it down.

    Even if you happen to like the "const == variable" syntax and find it perfectly easy to read and parse, it doesn't actually solve the alleged problem, so that's not a good reason to give for using it. Just say you like it. If you're actually trying to solve this problem then:

    a) use a language that doesn't permit this; or
    b) configure your compiler to issue a warning or error if you accidentally do this; or
    c) configure your source control system to refuse check-ins that use this syntax you've decided to disallow; or
    d) periodically run a source checker to look for this and any other construct you've encountered that causes you problems.

    Any of the above methods will be more effective at actually resolving this issue, and will do so consistently.
  • Luke 2013-07-24 17:43
    There are an infinite number of empty strings and all strings so the first example should not halt. If it did however it would return "BobBobBobBobBobBob"....
  • -is 2013-07-26 03:55
    DaveK:
    C-Derb:
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    People who get thrown by the order of arguments to a commutative operator are TRWTF.



    What he wrote.