function and arguments as aguments

T

Telmo Costa

Hi. I have the following code:

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

function Sum() {
var sum = 0;
for (i=0; i<arguments.length; i++) sum += arguments;
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
 
U

UnaCoder

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
 
T

Telmo Costa

UnaCoder said:
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
;) ).
 
U

UnaCoder

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 =)
 
M

Michael Winter

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);

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;
}
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
 
T

Telmo Costa

UnaCoder said:
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.
 
R

RobG

UnaCoder said:
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).
 
R

RobG

Telmo said:
Hi. I have the following code:

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

function Sum() {
var sum = 0;
for (i=0; i<arguments.length; i++) sum += arguments;
alert(sum);
};

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

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


How about:

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

var funcName = arguments[0];
var ar = [];
for (var i=1, len=arguments.length; i<len; ++i) {
ar[ar.length] = arguments;
}
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.
 
T

Telmo Costa

How about:

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

var funcName = arguments[0];
var ar = [];
for (var i=1, len=arguments.length; i<len; ++i) {
ar[ar.length] = arguments;
}
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.
 
T

Thomas 'PointedEars' Lahn

RobG said:
UnaCoder said:
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);
}

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
 
R

ron.h.hall

Thomas 'PointedEars' Lahn wrote:
[...]
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);
}

return a.join(delim);
}

[...]

But since Array.prototype.join is generic (under ECMASCript 3), it
seems you should be able to use the built-in here, given that
'arguments': has a length and "numeric" properties:

Object.prototype.join = Array.prototype.join;

../rh
 
T

Thomas 'PointedEars' Lahn

Thomas said:
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);
}

return a.join(delim);
}


But since Array.prototype.join is generic (under ECMASCript 3), it
seems you should be able to use the built-in here, given that
'arguments': has a length and "numeric" properties:

Object.prototype.join = Array.prototype.join;


Indeed. Thank you for pointing this out. When reading only

,-[ECMAScript Edition 3 Final]
|
| 15.4.4.5 Array.prototype.join (separator)
|
| The elements of the array are converted to strings, [...]
^^^^^^^^^^^^^^^^^^^^^^^^^

it is easy to overlook the following at the top of the next page
(PDF version):

| NOTE The join function is intentionally generic; it does not require that
| its `this' value be an Array object. Therefore, it can be transferred to
| other kinds of objects for use as a method. Whether the join function
| can be applied successfully to a host object is implementation-dependent.

(It should be noted *g* that there is such a NOTE for other methods of
Array.prototype too.)

The test case

Object.prototype.join = Array.prototype.join;
(function() { alert(arguments.join("x")); })(1, 2, 3); // "1x2x3"
alert({1: 2, 2: 3, length: 3}.join("x")); // "x2x3"

works in the following user agents:

- Mozilla Firefox 1.5.0.1
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.1) Gecko/20060209
Debian/1.5.dfsg+1.5.0.1-2 Firefox/1.5.0.1

- Mozilla (Suite) 1.7.12
[Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20060205
Debian/1.7.12-1.1]

- Netscape Navigator 4.8
[Mozilla/4.8 [en] (X11; U; Linux 2.6.15.1-20060130.184242+0100 i686)]

- Opera 8.51
[Opera/8.51 (X11; Linux i686; U; en)]

- Konqueror 3.5.1
[Mozilla/5.0 (compatible; Konqueror/3.5;
Linux 2.6.15.1-20060130.184242+0100; X11; i686; de, en_US)
KHTML/3.5.1 (like Gecko) (Debian package 4:3.5.1-2)]

IE, Windows, and Mac testers, it's your turn :)


PointedEars
 
R

RobG

Thomas said:
RobG wrote:

UnaCoder said:
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/

Yes, a list Object.

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

The way I read the spec was that arguments shares the Object prototype,
which is null. I concluded that you couldn't add to it - clearly an
incorrect conclusion. :-x

I'll run the test in your other post later on a few Mac OS browsers.
 
V

VK

Thomas said:
Thomas said:
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);
}

return a.join(delim);
}


But since Array.prototype.join is generic (under ECMASCript 3), it
seems you should be able to use the built-in here, given that
'arguments': has a length and "numeric" properties:

Object.prototype.join = Array.prototype.join;


Indeed. Thank you for pointing this out. When reading only

,-[ECMAScript Edition 3 Final]
|
| 15.4.4.5 Array.prototype.join (separator)
|
| The elements of the array are converted to strings, [...]
^^^^^^^^^^^^^^^^^^^^^^^^^

it is easy to overlook the following at the top of the next page
(PDF version):

| NOTE The join function is intentionally generic; it does not require that
| its `this' value be an Array object. Therefore, it can be transferred to
| other kinds of objects for use as a method. Whether the join function
| can be applied successfully to a host object is implementation-dependent.

(It should be noted *g* that there is such a NOTE for other methods of
Array.prototype too.)

The test case

Object.prototype.join = Array.prototype.join;
(function() { alert(arguments.join("x")); })(1, 2, 3); // "1x2x3"
alert({1: 2, 2: 3, length: 3}.join("x")); // "x2x3"

works in the following user agents:

- Mozilla Firefox 1.5.0.1
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.1) Gecko/20060209
Debian/1.5.dfsg+1.5.0.1-2 Firefox/1.5.0.1

- Mozilla (Suite) 1.7.12
[Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20060205
Debian/1.7.12-1.1]

- Netscape Navigator 4.8
[Mozilla/4.8 [en] (X11; U; Linux 2.6.15.1-20060130.184242+0100 i686)]

- Opera 8.51
[Opera/8.51 (X11; Linux i686; U; en)]

- Konqueror 3.5.1
[Mozilla/5.0 (compatible; Konqueror/3.5;
Linux 2.6.15.1-20060130.184242+0100; X11; i686; de, en_US)
KHTML/3.5.1 (like Gecko) (Debian package 4:3.5.1-2)]

IE, Windows, and Mac testers, it's your turn :)


It works in JScript 5.6 (IE 6.0)

For the purity of picture :) one should say that in JScript
"arguments" is an objects with non-enumerable properties "length",
"callee", "caller" and "00"..."0X"
Besides that "00"..."0N of arguments" properties are *protected* so you
can access them only by numeric index, so say arguments[1] is really an
access to the property arguments['01'] which is not accessible
otherwise. Overall it looks like HTMLCollection where scring property
access is locked. That is the reason why it is stated in docs that
"arguments is not an array despite it looks like one" (because it's
indeed not).
 
T

Thomas 'PointedEars' Lahn

RobG said:
Thomas said:
RobG said:
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/

Yes, a list Object.

There is no such thing.
The way I read the spec was that arguments shares the Object prototype,

You misunderstood it.

| 10.1.8 Arguments Object
| [...]
| * The value of the internal [[Prototype]] property of the arguments object
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| is the original Object prototype object, the one that is the initial
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| value of Object.prototype (section 15.2.3.1).

That means essentially that `arguments' is an Object object, as it
inherits directly from Object.prototype through the prototype chain.
Which makes it possible to augment Object.prototype and call its
methods with `arguments' as caller.

And since there are is no constraint for `arguments' regarding this,
it is possible, as with any Object object, to augment it directly.
Since it has been pointed out that Array.prototype.join and other
methods of Array.prototype are generic, direct augmentation is
indeed of practical value:

function x()
{
arguments.join = Array.prototype.join;
alert(arguments.join(","));
}

Only the current `arguments' object would be affected by it then,
not other Object objects. (Think about iterating through their
properties with `for..in'.)
which is null. [...]

No, fortunately it is not :) There would not be such nice properties
as `constructor' and methods as toString() otherwise. You are confusing
the prototype object and its [[Prototype]] property:

| 15.2.3.1 Object.prototype
|
| The initial value of Object.prototype is the Object prototype object
| (section 15.2.4).
|
| This property has the attributes { DontEnum, DontDelete, ReadOnly }.

The last attribute means essentially that you cannot overwrite the value of
Object.prototype with a reference to another object as that would break the
prototype chain mechanism preserved by the following:

| 15.2.4 Properties of the Object Prototype Object
|
| The value of the internal [[Prototype]] property of the Object prototype
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| object is null [...]

Hopefully this helps (you) to see the difference:

arguments.[[Prototype]] --> Object.prototype
Object.prototype --> {constructor: ..., toString: ..., ...}
Object.prototype.[[Prototype]] --> null
I'll run the test in your other post later on a few Mac OS browsers.

Thanks in advance.


Regards,
PointedEars
 
T

Thomas 'PointedEars' Lahn

VK said:
Thomas said:
The test case

Object.prototype.join = Array.prototype.join;
(function() { alert(arguments.join("x")); })(1, 2, 3); // "1x2x3"
alert({1: 2, 2: 3, length: 3}.join("x")); // "x2x3"

works in the following user agents:

- Mozilla Firefox 1.5.0.1
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.1) Gecko/20060209
Debian/1.5.dfsg+1.5.0.1-2 Firefox/1.5.0.1

- Mozilla (Suite) 1.7.12
[Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20060205
Debian/1.7.12-1.1]

- Netscape Navigator 4.8
[Mozilla/4.8 [en] (X11; U; Linux 2.6.15.1-20060130.184242+0100 i686)]

- Opera 8.51
[Opera/8.51 (X11; Linux i686; U; en)]

- Konqueror 3.5.1
[Mozilla/5.0 (compatible; Konqueror/3.5;
Linux 2.6.15.1-20060130.184242+0100; X11; i686; de, en_US)
KHTML/3.5.1 (like Gecko) (Debian package 4:3.5.1-2)]

IE, Windows, and Mac testers, it's your turn :)

It works in JScript 5.6 (IE 6.0)

OK, thanks.
For the purity of picture :) one should say that in JScript
"arguments" is an objects with non-enumerable properties "length",
"callee", "caller"

That is ECMAScript-compliant, except of the `caller' property. It is
identical to JavaScript before version 1.3. Since that version, the
latter property is only a property of the called Function object;
otherwise the implementation is identical.
and "00"..."0X"

I seriously doubt that.
Besides that "00"..."0N of arguments" properties are
protected so you can access them only by numeric index

How did you get /that/ idea anyway?
so say arguments[1] is really an access to the property arguments['01']

Most certainly it is not.
which is not accessible otherwise.

Because it does not exist. The property name is '1', not '01', as all
property names are strings and number-value names provided in bracket
property accessors are converted to string before the actual property
access occurs.
Overall it looks like HTMLCollection where scring property access
is locked.

It does not look like an HTMLCollection object at all. There is no
namedItem() and no item() method, and removing one element does not
change following key-value relationships.

"String property access" (whatever that might be) is not locked with
HTMLCollection objects. It is only that the type of the argument to
the property accessor defines which one of the methods, namedItem()
[for strings] or item() [for numbers] is actually called.

Try

arguments.join = Array.prototype.join;
alert(arguments.join(","));

If that works in function code, `arguments' is not "locked" in any way.
I am confident that this applies. So I dare say, without having tested
it in IE, assigning 42 to arguments['01'] will most certainly get you 42
for arguments['01'] but of course not for arguments['1'] or arguments[1]
in JScript, too. Because those are _different_ properties.
That is the reason why it is stated in docs that "arguments is not
an array despite it looks like one" (because it's indeed not).

That is not the reason why. The reason is that it does show certain
features of Array-ness, such as properties with numeric name and a `length'
property, but lacks others, such as the join() and split() methods. Even
with an Array object referred to by identifier `a', assigning to a['01']
would not add an element to the array.

ISTM that your problem is that you have still not understood Array objects,
and property accesses in general.

BTW, you could have trimmed your quotes.


PointedEars
 
V

VK

Thomas said:
How did you get /that/ idea anyway?

JScript 5.6 Language Reference

"arguments Object"

<quote>
You cannot explicitly create an arguments object. The arguments object
only becomes available when a function begins execution. The arguments
object of the function is not an array, but the individual arguments
are accessed the same way array elements are accessed. The index n is
actually a reference to one of the 0n properties of the arguments
object.
ISTM that your problem is that you have still not understood Array objects,
and property accesses in general.

It is mostly your problem as you still did not get that ECMAScript
specs is a technical description of an engine which is gone years ago
(NN 4.5) so the next generations could reproduce its *behavior* if they
decide so. The *real* internal mechanics mimicing a particular behavior
may have nothing in common (and often it hasn't) with the mechanics of
NN as it was in 1999.

IE does it this way, FF this way, someone else may in other way. It is
not really important *most of the time* as long as the top level
behavior seems "as spelled".
 
T

Thomas 'PointedEars' Lahn

VK said:
JScript 5.6 Language Reference

"arguments Object"

<quote>
You cannot explicitly create an arguments object. The arguments object
only becomes available when a function begins execution. The arguments
object of the function is not an array, but the individual arguments
are accessed the same way array elements are accessed. The index n is
actually a reference to one of the 0n properties of the arguments
object.
</quote>

Given your posting history, you should not even try to patronize me. This
is *obviously* a typo. It should read "0...n", for "0 to n", because it
goes on with:

| [...]
| See Also
|
| Reference
|
| 0...n Properties (JScript 5.6)
| [...]

Do I have anything more to say?
ISTM that your problem is that you have still not understood Array
objects, and property accesses in general.

It is mostly your problem as you still did not get that ECMAScript
specs is a technical description of an engine which is gone years
ago (NN 4.5) [snipped further nonsense]

Hear, hear!


PointedEars
 
M

Michael Winter

On 17/02/2006 18:42, Thomas 'PointedEars' Lahn wrote:

[snip]
| 10.1.8 Arguments Object
| [...]
| * The value of the internal [[Prototype]] property of the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| arguments object is the original Object prototype object,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| the one that is the initial value of Object.prototype
| (section 15.2.3.1).

As I've always understood the 'original Object prototype' phrase, and it
seems rather explicit, above, the arguments object may only ever have
the properties as described in 15.2.3.1. That is, because it's
[[Prototype]] property is the /original/ Object prototype object,
modifications to that prototype will not be seen with an arguments
object. The fact that some implementations do use a modified Object
prototype object is a peculiarity of those implementations.

Note that the only other use of the phrase, 'original Object prototype
object', is found in the description of the [[Construct]] property
(13.2.2) where the original Object prototype object will be used if the
prototype property of the Function object is not an object.
That means essentially that `arguments' is an Object object, as it
inherits directly from Object.prototype through the prototype chain.
Which makes it possible to augment Object.prototype and call its
methods with `arguments' as caller.

Assuming for the moment that I'm correct, that would make this statement
false: it /shouldn't/ be possible (except through extensions to the
language) to use the properties of an augmented Object prototype object.
So, whilst:

arguments.join = Array.prototype.join;
arguments.join();

and:

Array.prototype.join.call(arguments);

would be acceptable:

Object.prototype.join = Array.prototype.join;
arguments.join();

is dubious.

[snip]

A final, related note: the arguments object /is/ an Array instance in Opera.

Mike
 
R

ron.h.hall

Michael said:
On 17/02/2006 18:42, Thomas 'PointedEars' Lahn wrote:

[snip]
| 10.1.8 Arguments Object
| [...]
| * The value of the internal [[Prototype]] property of the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| arguments object is the original Object prototype object,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| the one that is the initial value of Object.prototype
| (section 15.2.3.1).

As I've always understood the 'original Object prototype' phrase, and it
seems rather explicit, above, the arguments object may only ever have
the properties as described in 15.2.3.1. That is, because it's
[[Prototype]] property is the /original/ Object prototype object,
modifications to that prototype will not be seen with an arguments
object. The fact that some implementations do use a modified Object
prototype object is a peculiarity of those implementations.

But to accept that position, 15.2.3.1:

"Object.prototype - The initial value of Object.prototype is the
Object prototype object (15.2.4)."

which also seems rather explicit, has to be reconciled. If this is not
an assignment of the original, it's a nebulous and extremely sloppy
indication that it's actually a copy or an original that's, in turn, to
remain completely pristine. Or do I misunderstand your interpretation
of how the original would remain intact?
Note that the only other use of the phrase, 'original Object prototype
object', is found in the description of the [[Construct]] property
(13.2.2) where the original Object prototype object will be used if the
prototype property of the Function object is not an object.

This, then, raises the question of what possible reason would there be
making this type of special condition of 'original inheritance only'
for these two cases. And especially in the case of a Function object
that doesn't happen to have an object as a prototype - why would
something outside the mold of all other objects being created have to
be used in this case?

It doesn't add up. The whole thing has the appearance of something that
was backed off in the production of the standard, but not completely.
In other words, it appears to me that the word 'original' should have
been removed in a couple of places, but was overlooked.

../rh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top