Handling optional method parameters with Mozilla

The central focus of the bugs I have been working on over the last 2 weeks has been handling methods that take optional arguments and how to know if they have been passed. From here you can easily have code to handle setting those arguments to specific values in the event they were not passed in allowing your code to be more robust but also forgiving.

The bugs in question are the following:

Bug 698384
Bug 698385
Bug 698381

While I haven’t had a chance to do much with the third as it is slightly different, the other two are essentially done. My reviews are nearly done for them and I expect it to be over with sometime tomorrow.

The first step to making arguments in a method optional is adding the [optional] flag infront of the argument you are making optional it its IDL file.

  nsIDOMNodeIterator createNodeIterator(in nsIDOMNode root,
                                        [optional] in unsigned long whatToShow,
                                        [optional] in nsIDOMNodeFilter filter)
                                          raises(DOMException);
  nsIDOMTreeWalker   createTreeWalker(in nsIDOMNode root,
                                      [optional] in unsigned long whatToShow,
                                      [optional] in nsIDOMNodeFilter filter)
                                        raises(DOMException);

So now all users of this IDL will know that both createNodeIterator and createTreeWalker accept arguments that are optional.

While that’s a nice feature, its not particularly useful if those optional arguments are actually required to be used somewhere in the method forcing them to have a valid value at some point or another. That brings the question, how does one know if they were actually passed or not? Is there an event of some sort? Do they have default values?

No there isn’t any event associated with it. There ARE defaults but that isn’t completely reliable. For example, an optional argument of type boolean will default to false. But what if the user actually passed in false because that was the value they wanted? Well if your code was looking to see if that argument was false and taking action based on that your users would never be able to pass in false which is obviously no good.

The solution is another addition to our IDL file that will provide a useful counter for how many of the optional arguments were provided.

  [optional_argc] nsIDOMNodeIterator createNodeIterator(in nsIDOMNode root,
                                                        [optional] in unsigned long whatToShow,
                                                        [optional] in nsIDOMNodeFilter filter)
                                                          raises(DOMException);
  [optional_argc] nsIDOMTreeWalker   createTreeWalker(in nsIDOMNode root,
                                                      [optional] in unsigned long whatToShow,
                                                      [optional] in nsIDOMNodeFilter filter)
                                                        raises(DOMException);

From here all it requires is a simple addition of an argument in the language you are implementing in. For example, in the C++ implementation of this code for Mozilla you would do the following:

NS_IMETHODIMP
nsDocument::CreateNodeIterator(nsIDOMNode *aRoot,
                               PRUint32 aWhatToShow,
                               nsIDOMNodeFilter *aFilter,
                               PRUint8 aOptionalArgc,
                               nsIDOMNodeIterator **_retval)

NS_IMETHODIMP
nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
                             PRUint32 aWhatToShow,
                             nsIDOMNodeFilter *aFilter,
                             PRUint8 aOptionalArgc,
                             nsIDOMTreeWalker **_retval)

If the method has some sort of return value, you will want it to be the second last argument as Mozilla’s system expects their return value as the last argument in methods. If not then place it as the last one.

From there it’s simple. If aOptionalArgc is 0 none were given, if aOptionalArgc is 1 the first was given and if aOptionalArgc is 2 then both were given.

From there you can easily add logic to handle all the different scenarios aOptionalArgc could be and make your code very flexible!

One response to “Handling optional method parameters with Mozilla

  1. Pingback: OSD700 Release 1 – Updating the DOM « Thoughts of a programmer in training

Leave a comment