Loading ...
Sorry, an error occurred while loading the content.

Calling With Too Much Parameters

Expand Messages
  • Jean-Charles Meyrignac
    I just discovered a bug in a Firefox plugin, and the bug was that a routine using 3 parameters was called with 4 parameters. So I did a little test with
    Message 1 of 8 , Aug 10, 2010
    • 0 Attachment
      I just discovered a bug in a Firefox plugin, and the bug was that a routine
      using 3 parameters was called with 4 parameters.

      So I did a little test with jslint:
      function test(a,b,c)
      {
      return a+b+c;
      }

      test(1,2,3,4);

      Shouldn't JsLint send a warning on this ?

      JC


      [Non-text portions of this message have been removed]
    • pauanyu
      Don t forget that it s possible to access the non-named parameters using the arguments object. I suppose if the function does not access the arguments
      Message 2 of 8 , Aug 10, 2010
      • 0 Attachment
        Don't forget that it's possible to access the non-named parameters using the "arguments" object.

        I suppose if the function does not access the arguments object, then throwing a warning or error in that case might be nice.

        In any case, if the function is called with more arguments than it expects, it simply ignores the excess. I'm not sure why that would cause a bug in the plugin.

        --- In jslint_com@yahoogroups.com, Jean-Charles Meyrignac <jcmeyrignac@...> wrote:
        >
        > I just discovered a bug in a Firefox plugin, and the bug was that a routine
        > using 3 parameters was called with 4 parameters.
        >
        > So I did a little test with jslint:
        > function test(a,b,c)
        > {
        > return a+b+c;
        > }
        >
        > test(1,2,3,4);
        >
        > Shouldn't JsLint send a warning on this ?
        >
        > JC
        >
        >
        > [Non-text portions of this message have been removed]
        >
      • Jean-Charles Meyrignac
        ... And the routine was declared with (url, server, callback), with server = {login, password} So password was used instead of callback . It seems that a
        Message 3 of 8 , Aug 10, 2010
        • 0 Attachment
          On Wed, Aug 11, 2010 at 7:49 AM, pauanyu <pcxunlimited@...> wrote:

          >
          >
          > Don't forget that it's possible to access the non-named parameters using
          > the "arguments" object.
          >
          > Thanks, I forgot that.


          > I suppose if the function does not access the arguments object, then
          > throwing a warning or error in that case might be nice.
          >
          > A warning is enough, and would help locating weird calls.


          > In any case, if the function is called with more arguments than it expects,
          > it simply ignores the excess. I'm not sure why that would cause a bug in the
          > plugin.
          >
          > The routine was called with arguments (url, login, password, callback).
          And the routine was declared with (url, server, callback), with server =
          {login, password}
          So 'password' was used instead of 'callback'.
          It seems that a refactoring gone wrong..

          JC


          [Non-text portions of this message have been removed]
        • Rob Richardson
          This is totally valid (albeit confusing): var f = function () { // FRAGILE: Error check arguments.length and resulting vars for presence of value before using
          Message 4 of 8 , Aug 11, 2010
          • 0 Attachment
            This is totally valid (albeit confusing):

            var f = function () {
            // FRAGILE: Error check arguments.length and resulting vars for presence of
            value before using
            var a = arguments[0];
            var b = arguments[1];
            ...
            }

            A function like this could correctly be called in all these cases:

            f(1,2,3,4,5);

            f(1,2,3);

            f({a: 1, b: 2, c: 3});

            f();

            The jQuery UI suite uses this technique a lot -- optionally pass in a settings
            initialization object on first run, pass in a setting name and get back the
            current value, pass in a setting name and a new value to set it. The main
            jQuery framework also uses this technique a lot.

            I like the idea of JSLint knowing that a function was called with a different
            number of arguments than it accepts or with arguments that don't match the
            definition, but because function overloading is a standard API development
            technique, I can see it easily becoming more distracting than helpful. If it
            could also parse my docs and validate usages match my intent ... and drive my
            car and clean my kitchen and read my mind. :D It seems a carefully built set
            of unit tests that run on each commit better accounts for potential mistakes in
            this arena.

            Rob


            ________________________________
            From: Jean-Charles Meyrignac <jcmeyrignac@...>
            To: jslint_com@yahoogroups.com
            Sent: Tue, August 10, 2010 11:57:59 PM
            Subject: Re: [jslint] Re: Calling With Too Much Parameters


            On Wed, Aug 11, 2010 at 7:49 AM, pauanyu <pcxunlimited@...> wrote:

            >
            >
            > Don't forget that it's possible to access the non-named parameters using
            > the "arguments" object.
            >
            > Thanks, I forgot that.

            > I suppose if the function does not access the arguments object, then
            > throwing a warning or error in that case might be nice.
            >
            > A warning is enough, and would help locating weird calls.

            > In any case, if the function is called with more arguments than it expects,
            > it simply ignores the excess. I'm not sure why that would cause a bug in the
            > plugin.
            >
            > The routine was called with arguments (url, login, password, callback).
            And the routine was declared with (url, server, callback), with server =
            {login, password}
            So 'password' was used instead of 'callback'.
            It seems that a refactoring gone wrong..

            JC
          • pauanyu
            Just one question... how is that function any different from this one? var f = function (a, b) { // ... };
            Message 5 of 8 , Aug 12, 2010
            • 0 Attachment
              Just one question... how is that function any different from this one?

              var f = function (a, b) {
              // ...
              };

              --- In jslint_com@yahoogroups.com, Rob Richardson <erobrich@...> wrote:
              >
              > This is totally valid (albeit confusing):
              >
              > var f = function () {
              > // FRAGILE: Error check arguments.length and resulting vars for presence of
              > value before using
              > var a = arguments[0];
              > var b = arguments[1];
              > ...
              > }
              >
              > A function like this could correctly be called in all these cases:
              >
              > f(1,2,3,4,5);
              >
              > f(1,2,3);
              >
              > f({a: 1, b: 2, c: 3});
              >
              > f();
              >
              > The jQuery UI suite uses this technique a lot -- optionally pass in a settings
              > initialization object on first run, pass in a setting name and get back the
              > current value, pass in a setting name and a new value to set it. The main
              > jQuery framework also uses this technique a lot.
              >
              > I like the idea of JSLint knowing that a function was called with a different
              > number of arguments than it accepts or with arguments that don't match the
              > definition, but because function overloading is a standard API development
              > technique, I can see it easily becoming more distracting than helpful. If it
              > could also parse my docs and validate usages match my intent ... and drive my
              > car and clean my kitchen and read my mind. :D It seems a carefully built set
              > of unit tests that run on each commit better accounts for potential mistakes in
              > this arena.
              >
              > Rob
              >
              >
              > ________________________________
              > From: Jean-Charles Meyrignac <jcmeyrignac@...>
              > To: jslint_com@yahoogroups.com
              > Sent: Tue, August 10, 2010 11:57:59 PM
              > Subject: Re: [jslint] Re: Calling With Too Much Parameters
              >
              >
              > On Wed, Aug 11, 2010 at 7:49 AM, pauanyu <pcxunlimited@...> wrote:
              >
              > >
              > >
              > > Don't forget that it's possible to access the non-named parameters using
              > > the "arguments" object.
              > >
              > > Thanks, I forgot that.
              >
              > > I suppose if the function does not access the arguments object, then
              > > throwing a warning or error in that case might be nice.
              > >
              > > A warning is enough, and would help locating weird calls.
              >
              > > In any case, if the function is called with more arguments than it expects,
              > > it simply ignores the excess. I'm not sure why that would cause a bug in the
              > > plugin.
              > >
              > > The routine was called with arguments (url, login, password, callback).
              > And the routine was declared with (url, server, callback), with server =
              > {login, password}
              > So 'password' was used instead of 'callback'.
              > It seems that a refactoring gone wrong..
              >
              > JC
              >
            • Rob Richardson
              Imagine a function whose body looked like so: var f = function () { var option = {}; // Options stored in a stateful mechanism if ( arguments.length === 2 &&
              Message 6 of 8 , Aug 13, 2010
              • 0 Attachment
                Imagine a function whose body looked like so:

                var f = function () {
                var option = {}; // Options stored in a stateful mechanism

                if ( arguments.length === 2 && typeof(arguments[0]) === 'string' ) {
                // Called as f("setting",value);
                option[arguments[0]] = arguments[1];
                return;
                }

                if ( arguments.length === 1 && typeof(arguments[0]) === 'string' ) {
                // Called as f("setting");
                return option[arguments[0]];
                }

                if ( arguments.length === 0 ) {
                // Called as f();
                option.init();
                return;
                }

                // Other implementations here

                throw {
                message: "You called this function incorrectly",
                arguments: arguments
                };
                }

                Rob

                ________________________________
                From: pauanyu <pcxunlimited@...>
                To: jslint_com@yahoogroups.com
                Sent: Thu, August 12, 2010 8:36:50 PM
                Subject: [jslint] Re: Calling With Too Much Parameters


                Just one question... how is that function any different from this one?

                var f = function (a, b) {
                // ...
                };

                --- In jslint_com@yahoogroups.com, Rob Richardson <erobrich@...> wrote:
                >
                > This is totally valid (albeit confusing):
                >
                > var f = function () {
                > // FRAGILE: Error check arguments.length and resulting vars for presence of


                > value before using
                > var a = arguments[0];
                > var b = arguments[1];
                > ...
                > }
                >
                > A function like this could correctly be called in all these cases:
                >
                > f(1,2,3,4,5);
                >
                > f(1,2,3);
                >
                > f({a: 1, b: 2, c: 3});
                >
                > f();
                >
                > The jQuery UI suite uses this technique a lot -- optionally pass in a settings


                > initialization object on first run, pass in a setting name and get back the
                > current value, pass in a setting name and a new value to set it. The main
                > jQuery framework also uses this technique a lot.
                >
                > I like the idea of JSLint knowing that a function was called with a different
                > number of arguments than it accepts or with arguments that don't match the
                > definition, but because function overloading is a standard API development
                > technique, I can see it easily becoming more distracting than helpful. If it
                > could also parse my docs and validate usages match my intent ... and drive my
                > car and clean my kitchen and read my mind. :D It seems a carefully built set

                > of unit tests that run on each commit better accounts for potential mistakes in
                >
                > this arena.
                >
                > Rob
                >
                >
                > ________________________________
                > From: Jean-Charles Meyrignac <jcmeyrignac@...>
                > To: jslint_com@yahoogroups.com
                > Sent: Tue, August 10, 2010 11:57:59 PM
                > Subject: Re: [jslint] Re: Calling With Too Much Parameters
                >
                >
                > On Wed, Aug 11, 2010 at 7:49 AM, pauanyu <pcxunlimited@...> wrote:
                >
                > >
                > >
                > > Don't forget that it's possible to access the non-named parameters using
                > > the "arguments" object.
                > >
                > > Thanks, I forgot that.
                >
                > > I suppose if the function does not access the arguments object, then
                > > throwing a warning or error in that case might be nice.
                > >
                > > A warning is enough, and would help locating weird calls.
                >
                > > In any case, if the function is called with more arguments than it expects,
                > > it simply ignores the excess. I'm not sure why that would cause a bug in the
                > > plugin.
                > >
                > > The routine was called with arguments (url, login, password, callback).
                > And the routine was declared with (url, server, callback), with server =
                > {login, password}
                > So 'password' was used instead of 'callback'.
                > It seems that a refactoring gone wrong..
                >
                > JC
              • pauanyu
                Yeah, I get the idea. But couldn t that function be written like this, with the same effect? var f = function (key, value) { var option = {}; // Options stored
                Message 7 of 8 , Aug 14, 2010
                • 0 Attachment
                  Yeah, I get the idea. But couldn't that function be written like this, with the same effect?


                  var f = function (key, value) {
                  var option = {}; // Options stored in a stateful mechanism

                  if (arguments.length === 2 && typeof key === 'string') {
                  // Called as f("setting", value);
                  option[key] = value;
                  return;
                  }

                  if (arguments.length === 1 && typeof key === 'string') {
                  // Called as f("setting");
                  return option[key];
                  }

                  if (arguments.length === 0) {
                  // Called as f();
                  option.init();
                  return;
                  }

                  // Other implementations here

                  throw {
                  message: "You called this function incorrectly",
                  arguments: arguments
                  };
                  };


                  --- In jslint_com@yahoogroups.com, Rob Richardson <erobrich@...> wrote:
                  >
                  > Imagine a function whose body looked like so:
                  >
                  > var f = function () {
                  > var option = {}; // Options stored in a stateful mechanism
                  >
                  > if ( arguments.length === 2 && typeof(arguments[0]) === 'string' ) {
                  > // Called as f("setting",value);
                  > option[arguments[0]] = arguments[1];
                  > return;
                  > }
                  >
                  > if ( arguments.length === 1 && typeof(arguments[0]) === 'string' ) {
                  > // Called as f("setting");
                  > return option[arguments[0]];
                  > }
                  >
                  > if ( arguments.length === 0 ) {
                  > // Called as f();
                  > option.init();
                  > return;
                  > }
                  >
                  > // Other implementations here
                  >
                  > throw {
                  > message: "You called this function incorrectly",
                  > arguments: arguments
                  > };
                  > }
                  >
                  > Rob
                  >
                  > ________________________________
                  > From: pauanyu <pcxunlimited@...>
                  > To: jslint_com@yahoogroups.com
                  > Sent: Thu, August 12, 2010 8:36:50 PM
                  > Subject: [jslint] Re: Calling With Too Much Parameters
                  >
                  >
                  > Just one question... how is that function any different from this one?
                  >
                  > var f = function (a, b) {
                  > // ...
                  > };
                  >
                  > --- In jslint_com@yahoogroups.com, Rob Richardson <erobrich@> wrote:
                  > >
                  > > This is totally valid (albeit confusing):
                  > >
                  > > var f = function () {
                  > > // FRAGILE: Error check arguments.length and resulting vars for presence of
                  >
                  >
                  > > value before using
                  > > var a = arguments[0];
                  > > var b = arguments[1];
                  > > ...
                  > > }
                  > >
                  > > A function like this could correctly be called in all these cases:
                  > >
                  > > f(1,2,3,4,5);
                  > >
                  > > f(1,2,3);
                  > >
                  > > f({a: 1, b: 2, c: 3});
                  > >
                  > > f();
                  > >
                  > > The jQuery UI suite uses this technique a lot -- optionally pass in a settings
                  >
                  >
                  > > initialization object on first run, pass in a setting name and get back the
                  > > current value, pass in a setting name and a new value to set it. The main
                  > > jQuery framework also uses this technique a lot.
                  > >
                  > > I like the idea of JSLint knowing that a function was called with a different
                  > > number of arguments than it accepts or with arguments that don't match the
                  > > definition, but because function overloading is a standard API development
                  > > technique, I can see it easily becoming more distracting than helpful. If it
                  > > could also parse my docs and validate usages match my intent ... and drive my
                  > > car and clean my kitchen and read my mind. :D It seems a carefully built set
                  >
                  > > of unit tests that run on each commit better accounts for potential mistakes in
                  > >
                  > > this arena.
                  > >
                  > > Rob
                  > >
                  > >
                  > > ________________________________
                  > > From: Jean-Charles Meyrignac <jcmeyrignac@>
                  > > To: jslint_com@yahoogroups.com
                  > > Sent: Tue, August 10, 2010 11:57:59 PM
                  > > Subject: Re: [jslint] Re: Calling With Too Much Parameters
                  > >
                  > >
                  > > On Wed, Aug 11, 2010 at 7:49 AM, pauanyu <pcxunlimited@> wrote:
                  > >
                  > > >
                  > > >
                  > > > Don't forget that it's possible to access the non-named parameters using
                  > > > the "arguments" object.
                  > > >
                  > > > Thanks, I forgot that.
                  > >
                  > > > I suppose if the function does not access the arguments object, then
                  > > > throwing a warning or error in that case might be nice.
                  > > >
                  > > > A warning is enough, and would help locating weird calls.
                  > >
                  > > > In any case, if the function is called with more arguments than it expects,
                  > > > it simply ignores the excess. I'm not sure why that would cause a bug in the
                  > > > plugin.
                  > > >
                  > > > The routine was called with arguments (url, login, password, callback).
                  > > And the routine was declared with (url, server, callback), with server =
                  > > {login, password}
                  > > So 'password' was used instead of 'callback'.
                  > > It seems that a refactoring gone wrong..
                  > >
                  > > JC
                  >
                • Rob Richardson
                  Yes, until one of the implementations looked like this: if (arguments.length === 1 && typeof(arguments[0]) === object ) { var arg = arguments[0]; // TODO:
                  Message 8 of 8 , Aug 16, 2010
                  • 0 Attachment
                    Yes, until one of the implementations looked like this:

                    if (arguments.length === 1 && typeof(arguments[0]) === 'object') {
                    var arg = arguments[0]; // TODO: move var definition to the top
                    if (arg.length && arg.length > 0) {
                    // ASSUME: Array
                    for ( var i = 0; i < arg.length; i++ ) {
                    option.arrayelem[i] = arg[i];
                    }
                    } else {
                    // ASSUME: Object
                    for ( var prop in arg ) {
                    if ( arg.hasOwnProperty(prop) ) {
                    option[prop] = arg[prop];
                    }
                    }
                    }
                    return;
                    }

                    ... yeah, I'll grant you could swap this to be:

                    ...
                    var arg = key;
                    ...

                    But in this case you couldn't:

                    if (arguments.length > 2) {
                    // ASSUME: they passed in the array as items instead of as an array
                    var arg = Array.prototype.slice.call(arguments); // TODO: move var
                    definition to the top
                    for ( var i = 0; i < arg.length; i++ ) {
                    option.arrayelem[i] = arg[i];
                    }
                    }

                    The dilemma is that because the contract for this function is so diverse in
                    number and type of arguments passed, sometimes it's just easier to define the
                    function with no input parameters and use the arguments (fake) array to parse
                    out what you're trying to do instead. Because the arguments array is always
                    available, I can't just look at the function definition and the caller and
                    positively identify you called me in a way I didn't expect. And because
                    different implementations may use more or less arguments in the function, I
                    can't from a static analysis point of view know that you called me with too many
                    or too few arguments or the incorrect data type(s) to match the implementation
                    you were looking for. ... or rather if you figure out a good way to do it, I'll
                    sign up. Thus far, I've only been able to prove this by unit test.

                    Rob

                    ________________________________
                    From: pauanyu <pcxunlimited@...>
                    To: jslint_com@yahoogroups.com
                    Sent: Sat, August 14, 2010 4:15:39 AM
                    Subject: [jslint] Re: Calling With Too Much Parameters


                    Yeah, I get the idea. But couldn't that function be written like this, with the
                    same effect?

                    var f = function (key, value) {
                    var option = {}; // Options stored in a stateful mechanism

                    if (arguments.length === 2 && typeof key === 'string') {
                    // Called as f("setting", value);
                    option[key] = value;
                    return;
                    }

                    if (arguments.length === 1 && typeof key === 'string') {
                    // Called as f("setting");
                    return option[key];
                    }

                    if (arguments.length === 0) {
                    // Called as f();
                    option.init();
                    return;
                    }

                    // Other implementations here

                    throw {
                    message: "You called this function incorrectly",
                    arguments: arguments
                    };
                    };

                    --- In jslint_com@yahoogroups.com, Rob Richardson <erobrich@...> wrote:
                    >
                    > Imagine a function whose body looked like so:
                    >
                    > var f = function () {
                    > var option = {}; // Options stored in a stateful mechanism
                    >
                    > if ( arguments.length === 2 && typeof(arguments[0]) === 'string' ) {
                    > // Called as f("setting",value);
                    > option[arguments[0]] = arguments[1];
                    > return;
                    > }
                    >
                    > if ( arguments.length === 1 && typeof(arguments[0]) === 'string' ) {
                    > // Called as f("setting");
                    > return option[arguments[0]];
                    > }
                    >
                    > if ( arguments.length === 0 ) {
                    > // Called as f();
                    > option.init();
                    > return;
                    > }
                    >
                    > // Other implementations here
                    >
                    > throw {
                    > message: "You called this function incorrectly",
                    > arguments: arguments
                    > };
                    > }
                    >
                    > Rob
                    >
                    > ________________________________
                    > From: pauanyu <pcxunlimited@...>
                    > To: jslint_com@yahoogroups.com
                    > Sent: Thu, August 12, 2010 8:36:50 PM
                    > Subject: [jslint] Re: Calling With Too Much Parameters
                    >
                    >
                    > Just one question... how is that function any different from this one?
                    >
                    > var f = function (a, b) {
                    > // ...
                    > };
                    >
                    > --- In jslint_com@yahoogroups.com, Rob Richardson <erobrich@> wrote:
                    > >
                    > > This is totally valid (albeit confusing):
                    > >
                    > > var f = function () {
                    > > // FRAGILE: Error check arguments.length and resulting vars for presence
                    >of
                    >
                    >
                    >
                    > > value before using
                    > > var a = arguments[0];
                    > > var b = arguments[1];
                    > > ...
                    > > }
                    > >
                    > > A function like this could correctly be called in all these cases:
                    > >
                    > > f(1,2,3,4,5);
                    > >
                    > > f(1,2,3);
                    > >
                    > > f({a: 1, b: 2, c: 3});
                    > >
                    > > f();
                    > >
                    > > The jQuery UI suite uses this technique a lot -- optionally pass in a
                    >settings
                    >
                    >
                    >
                    > > initialization object on first run, pass in a setting name and get back the
                    > > current value, pass in a setting name and a new value to set it. The main
                    > > jQuery framework also uses this technique a lot.
                    > >
                    > > I like the idea of JSLint knowing that a function was called with a different
                    >
                    >
                    > > number of arguments than it accepts or with arguments that don't match the
                    > > definition, but because function overloading is a standard API development
                    > > technique, I can see it easily becoming more distracting than helpful. If it
                    >
                    >
                    > > could also parse my docs and validate usages match my intent ... and drive my
                    >
                    >
                    > > car and clean my kitchen and read my mind. :D It seems a carefully built
                    >set
                    >
                    >
                    > > of unit tests that run on each commit better accounts for potential mistakes

                    >in
                    >
                    > >
                    > > this arena.
                    > >
                    > > Rob
                    > >
                    > >
                    > > ________________________________
                    > > From: Jean-Charles Meyrignac <jcmeyrignac@>
                    > > To: jslint_com@yahoogroups.com
                    > > Sent: Tue, August 10, 2010 11:57:59 PM
                    > > Subject: Re: [jslint] Re: Calling With Too Much Parameters
                    > >
                    > >
                    > > On Wed, Aug 11, 2010 at 7:49 AM, pauanyu <pcxunlimited@> wrote:
                    > >
                    > > >
                    > > >
                    > > > Don't forget that it's possible to access the non-named parameters using
                    > > > the "arguments" object.
                    > > >
                    > > > Thanks, I forgot that.
                    > >
                    > > > I suppose if the function does not access the arguments object, then
                    > > > throwing a warning or error in that case might be nice.
                    > > >
                    > > > A warning is enough, and would help locating weird calls.
                    > >
                    > > > In any case, if the function is called with more arguments than it
                    expects,
                    > > > it simply ignores the excess. I'm not sure why that would cause a bug in
                    >the
                    > > > plugin.
                    > > >
                    > > > The routine was called with arguments (url, login, password, callback).
                    > > And the routine was declared with (url, server, callback), with server =
                    > > {login, password}
                    > > So 'password' was used instead of 'callback'.
                    > > It seems that a refactoring gone wrong..
                    > >
                    > > JC
                    >
                  Your message has been successfully submitted and would be delivered to recipients shortly.