等到以后正式放到 sonatype 存储库,我得给 ArgParser 加 multi-arg 和什么 "CLI propmting" ,好好寒碜一下他们…… multi-arg 有啥好炫耀的,流解析器哪个不能做到高扩展性?ArgParser 的解析循环驱动层就支持, 开始我不打算在EDSL里设计就是因为太不合常理。 居然连 get environment varaible 都拿出来当基础 feature ,真是服气了,管得比 ParserKt 宽啊……
只有重视简洁性的代码才是最好的,只做、并做好自己该做的事。以面向对象的 SwitchParser 为核心,再利用各种动态数据结构扩充成 ArgParser;同时具备面向对象和函数式的风格,不随便滥用反射和类型推导,才是 Kotiln 代码应该有的样子;而不是见得风是得雨,看到啥结构好玩就不加考虑地去添加。懂得从用户角度考虑。
只有重视简洁性的代码才是最好的,只做、并做好自己该做的事。以面向对象的 SwitchParser 为核心,再利用各种动态数据结构扩充成 ArgParser;同时具备面向对象和函数式的风格,不随便滥用反射和类型推导,才是 Kotiln 代码应该有的样子;而不是见得风是得雨,看到啥结构好玩就不加考虑地去添加。懂得从用户角度考虑。
不过要是支持 multi-arg ,ArgParser 的表层封装内部表示就要引入不优雅性了…… Converter 只能接收 String,那么就必须把多个 String 拼成一个还能切开,只好用
还好目前而言 Arg.param 变量只是 toString 的时候用的,没有数据处理存储会用到它,这样就好办了(toString都不用改因为本来就是用空格切参数名),只需要修一下 read() 里的代码,convert 的架构是现成的…… 还真是容易啊
toString 里方括号的语义混淆了, Subcommand 也要支持…… 看来又有功能扩展要做了,还好状态机的模型不变,可扩展性就没问题。
@-argfile 也要给提示、 error message format 也要加 TextCaps 、要支持基于数组切片替换的 aliases …… unknown command 也要 open
'\u0000' 这个特殊值了…… 真麻烦啊,还必须修改解析器onPrefix的代码…… 就为了这种莫名其妙的特性还好目前而言 Arg.param 变量只是 toString 的时候用的,没有数据处理存储会用到它,这样就好办了(toString都不用改因为本来就是用空格切参数名),只需要修一下 read() 里的代码,convert 的架构是现成的…… 还真是容易啊
toString 里方括号的语义混淆了, Subcommand 也要支持…… 看来又有功能扩展要做了,还好状态机的模型不变,可扩展性就没问题。
@-argfile 也要给提示、 error message format 也要加 TextCaps 、要支持基于数组切片替换的 aliases …… unknown command 也要 open
https://github.com/duangsuse/kamet-dse/blob/master/src/main/kotlin/org/duangsuse/parserkt/argp/ArgParser.kt
https://github.com/duangsuse/kamet-dse/blob/master/src/test/kotlin/ArgParserTest.kt
https://github.com/duangsuse/kamet-dse/blob/master/src/test/kotlin/ArgParserTest.kt
GitHub
duangsuse/kamet-dse
duangsuse's rewrite for Mivik/kamet LLVM compiler. Contribute to duangsuse/kamet-dse development by creating an account on GitHub.
看到这里我就莫名觉得 ArgParser 的设计也真是牛逼,只是给每个 Arg 都加了 convert 函数式属性,就同时做到了另两个框架特殊处理的 validate 和 convert,还有什么 -v -h 这样的 "eager argument"…… 调用 SwitchParser.stop() 和 throw ParseError 不就做到了么?起那么多名词,却背离了框架所应解决问题的本心。抛弃JVM优雅性的过度封装。
duangsuse::Echo
看到这里我就莫名觉得 ArgParser 的设计也真是牛逼,只是给每个 Arg 都加了 convert 函数式属性,就同时做到了另两个框架特殊处理的 validate 和 convert,还有什么 -v -h 这样的 "eager argument"…… 调用 SwitchParser.stop() 和 throw ParseError 不就做到了么?起那么多名词,却背离了框架所应解决问题的本心。抛弃JVM优雅性的过度封装。
其实从action封装的这个角度讲,那两个框架还不如 Python 的 argparse 。人家是只用了一个 ActionContainer ,我的做法和它大致一样(只不过是静态检查的)。
也有一些框架是按 argparse module 的模式照搬的,可惜它们的其他基础部分太烂…… 而且现在的程序员,估计都喜欢搞一些花里胡哨的东西显得自己很懂、很牛逼,却忘记了自己是在解决问题,应该站在问题的角度为它服务,而不是凌驾于问题之上,刻意套用狭隘的语言特性。
真正牛逼的算法大佬从来不屑于在这种破事上费功夫,我们这些做封装的,有什么脸去炫技…… 框架只该考虑优雅地定义、实现好它的本职工作,而不是在后面的算法没啥特色的情况下硬上「高大上」的 API。
就是对自己的能力没有自信才会作这种腔调!如果真的把自己当程序的设计者,就应该有为了程序舍弃自身的觉悟才对。
也有一些框架是按 argparse module 的模式照搬的,可惜它们的其他基础部分太烂…… 而且现在的程序员,估计都喜欢搞一些花里胡哨的东西显得自己很懂、很牛逼,却忘记了自己是在解决问题,应该站在问题的角度为它服务,而不是凌驾于问题之上,刻意套用狭隘的语言特性。
真正牛逼的算法大佬从来不屑于在这种破事上费功夫,我们这些做封装的,有什么脸去炫技…… 框架只该考虑优雅地定义、实现好它的本职工作,而不是在后面的算法没啥特色的情况下硬上「高大上」的 API。
就是对自己的能力没有自信才会作这种腔调!如果真的把自己当程序的设计者,就应该有为了程序舍弃自身的觉悟才对。
因为数据结构动态类型程度过分,赋值的时序关系没注意到就容易踩很多坑…… 看来 Kotlin 的 local function 也一定不能混乱整个函数内部的代码行号和执行顺序
还是强类型语言好…… 每次 unchecked cast 都好怕的 😱
还是强类型语言好…… 每次 unchecked cast 都好怕的 😱
我觉得现在 ArgParser 仍然是有特色,但再也不有趣了。 虽然我也修复了三四个bug,但它不像以前一样鲜活灵动了。
我感觉它是黑色的,有一大片功能平常不会用到,我讨厌这种藏在阴影里的代码。
我感觉它是黑色的,有一大片功能平常不会用到,我讨厌这种藏在阴影里的代码。
duangsuse::Echo
……写了半天我自己也给绕糊涂了,ArgParse 有三种arg: flag, param, item ,但其 param 分为强类型(1~4) 与弱类型(moreArgs, resucePrefix) 两种,分别存储在 tup 和 dynamicMap 里…… 这次遇到的坑就是 dynamicMap 里存项是 T 但 tup 里就是 OM<T>,不一致啊。 改起来就超级麻烦,必须得重构了,不然不优雅性就要暴露到接口上
老实说我最开始的方案是利用 NamedMap 的动态类型,在解析可重复参数时建一个 MutableList as Any 再在下次 get as 回来(就是getOrPut)
后来才发现这是个大问题,而且用自己开始弄好的 OneOrMore 封装明明也完全可行的说……(看测试里的用例加了冗余类型参数 就怕麻烦没改 NamedMap 的型参) 不过这种框架也不好写就是了。
后来才发现这是个大问题,而且用自己开始弄好的 OneOrMore 封装明明也完全可行的说……(看测试里的用例加了冗余类型参数 就怕麻烦没改 NamedMap 的型参) 不过这种框架也不好写就是了。