473,704 Members | 2,626 Online

# function and arguments as aguments

Hi. I have the following code:

--------------------------------------
function Tunnel() {
//arguments[0](???);
}

function Sum() {
var sum = 0;
for (i=0; i<arguments.len gth; i++) sum += arguments[i];
};

// calling Sum directly
Sum(1,2,3,4);

// calling Sum through Tunnel
Tunnel(Sum, 1,2,3,4);
--------------------------------------

How should the Tunnel function be defined, knowing that the number of
parameters passed are unknown?

telmo
Feb 15 '06 #1
41 2572
You would be better off designing Sum to take an array as an argument,
then you can just pass the array of arguments to Sum

Feb 15 '06 #2
UnaCoder wrote:
You would be better off designing Sum to take an array as an argument,
then you can just pass the array of arguments to Sum

I was looking for a generic solution. But I presume for your replay that
there is no direct solution (at least no direct solution known by you
;) ).

Feb 15 '06 #3
Well I thought there was and I researched java script to see if you can
invoke a string containing java script code. the solution that seemed
intuitive would be to do something like:

function Tunnel() {
function_name= arguments[0];
arguments.shift (); args = arguments.join( );
eval function_name + "(" + args + ");";
}

I didn't put any error checking in there, or test that code, but as far
as I know that should work =)

Feb 15 '06 #4
On 15/02/2006 17:42, Telmo Costa wrote:

[snip]
// calling Sum directly
Sum(1,2,3,4);

// calling Sum through Tunnel
Tunnel(Sum, 1,2,3,4);
--------------------------------------

How should the Tunnel function be defined, knowing that the number of
parameters passed are unknown?

The previous suggestion - rewrite the Sum function to take an array
argument - is preferable as it's the simplest and most compatible
solution. However, there is an alternative: the Function.protot ype.apply
method.

function tunnel(func) {
return func.apply(null ,
Array.prototype .slice.call(arg uments, 1));
}
function sum() {
var total = 0,
i = arguments.lengt h;

while (i--) {
total += arguments[i];
}
}

alert(tunnel(su m, 1, 2, 3, 4)); /* 10 */

The problem with this approach is that not all browsers, especially IE
with a pre-5.5 JScript library, do not implement either the
Function.protot ype.apply or call methods. Though both can be emulated,
it requires quite a significant (though relatively trivial) amount of
work to accommodate a general case.

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Feb 15 '06 #5
UnaCoder wrote:
Well I thought there was and I researched java script to see if you can
invoke a string containing java script code. the solution that seemed
intuitive would be to do something like:

function Tunnel() {
function_name= arguments[0];
arguments.shift (); args = arguments.join( );
eval function_name + "(" + args + ");";
}

I didn't put any error checking in there, or test that code, but as far
as I know that should work =)

I always think of eval function as cheating :) Michael's solution is
more what i was looking for.

To be honest, the function i'm working with only takes 1 argument, so it
is like using the array solution. I was just wondering.

Nevertheless, thank you both.

Feb 16 '06 #6
UnaCoder wrote:
Well I thought there was and I researched java script to see if you can
invoke a string containing java script code. the solution that seemed
intuitive would be to do something like:

function Tunnel() {
function_name= arguments[0];
arguments.shift (); args = arguments.join( );
eval function_name + "(" + args + ");";
}

I didn't put any error checking in there, or test that code, but as far
as I know that should work =)

Arguments is not an array, it's just a list with a few other properties
that make it look a bit like an array. Consequently, it doesn't have
split() or join() methods (and I don't think you can add them to its
prototype).
--
Rob
Feb 16 '06 #7
Telmo Costa wrote:
Hi. I have the following code:

--------------------------------------
function Tunnel() {
//arguments[0](???);
}

function Sum() {
var sum = 0;
for (i=0; i<arguments.len gth; i++) sum += arguments[i];
};

// calling Sum directly
Sum(1,2,3,4);

// calling Sum through Tunnel
Tunnel(Sum, 1,2,3,4);
--------------------------------------

How should the Tunnel function be defined, knowing that the number of
parameters passed are unknown?

function tunnel()
{
this.sum = function(x){
var s=x[0], i=x.length;
while (--i) s += x[i];
return s;
}
this.product = function(x){
var s=x[0], i=x.length;
while (--i) s *= x[i];
return s;
}

var funcName = arguments[0];
var ar = [];
for (var i=1, len=arguments.l ength; i<len; ++i) {
ar[ar.length] = arguments[i];
}
return this[funcName](ar);
}

alert(tunnel('s um', 1, 2, 3, 4)); /* 10 */
alert(tunnel('p roduct', 1, 2, 3, 4)); /* 24 */
Note that the function (e.g. sum) name needs to be passed as a string.
--
Rob
Feb 16 '06 #8
>

function tunnel()
{
this.sum = function(x){
var s=x[0], i=x.length;
while (--i) s += x[i];
return s;
}
this.product = function(x){
var s=x[0], i=x.length;
while (--i) s *= x[i];
return s;
}

var funcName = arguments[0];
var ar = [];
for (var i=1, len=arguments.l ength; i<len; ++i) {
ar[ar.length] = arguments[i];
}
return this[funcName](ar);
}

alert(tunnel('s um', 1, 2, 3, 4)); /* 10 */
alert(tunnel('p roduct', 1, 2, 3, 4)); /* 24 */
Note that the function (e.g. sum) name needs to be passed as a string.

That won't do.

I'm building a XUL application (but could be HTML) and, at some point, I
need to start a couple of XMLHTTPRequest objects (using your examples,
sum and product will generate a XMLHTTPRequest object). Everything
worked ok, but now I have a restriction from the remote server: one
request at a time. I could make synchronous XMLHTTPRequests , but it will
froze the application.

So, I thought of a "tunnel" function that could work as a
synchronization point, where i build a queue of request and dispatch one
at a time. This way, the impact in the rest of the code is minimal.

Feb 16 '06 #9
RobG wrote:
UnaCoder wrote:
Well I thought there was and I researched java script to see if you can
invoke a string containing java script code. the solution that seemed
intuitive would be to do something like:

function Tunnel() {
function_name= arguments[0];
arguments.shift (); args = arguments.join( );
eval function_name + "(" + args + ");";
}

I didn't put any error checking in there, or test that code, but as far
as I know that should work =)
Arguments is not an array, it's just a list

s/list/(Object) object/
with a few other properties that make it look a bit like an array.
Consequently, it doesn't have split() or join() methods (and I don't
think you can add them to its prototype).

Since `arguments' inherits directly from Object (ECMASCript 3 Final,
10.1.8), it is possible to add them, e.g.:

Object.prototyp e.join = function(delim)
{
var a = [];

for (var i = 0, len = this.length; i < len; i++)
{
a.push(this[i]);
}

return a.join(delim);
}

However, it is also an Object object without the ReadOnly attribute, so you

arguments.join = function(delim)
{
/* see above */
}

The second approach would work for only one execution context, though, as
the `arguments' object is (re-)created and initialized every time control
enters an execution context for function code.

I have tested both approaches positive in Mozilla/5.0 (X11; U; Linux i686;
en-US; rv:1.8) Gecko/20060110 Debian/1.5.dfsg-4 Firefox/1.5.
PointedEars
Feb 16 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.