views:

902

answers:

6

I have a simple question related to one-line programming. First an example:

function test(a)
{
   var b=a.toString();
   return b.replace("a","b");
}

It's very simple (this function is, of course, useless), but the question here is little more complicated: What if I was to do this in one line? I have my thoughts, but tell me does this work properly with respect to memory cleanup:

function test(a)
{
   return (arguments[1]=a.toString()).doSomething().doSomethingMore(arguments[1]);
}

This is, of course, an example, but the idea is simple: use arguments as a container for local variables - I'm not sure, but from what I know, when function are over, arguments are deleted also ? Or does creating new elements in arguments makes this element defined globally? From my tests it seems that I'm correct, but I'm curious to see if anyone has tried this? Is this a safe and clean solution?: ) Thanks for any comments.

Here are more real problem with One-Line script problem:

function (number,limiter)
{
return ((arguments[2] = number.toString().replace(
         new RegExp("(\\d+)(\\d{3})($|"+limiter+")"),
         '$1'+limiter+'$2$3')) == number) ?
            arguments[2] : 
            arguments.callee(arguments[2],limiter);
}

This one line function do things with given string and return it or parse it recursively to the same function. (on other thread i show how this could be done without recursion, but this is not a case of a problem).

A: 

I think you only have to try reading it to realise it's not a "clean" solution! I'd especially avoid chaining an assignment like that:

return (arguments[1]=a.toString()).doSomething().doSomethingMore(arguments[1]);
// is this a or a.toString()? it's not clear at a glance -------------^
Greg
From mine developement it seems that this works... and value of arguments[1] is a.toString()..
Wilq32
A: 

Why are you trying to avoid creating a variable locally? Doing so makes code that's a lot easier to read/understand, and I don't think you're really gaining anything.

The variables are basically just references to the objects you're creating. Whether you assign them to a normal variable or put them in an array the cleanup is going to be the same. Both the arguments array and the local variable will be out of scope once the method returns so I don't think you're going to see any difference in behavior. (the arguments array's scope might be different if the method was called via an apply() command, but I haven't tested that to be sure).

Herms
+4  A: 

You're needlessly complicating the operation. You don't need to declare anything at all.

function test(a) {
return a.toString().replace("a","b");
}

There shouldn't be a hit to performance or memory with this.

However, if you were to use a closure, you could potentially run into memory issues.

Assigning a value to the arguments array like you're doing is pointless, as each function has its own arguments array. To address your question about scope, Javascript scoping is lexical; something declared locally inside a function isn't automatically accessible to things outside the function.

edit: using the arguments array is no cleaner or better than any other method. It's actually worse than being clear.

jacobangel
I think he means in a more generic sense.
kouPhax
well then its just a needlessly complicated way of doing it. garbage collection will take care of it.
jacobangel
Yes that was more generic problem. To precise I show you real example.
Wilq32
+1  A: 

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." – Brian W. Kernighan

I'm not knocking you, I'm just saying be careful not to get overzealous.

geowa4
It's rather question in type of One-Line javascript programming. I know that this one is less readable:)
Wilq32
A: 

~~shudder~~

This reminds me of awk where there is no way to have local variables in a function unless you declare extra variables in the arguments list.

If you need to have a local variable, just do it.

Jason S
+3  A: 

Your example may be over-complicating a simple operation but the technique you are demonstrating is called method 'chaining'. It's a perfectly valid form and can actually be used to make code more readable when the intermediate results are not needed or meaningful.

My current favorite example of this is the wonderful DateJs:

var nextTuesday = DateJs.today().next().tuesday();

var aBitLater = DateJs.now().addHours(1).addMinutes(30);

Sure, it's syntactic sugar and could be written more verbosely as separate statements, but with careful method nameing you can actually cause this to read like English.

GC / Memory management is not affected by this style, parameters to functions are cleaned up just as any other. In fact it may actually be safer since the parameters immediately go out of scope after the function calls return and there is no need to create local vars for values just to pass them to the next function call.

Your example may be a little contrived but if you use it where it makes sense, it's a useful pattern.

Mark Renouf