Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Javascript (http://www.velocityreviews.com/forums/f68-javascript.html)
-   -   function and arguments as aguments (http://www.velocityreviews.com/forums/t923016-function-and-arguments-as-aguments.html)

Telmo Costa 02-15-2006 05:42 PM

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.length; i++) sum += arguments[i];
alert(sum);
};

// 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

UnaCoder 02-15-2006 08:41 PM

Re: function and arguments as aguments
 
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


Telmo Costa 02-15-2006 09:16 PM

Re: function and arguments as aguments
 
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
;) ).


UnaCoder 02-15-2006 10:01 PM

Re: function and arguments as aguments
 
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 =)


Michael Winter 02-15-2006 10:08 PM

Re: function and arguments as aguments
 
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.prototype.apply
method.

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

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

alert(tunnel(sum, 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.prototype.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.

Telmo Costa 02-16-2006 12:41 AM

Re: function and arguments as aguments
 
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.




RobG 02-16-2006 02:16 AM

Re: function and arguments as aguments
 
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

RobG 02-16-2006 02:19 AM

Re: function and arguments as aguments
 
Telmo Costa wrote:
> Hi. I have the following code:
>
> --------------------------------------
> function Tunnel() {
> //arguments[0](???);
> }
>
> function Sum() {
> var sum = 0;
> for (i=0; i<arguments.length; i++) sum += arguments[i];
> alert(sum);
> };
>
> // 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?


How about:

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.length; i<len; ++i) {
ar[ar.length] = arguments[i];
}
return this[funcName](ar);
}

alert(tunnel('sum', 1, 2, 3, 4)); /* 10 */
alert(tunnel('product', 1, 2, 3, 4)); /* 24 */


Note that the function (e.g. sum) name needs to be passed as a string.


--
Rob

Telmo Costa 02-16-2006 01:46 PM

Re: function and arguments as aguments
 
>
> How about:
>
> 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.length; i<len; ++i) {
> ar[ar.length] = arguments[i];
> }
> return this[funcName](ar);
> }
>
> alert(tunnel('sum', 1, 2, 3, 4)); /* 10 */
> alert(tunnel('product', 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.




Thomas 'PointedEars' Lahn 02-16-2006 05:29 PM

Re: function and arguments as aguments
 
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.prototype.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
can add the methods to it instead, e.g.

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


All times are GMT. The time now is 01:01 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.