2

某些 Google Apps 脚本函数(例如 Logger.log() 和 Utility.formatString())接受无限参数。

我想包装对 Logger.log() 或 Utility.formatString() 的调用,以便在最里面的函数调用中,我可以在结果字符串前面加上时间戳和我自己的文本。通常,您只会.apply将当前模块的 ags 用于该功能,但在我的测试中,这并没有按预期工作。它会导致TypeError: Cannot find default value for object. (line 14, file "Code")看起来来自java/server 端的错误。

这是我用于测试的代码。问题:

  1. 这是这些 Apps 脚本方法中的错误吗?
  2. 是否有解决方法或替代方法来实现我的目标?

如果这是一个错误,我也会将其归档在问题跟踪器跟踪器上

function testMyLogger() {
  myLogger('Testing %s %s %s', 'one', 2, 'three'); 
}

function myLogger()  {
  // do common things like prefix a timestamp to the first arg
    var logdate = Utilities.formatDate(new Date(), Session.getTimeZone(), "yyyy-MM-dd HH:mm:ss");
    arguments[0]= logdate + " " + arguments[0]; 

  Logger.log.apply(this, arguments); 
  // At the above line I get error "TypeError: Cannot find default value for object. (line 14, file "Code")"
  // but I expected '<timestamp> Testing one 2.0 three' to the log (View > Logs...)
}
4

2 回答 2

3

尝试Logger.log.apply(Logger, arguments);

于 2013-04-09T21:40:40.763 回答
2

不幸的是,这不起作用,但通常不能很好地与主机对象上的函数一起使用(有时在浏览器中也是如此)applymap然而,这个可怕的丑陋黑客会为你解决问题。将您的替换Logger.log.apply为:

for (var i = 0, arr = []; i < arguments.length; ++i)
  arr.push('arguments[' + i + ']');
eval('Logger.log(' + arr.join() + ')');

或者,如果一个人更喜欢简洁而不是可读性:

eval('Logger.log(' + [].slice.call(arguments, 0)
    .map(function(x, y){ return 'arguments[' + y + ']'; }).join() + ')');

更新

或者我们可以,你知道,只是修复错误 :)

我夸大了原始错误的严重性:call实际上apply现在可以处理应用程序脚本宿主对象上 95% 的方法,但是您碰巧遇到了当前无法使用的方法之一。不幸的是,我无法向您解释这种模式,因为我知道哪些模式可以在不参考我们内部代码的情况下工作。幸运的是,我的一位优秀同事诊断出问题并已解决。Logger.log.apply(Logger, ...)将在一两个版本中开始工作。密切关注发行说明。

于 2013-04-10T00:52:22.583 回答