[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

【项目1】批处理函数库调用接口的约定

本帖最后由 lllsoslll 于 2012-6-1 18:53 编辑

走自己的路, 让别人紧随其后。。。
如题,本贴主要讨论:
           子过程(函数)调用接口的多样化问题,
      目的:
           为接口约定一个标准, 方便使用者调用和编写者高效实现;
SOS --- >> lllsoslll@163.com

实在没办法的话,为了兼顾可读性和兼容性最大化,只好用临时文件了
  1. set>"%tmp%\var.$"&endlocal
  2. for /f "eol==delims=" %%a in ("%tmp%\var.$") do set "%%a"
  3. del "%tmp%\var.$"
复制代码

TOP

回复 33# CrLf


是个问题, 研究下。。

TOP

讨论了那么多年都没开始写,符合我党作风。

TOP

回32楼和33楼
感觉为了通用性过多的牺牲了简洁性
而复杂性的提升往往意味着可读性的下降
同时也意味着健壮性的下降

就楼上所讨论的set保存变量来说
虽然它存在种种的不足和缺陷
但它仍然是绝对主流的用例
因为它简洁易懂而且能处理大多数情形
对于某些特殊性的场合
建议调用者区别对待

另外刚从cndos的备份站点中看到了函数库的讨论帖
很老了但仍然有借鉴意义
http://cndos.fam.cx/forum/viewthread.php?tid=38969&fpage=5
1

评分人数

    • CrLf: 好地方技术 + 1
天的白色影子

TOP

话说 endlocal 后保留变量面临一个很郁闷的问题,如果用户在调用函数之前已经开启了变量延迟,而需要保留的变量内容中又含 ! 号,如何避免它被解释掉?难道输出到临时文件再 set /p?可是不用 setlocal 又难保变量环境的干净——尤其是函数间互相调用的时候

TOP

回复 31# qzwqzw


    我的目的是通用性最大化,常见的方案大思路主要有 set var=%var% 和 set var=%%a 两类,但前者的通用性实在是...
1、
  1. endlocal&set var1=%var1%&set var2=%var2%
  2. rem 若含 " 等将极易致错
复制代码
2、
  1. for %%a in ($ "!var1=!var1!" "var2=!var2!") do (
  2.    if %%a==$ (endlocal) else set "%%a"
  3. )
  4. rem 遇到变量内容含 * 和 ? 则必死无疑
复制代码
3、
  1. set 换行符=^
  2. for /f "delims=" %%a in ("$!换行符!var1=!var1!!换行符!var2=!var2!") do (
  3.    if %%a==$ (endlocal) else set "%%a"
  4. )
  5. rem 个人认为比较好的方案1,但是获取换行符的那三行不容压缩和添字,难保 copy 的时候会不会出岔子(尤其是有些论坛经常会在行末添加空格)
复制代码
4、
  1. for /f "delims=" %%a in ("var1=!var1!") do (
  2.    for /f "delims=" %%b in ("var2=!var2!") do (
  3.       endlocal
  4.       set "%%b"
  5.    )
  6.    set "%%a"
  7. )
  8. rem 个人认为比较好的方案2,实际上我更喜欢方案3,但这个容易看懂,行数也可以压缩得很短
复制代码

TOP

我都觉得29楼的代码还是比较清晰简洁的
如果能把UB[ArrayName]换成ArrayName.length可读性更好些

27楼的代码可读性略有些差
没看出为什么不直接赋值而用for嵌套
而且如果v2为类似!v1!的值话
会得到意外的结果

另外思考了下标准所需要遵循的几个原则:
1、被广泛使用的用法不应该轻易改变
2、标准应用后代码的可读性不应该降低
3、无法达成大多数意见的不做约定
天的白色影子

TOP

回复 29# CrLf


有点复杂, 调用应该简洁,可读性好

TOP

本帖最后由 CrLf 于 2012-11-15 22:32 编辑

对于伪数组的构思,仅作简单示例:
  1. @echo off&setlocal enabledelayedexpansion
  2. call :setAr 1234 @#$ test
  3. echo 第2个元素 ar[1] = %ar[1]%
  4. echo;
  5. echo 最大上标 UB[ar] = %UB[ar]%
  6. echo;
  7. echo 显示“数组”中的所有元素
  8. call :listAr ar
  9. echo;
  10. pause
  11. :setAr
  12. set UB[ar]=-1
  13. for %%a in (%*) do (
  14. set /a UB[ar]+=1
  15. set "ar[!UB[ar]!]=%%a"
  16. )
  17. exit/b
  18. :listAr
  19. for /l %%a in (0 1 !UB[%1]!) do echo;!ar[%%a]!
复制代码
当然可以不定义 UB[arName],但是遍历数组时将很难兼顾通用性和效率

TOP

所谓内嵌和外置函数
你应该是指主程序内和主程序外的函数代码
我在想函数发布时都是“外置”的形式
那么是否需要一个外置变内置的过程
如果只是一两个函数当然手动可以完成
如果超过一定的数量级是否需要用程序来实现

另外外置函数是否也分为两种形式
一是每个函数一个脚本文件
这样就可以不用变内置直接简单的
以 call 函数名.cmd 的形式调用

二是功能相类的函数打包到一个库文件中
如果要调用就得将函数内置化了

返回值变量既要考虑可以快速存取
也要考虑可读性的问题
所以建议用类似$return的形式
另外需要考虑返回值何时被清空的问题
如果由调用方清空似乎有些麻烦
如果不清空那么又存在可能会引用前一个函数的返回值的情况
我能想到的办法
就是在函数内部setlocal的时候
同时将返回值先清空

入口参数没看出有什么约定的必要
如果需要传入且传出
那么由该函数在说明中单独约定就足够了
应该不需要作为整体的接口标准的一部分吧
天的白色影子

TOP

本帖最后由 CrLf 于 2012-11-16 22:21 编辑

在 endlocal 后保留变量的构思,除了含换行符的变量外应该均可兼容
  1. @echo off&setlocal enabledelayedexpansion
  2. set a=123
  3. set b=abc
  4. set c=@#$
  5. set "getEndlocal=endlocal"
  6. for %%a in (a b c) do (
  7. set "getEndlocal=(for /f "delims=" %%$ in (^!%%a^!)do !getEndlocal!&set "$_%%~a=%%$")"
  8. )
  9. echo 实际命令:
  10. echo !getEndlocal!
  11. echo;
  12. %getEndlocal%
  13. echo 执行后的效果:
  14. set $_
  15. pause
复制代码
如果写成函数就是这样(格式先随便写啦,仅作示例,回头再配合标准改写):
  1. :getEndlocal varName [varName [varName [...]]]     Ver:0.1  By:bathome-Crlf
  2. setlocal enabledelayedexpansion&set "$=endlocal"
  3. for %%a in (%*) do set "$=(for %%$ in (^!%%a^!)do !$!&set "$_%%~a=%%$")"
  4. for /f "delims=" %%a in ("!$!") do endlocal&set "getEndlocal=%%a"
  5. ::getEndlocal函数结束
复制代码

TOP

本帖最后由 plp626 于 2012-11-14 23:44 编辑

经讨论,用固定环境变量名作为函数返回值这一想法, 优势大于劣势(可维护可读性可扩展性好)

现在讨论下这个返回变量名 名字的约定,我以前用过 $_,$, ##,.... 为了给它起个合理富有意义的名字改了好多次, 现在用的是$_ ,,大家讨论约定个标准。。。
-------------------------------------------
对于入口的参数, 也得有个约定,一个入口参数什么都好说,两个三个也好说,上了10个就不好搞了
而且不少时候,入口参数 兼有传入和传出两重身份

看看大家有什么好的方法。。。使得复杂问题能够简单化解决。。。

TOP

本帖最后由 Demon 于 2012-11-14 19:34 编辑

虽不明但绝厉。

TOP

本帖最后由 CrLf 于 2012-11-14 18:52 编辑

回复 23# qzwqzw


    个人认为对于内嵌在脚本中的函数,所有东西都放进去实在有点冗杂,函数的参数接口和版本即可,具体说明在独立的使用范例脚本中注明较好。
但这样一来,内嵌函数与外置函数岂不是要使用两套标准?

TOP

返回列表