8

I was looking into building a toolset using google apps script. The problem with this is that as far as I can tell in only allows one level of organization. You can create a Library called Stopwatch and call methods Stopwatch.start() and Stopwatch.stop() which is pretty cool.

What I had in mind though was something more like Utils.Stopwatch().start() and Utils.Timer.start() etc. I think it's certainly possible in javascript, but in order to keep breaking Apps Script autocomplete function it needs to be added in a certain format. Below is example an example of doing it wrong (gives an error) but perhaps saves some time. It's based on this article.

/**
* A stopwatch object.
* @return {Object} The stopwatch methods
*/
function Stopwatch() 
{
  var current;

  /**
  * Stop the stopwatch.
  * @param {Time} time in miliseconds
  */
  function timeInSeconds_(time)
  {
    return time/1000;
  }

  return 
    {
      /**
      * Start the stopwatch.
      */
      start: function() 
      {
        var time = new Date().getTime();
        current = timeInSeconds_(time);
      },

      /**
      * Stop the stopwatch.
      * @return {decimal} time passed since calling 
      *    start (in seconds)
      */
      stop: function() 
      {
        var time = new Date().getTime();
        var difference = timeInSeconds_(time) - this.current;
        return difference.toFixed(3);
      }
    };
}

Thanks

Rubén
  • 34,714
  • 9
  • 70
  • 166
M. Oranje
  • 781
  • 5
  • 13

4 Answers4

4

Until such functionality is natively supported by Google you can define empty functions with annotations on the same level as your constructor function. You can even keep your original code structure. This would enable auto-complete in the editor. Plus you'll get auto-generated documentation for your library, e.g. https://script.google.com/macros/library/versions/d/YOUR_PROJECT_KEY

Example:

/**
* Constructor.
* @constructor
* @param {String} apiKey Doxument API key
* @param {String} apiToken Doxument API token
*/    
function DoxumentApi(apiKey, apiToken) {
  // public api
  return {
        get: function(id, params) {
          var httpResponse = execute('/docs/' + id + '.json?' + buildQuery(params));
          return parse(httpResponse);
        }
    }
}

/**
* Get document record.
* @param {String} id document id
* @param {Object=} params optional. extra get params
* @return {Object} Document object
*/    
function get(id, params) {}
  • 2
    This would autocomplete the method only on top level, not on the sublevel where the mothods are defined. For my example it should be Tools.Stopwatch().start() instead of Tools.start(). – M. Oranje Sep 17 '12 at 09:37
3

You can submit feature requests here:

http://code.google.com/p/google-apps-script-issues/issues/list

eddyparkinson
  • 3,680
  • 4
  • 26
  • 52
  • Perhaps I could, I'm not really sure whether this is something other people would find useful though. It might just be expecting too much. – M. Oranje Jun 05 '12 at 22:59
  • 6
    I created a bug report http://code.google.com/p/google-apps-script-issues/issues/detail?id=1389&thanks=1389&ts=1338940848 – Eduardo Jun 06 '12 at 00:01
2

It doesn't work yet but the team does know about it. Until then you will need to document your libraries on a site. I guess you could also put the methods in the description. It really is a great start for the new service but I was with you about 5 minutes in and already wanting more. ;)

James Ferreira
  • 316
  • 1
  • 2
  • 11
0

What about using OO?

It look very well organized and it's easy to document.

/**
 * A stopwatch Class.
 *
 * @constructor
 */
function Stopwatch() {
  this.current =  new Date().getTime();
}

/**
 * Starts the stopwatch
 */
Stopwatch.prototype.start = function(){
  this.current = new Date().getTime();
};

/**
 * Stops the stopwatch
 *
 * @return {number} Number of seconds since Stopwatch was started
 */
Stopwatch.prototype.stop = function(){
  return ((new Date().getTime()) - this.current) / 1000;
};

Example. In case your lib is imported as Utils.

var s = new Utils.Stopwatch();
s.start();

// (...) 

Logger.log(s.stop());

PS: This is untested code.

As a side effect you could have multiple Stopwatches, each one maintaining it's own local variable current

UPDATE

Although this is correctly documented following JSDoc it currently doesn't autocomplete the methods with Google Apps Script.

Eduardo
  • 22,574
  • 11
  • 76
  • 94
  • The code runs (and is more compact as well) but this breaks the way the Apps Script libraries work. To have the autocomplete version working there you define a keyword that Apps Script connects to the library. An example would be: `// For 'Utils' Utlis.Stopwatch().start()` – M. Oranje Jun 05 '12 at 22:47
  • Sorry I edited too many times and had to wait.. The rest `var time = Utlis.Stopwatch().stop()` There is a nice article about it here: [link](http://googleappsdeveloper.blogspot.com/feeds/posts/default) I gather you are aware of the above, what I mean is that 's.start()' or 'Utils.Stopwatch().start()' for that matter, aren't picked up by the autocomplete function. Only the keyword and one function down. If you can get the start() method to autocomplete, you have solved my problem :) @Eduardo – M. Oranje Jun 05 '12 at 23:19
  • You're right using OO doesn't autocomplete in Google Apps Script – Eduardo Jun 05 '12 at 23:35