P
Patient Guy
OPINIONS WANTED
I am wondering about best design or philosophy or coding practice
regarding argument checking of functions/methods.
For example, I am making what I consider library code in a file 'dom1.js'
where I have my own extensions or wrappers to DOM Level 1 specifications.
I was coding an extension method for defined DOM 1 object Node called
isAncestralNode() in which a successive parentNode search is done up the
tree starting from a node of interest, and at each search step a
comparison is made to see if that is the node.
One of two types of comparisons is made: the caller of the method has the
choice of comparing the string value of the 'id' attribute of the compared
DOM element node, or of comparing the element node itself with another
element node passed as an argument. I show code below for the method
(which has been partially tested).
The method has 3 arguments. Arg #1 is the DOM element node from which to
start the search up the tree through the parentNode property. Arg #2 is
of one of two types: either a string with the value of the 'id' attribute
of the element node, or the object representing the DOM element node
itself. Arg #3 is a boolean type that asks the method caller to
explicitly specify the type of Arg #2 (string or object) rather than
leaving the method to implicitly determine it.
The method returns a boolean, either 'true' or 'false' to indicate whether
the node has in its ancestral tree (chain of parent nodes) the specified
node (or node id).
Now my questions:
1. Is Arg #3 really necessary to specify the type (string or object) of
Arg #2? Is it reasonable to get the method caller to explicitly state the
type of Arg #2 because it gets the coder to think about what he is doing?
Is it better to drop Arg #3 and just implicitly determine the acceptable
type and process the method?
2. Suppose that Arg #1 is of the wrong type (an object that is expected
to be of type Node.ELEMENT_NODE, but which is only inspected for being
"undefined"): what is the best way to return from the method? Return
the value 'false' even though the return is because of incorrect argument
passing and has nothing to do with the fact that the node is an ancestor
of the node of interest. Indeed it may be true that it is. So in this
case, should an exception/error be thrown, and how would one do so?
I would also appreciate opinions about how to approach argument checking
of methods/functions. For instance, I checked Arg #1 node to see ONLY if
it was undefined and not of type Node.ELEMENT_NODE. Why? Because maybe
there are (DOM) nodes which are NOT of type Node.ELEMENT_NODE and it is
still valid to do the search up the tree...or so I believe.
===== <begin code> =====
Node.prototype.isAncestralNode =
function (node, ancestorIDorNode, isArgString) {
if (typeof(node) == "undefined" || node == null)
return (false); // OR throw (TypeError); ????
if (isArgString == true && typeof(ancestorIDorNode) != "string")
return (false); // OR throw (TypeError);
for (var currentNode = node; currentNode;
currentNode = currentNode.parentNode)
if ((isArgString == true && currentNode.id === ancestorIDorNode)
||
currentNode == ancestorIDorNode)
return (true);
return (false);
};
===== <end code> =====
I am wondering about best design or philosophy or coding practice
regarding argument checking of functions/methods.
For example, I am making what I consider library code in a file 'dom1.js'
where I have my own extensions or wrappers to DOM Level 1 specifications.
I was coding an extension method for defined DOM 1 object Node called
isAncestralNode() in which a successive parentNode search is done up the
tree starting from a node of interest, and at each search step a
comparison is made to see if that is the node.
One of two types of comparisons is made: the caller of the method has the
choice of comparing the string value of the 'id' attribute of the compared
DOM element node, or of comparing the element node itself with another
element node passed as an argument. I show code below for the method
(which has been partially tested).
The method has 3 arguments. Arg #1 is the DOM element node from which to
start the search up the tree through the parentNode property. Arg #2 is
of one of two types: either a string with the value of the 'id' attribute
of the element node, or the object representing the DOM element node
itself. Arg #3 is a boolean type that asks the method caller to
explicitly specify the type of Arg #2 (string or object) rather than
leaving the method to implicitly determine it.
The method returns a boolean, either 'true' or 'false' to indicate whether
the node has in its ancestral tree (chain of parent nodes) the specified
node (or node id).
Now my questions:
1. Is Arg #3 really necessary to specify the type (string or object) of
Arg #2? Is it reasonable to get the method caller to explicitly state the
type of Arg #2 because it gets the coder to think about what he is doing?
Is it better to drop Arg #3 and just implicitly determine the acceptable
type and process the method?
2. Suppose that Arg #1 is of the wrong type (an object that is expected
to be of type Node.ELEMENT_NODE, but which is only inspected for being
"undefined"): what is the best way to return from the method? Return
the value 'false' even though the return is because of incorrect argument
passing and has nothing to do with the fact that the node is an ancestor
of the node of interest. Indeed it may be true that it is. So in this
case, should an exception/error be thrown, and how would one do so?
I would also appreciate opinions about how to approach argument checking
of methods/functions. For instance, I checked Arg #1 node to see ONLY if
it was undefined and not of type Node.ELEMENT_NODE. Why? Because maybe
there are (DOM) nodes which are NOT of type Node.ELEMENT_NODE and it is
still valid to do the search up the tree...or so I believe.
===== <begin code> =====
Node.prototype.isAncestralNode =
function (node, ancestorIDorNode, isArgString) {
if (typeof(node) == "undefined" || node == null)
return (false); // OR throw (TypeError); ????
if (isArgString == true && typeof(ancestorIDorNode) != "string")
return (false); // OR throw (TypeError);
for (var currentNode = node; currentNode;
currentNode = currentNode.parentNode)
if ((isArgString == true && currentNode.id === ancestorIDorNode)
||
currentNode == ancestorIDorNode)
return (true);
return (false);
};
===== <end code> =====