tags:

views:

328

answers:

9

I was recently berated by a fellow developer for using "string math" in an app I wrote. I'm pretty new to the whole development thing, with no formal training, and I haven't heard of this issue. What is it?

Code in question:

$('.submit-input').click( function() {
    var valid = true;
    $('input, select, radio').removeClass('error');
    $('.error-message').hide();

    $('.validate').each( function() {
        if($(this).val() == $(this).attr('default')){
            valid = false;
            $(this).addClass('error');
        }
    });

    if(!$('select[name="contact"] option:selected').val() != ''){
        $('select[name="contact"]').addClass('error');
        valid = false;
    }

    if(!$('input[name="ampm"]:checked').length){
        $('input[name="ampm"]').addClass('error');          
        valid = false;
    }

    if(!valid){
        $('.error-message').css('display','block');
        return false;
    } else {

        var services_selected = 'Services Selected: ';
        services_selected += $('.l3').text() + ', ' + $('.l4').text() + ', ' + $('.l5').text() + '; ' + $('.l6').text();
        var prices = 'Prices: ';
        prices += $('.l7').text() + ', ' + $('.l8').text() + ', ' + $('.l9').text() + ', ' + $('.l10').text();
        var name = 'Name: ';
        name += $('input[name="name"]').val();  
        var phone = 'Phone: ' 
        phone += $('input[name="phone"]').val();
        var time = 'Preferred contact time: ';
        time += $('select[name="contact"] option:selected').val() + $('input[name="ampm"]:checked').val();

        $.ajax({
            url: 'php/mailer.php',
            data: 'services_selected=' + services_selected +'&prices=' + prices + '&name=' + name + '&phone=' + phone + '&time=' + time,
            type: "POST",
            success: function() {
                $('#email_form_box .container').children().fadeOut(500, function() {
                    $('#email_form_box .container').html('<div style="margin:20px auto;text-align:center;width:200px;">yada yada yada<br /><span class="close">Close</span></div>');
                });
            }
        });
    }

});

Edit: The gist I'm getting here is that this isn't a standard development colloquialism, and I should probably talk to the guy who gave me guff in the first place. So I'll do that. Thanks guys. I'll be back with an answer, or to check off whoever knew already.

+1  A: 

Edit: Ok, my bad, you don't use + for concatenation. Edited below:

Edit2: Ok, it is JavaScript, back to + :P


I think he's probably referring to something like:

$my_html = "<p>" + someVar + "<em>" + somethingImportant + "</em></p>";

i.e. using . for concatenation.

Skilldrick
Or with `.` instead of `+`.
Mark Byers
This wouldn't even work in PHP, because `+` is reserved for addition and `.` is used for string concatenation.
Matti Virkkunen
Sorry, mistagged. Should've been "javascript"
dclowd9901
How is it even possible to confuse PHP with JavaScript...
Matti Virkkunen
When you're on 3 hours sleep ;)
dclowd9901
+1  A: 

Are you perhaps storing/manipulating numerical data using strings? That's rarely a good idea.

COME FROM
Is it not a good idea even if you're not using them as numerical data?
dclowd9901
@dclowd9901 Imho all values should be stored in a according data structure and that means, use int (double..) for numbers. I like it because numbers are always numerical data even if you don't use it that way. But i don't know if others will agree with my opinion.
InsertNickHere
@InsertNickHere: The problem is that into and double are both not appropriate data structures for decimal fractions (such as money) either. Strings can actually be a better option there (e.g. PHP's BCMath extension).
Michael Borgwardt
@Michael oh i dident know about that, since i have never coded an app dealing with money. :)
InsertNickHere
A: 

To extend Skilldrick's answer:

There's nothing wrong using "+" to concat strings (depending on your language) till one of your variables isn't a string:

echo 0 + ": hi!<br />";
echo 0 .. ": hi!<br />";

The first line might output "0" (as it tries to convert the string to a number). The second line works as expected writing "0: hi!
".

Mario
+1  A: 

Since you're new to development the best thing to do would be to discuss with this developer what "String math" is, how you can identify when you're doing it again, and how to avoid it. Then, come back here and answer your own question so we can see what this "String math" really is - from your fellow dev's perspective.

Irwin
Don't be afraid to ask questions. No developer knows everything, and you'll learn more from others than you will by struggling alone. It also helps to find out how your co-workers like to do things, to avoid pointless arguments over programming style.
Kristopher Johnson
@Kristopher Johnson: Easy to say, harder in practice. It's a very intimidating world, this development thing, and I know that I'm miles behind most other people. It'd be nice if maybe more tact was involved.
dclowd9901
It is unfortunate that so many developers are assholes, but you'll have to develop a thick skin. Ultimately devs will respect you more if you ask the questions you need to ask, and they will even be flattered to be asked to teach you what they know (as long as you don't overdo it).
Kristopher Johnson
+1  A: 

Since you retagged your question with javascript, then your colleague might mean bugs in your code that lead to questions like http://stackoverflow.com/questions/1416633/strange-javascript-addition-problem

Basically "1" + 1 evaluates to 11 in javascript, while 1 + 1 evaluates to 2. Now replace the first argument of + with a variable and you can get some unexpected behaviour.

Residuum
Yeah, I get this, and parse the numbers out if they come in through string data, but all I was working with were strings, through and through, so I'm not entirely sure this is what he would have had a problem with.
dclowd9901
+6  A: 

In most Javascript browser implementations, concatenating strings is slow due to excessive copying. See http://stackoverflow.com/questions/2781686/javascript-string-concatenation-slow-performance-array-join

Preferred method is to use an array and join:

var pieces = ["You purchased "];
pieces.push(num, " widgets.");
el.innerHTML = pieces.join('');

Added more:

I think you may have a lurking bug in your code: you don't appear to be escaping your data values. If any of them include an ampersand, you'd be in trouble. Use escape() for all of your data values.

ps. And this is a real bug that the other developer missed. The string math issue is a performance / maintainability issue.

Added:

I rewrote your email composition section (quickly). I think it's cleaner (and will be slightly faster) when using a piece array.

....
} else {

var d = []; // the post_data pieces table

d.push ('services_selected='); // Start the services_selected value
d.push ('Services Selected: ');
d.push ($('.l3').text(), ', ', $('.l4').text(), ', ', $('.l5').text(),
        '; ', $('.l6').text());

d.push ('&prices='); // Start the prices value
d.push ('Prices: ');
d.push ($('.l7').text(), ', ', $('.l8').text(), ', ', $('.l9').text(),
        ', ', $('.l10').text());

d.push ('&name='); // Start the name value
d.push ('Name: ', $('input[name="name"]').val());

d.push ('&phone='); // Start the phone value
d.push ('Phone: ', $('input[name="phone"]').val());

d.push ('&time='); // Start the timevalue
d.push ('Preferred contact time: ',
        $('select[name="contact"] option:selected').val(),
        $('input[name="ampm"]:checked').val());

    $.ajax({
        url: 'php/mailer.php',
        data: d.join(''),
        type: "POST",
        success: function() {
            $('#email_form_box .container').children().fadeOut(500, function() {
                $('#email_form_box .container').html('<div style="margin:20px auto;text-align:center;width:200px;">yada yada yada<br /><span class="close">Close</span></div>');
            });
        }
    });
}
Larry K
I would love to see a native string builder in the next version of ECMAScript.
ChaosPandion
This could very well be it, but the JS was to allow a user to send an e-mail to a CSR to contact them for sales information. When we're talking about such inconsistent usage (only activates on user request), is there even an issue using concatenation vs. `.join()`, besides one being simply pedantic?
dclowd9901
I read somewhere that it is only slow in IE (up to IE7). "array joining" is slow in Firefox but I guess this depends on the context and how much the engines can optimize the expression.
Felix Kling
There's no way this matters when concatenating that few strings. Stick with + unless you're joining a bunch; it's more concise, more readable, and you save the array allocation.
tclem
Re @tclem: Yes, of course. The example was an example. I use the array method when either adding strings in a larger loop or more than 5 or so concatenations in an expression.
Larry K
Re @dclowd9901 -- my answer was the one that I immediately thought of when I read your question. For something like composing an email, I would usually go with a pieces array since the email might contain a lot of relatively long strings, especially an html email. Was the developer being pedantic? Perhaps. But maybe he/she was burned by this issue in the past. Also, if that's the most someone can complain about, your code is in good shape. Some folks feel that they ''always'' need to find something to criticize.
Larry K
Thanks, Larry K, and thanks for all the great help!
dclowd9901
+1  A: 

it's probably lines like this that your co-worker has issue with. in theory this is perfectly correct code, but it's pretty much impossible to read.

services_selected += $('.l3').text() + ', ' + $('.l4').text() + ', ' + $('.l5').text() + '; ' + $('.l6').text();

have a look at the function and discussion here: http://frogsbrain.wordpress.com/2007/04/28/javascript-stringformat-method/

you can easily add this function to your JS and then you can change this horrible line of code to something like:

services_selected = '{0} , {1}, {2}, {3}; {4}'.format($('.l3').text(), $('.l4').text(), $('.l5').text(), $('.l6').text());
Patricia
I can see this being the case. He's a stickler for clean, pretty code. One of those Ruby heads :\
dclowd9901
A: 

Here's what I think of when I hear "String math." I'd yell at him, too.

public String StringAdd (String str1, String str2){
   int int1, int2;
   switch (str1){
      case "Zero":
      int1 = 0;
      break;
      case "One":
      int1 = 1;
      break;
      //...etc...
      default:
      throw new BadNumberSpellingException("You spelled a number wrong.");
   }
   switch (str2){
      case "Zero":
      int2 = 0;
      break;
      //...etc...
   }

   int result = int1 + int2;
   switch (result){
      case 0:
         return "Zero";
      case 1:
         return "One";
      case 2:
         return "Two";
      //etc....
   }
}
iandisme
+2  A: 

Okay, so here's the answer he told me:

I should have said inline string concatenation/parsing, which is a potential injection vulnerability and a sign of sloppy code or bypassing the framework.

Which doesn't exactly fit the other answers we have here. I'm going to give the check to the answer with the most upvotes, as it's probably the most useful, but just wanted to inform.

dclowd9901
Thanks for letting us know what he meant. BTW, you are allowed to accept your own answer (but you don't get any rep when you do).
GreenMatt
Good job on going back to him!
Irwin