之前mass Framework拥有三种不同级别的处理字符串拼接的模板函数:format,tag, ejs, 现在又增加一种新的,不过它只适应于后端node.js环境中(因为在浏览器环境中,操蛋的FF会把注释全部去掉……)。它利用多行注释来模拟其他动态语言的here document。以下就是它的实现,其实是一个模块,内部依赖于lang模块的format方法。
mass.define("here_document","lang",function(){ //只允许最前面出现一个 "\*" ,只允许最后面出现一个 "*/" mass.hereDoc = function(f) { var str = f.toString(). replace(/^[^\/]+\/\*!?/, ''). replace(/\*\/[^\/]+$/, ''); if(arguments.length > 1){ arguments[0] = str; return mass.format.apply(mass,arguments) } return str } })
用法如下:
mass.require("here_document",function(){ var a = mass.hereDoc(function(){/* var bbb = "ccc" */ }); console.log(a)//输出 var bbb = "ccc" });
还支持两种形式的占位符,详见这里
mass.require("here_document",function(){ var a = mass.hereDoc(function(){/* var #{0} = "ccc" */ },"ddd"); console.log(a)//输出 var ddd = "ccc" });
一些更具体的应用。比如我的手脚架模块scaffold.js,要通过模型的名字生成相应的控制器与动作函数
for(var controller in mapper.controllers){ var object = mapper.controllers[controller]; //创建控制器 var contents = ["mass.define(\"",controller ,"_controller\",function(){\n", "\treturn {\n"] //创建动作 contents.push( object.actions.map(function(action){ return "\t\t\""+action + "\":function(){}" }).join(",\n")); contents.push("\n\t}\n });") ; createFile(path.join("app","controllers", controller +"_controller.js") ,contents.join("") ) //.... }
比如一个控制器名为comments,拥有 "index","create", "new","edit","destroy", "update", "show"这七个动作。那么它会生成一个comments_controller.js文件,里面内容为
mass.define("comments_controller",function(){ return { "index":function(){}, "create":function(){}, "new":function(){}, "edit":function(){}, "destroy":function(){}, "update":function(){}, "show":function(){} } });
但上面写不直接,换成here document是这样写的:
for(var controller in mapper.controllers){ var object = mapper.controllers[controller]; //创建控制器 var contents = mass.hereDoc(function(){/* mass.define("#{0}_controller",function(){ return { #{1} } });*/ },controller,object.actions.map(function(action){ //创建动作 return "\t\t\""+action + "\":function(){}" }).join(",\n")); createFile(path.join("app","controllers", controller +"_controller.js") ,contents ) }
在手脚架的另一处应用中,它表现得更加明显:
原来写法,需要转义
createFile('app/controllers/application_controller.js', 'before(\'protect from forgery\', function () {\n protectFromForgery(\'' + secret + '\');\n});\n')
here document的实现则是:
createFile('app/controllers/application_controller.js', mass.hereDoc(function(){/* before('protect from forgery',function(){ protectFromForgery("#{0}") }) */ },secret));
你能一眼就看出其最终输出结果,这对维护代码的人来说是福音啊!