设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 IT综合资讯 查看内容

数据即代码,我和我的小伙伴们都惊呆了

2013-8-11 14:17| 发布者: joejoe0332| 查看: 1520| 评论: 0|原作者: CoolShell.cn|来自: CoolShell.cn

摘要:   几个小伙伴在考虑下面这个各个语言都会遇到的问题:   问题:设计一个命令行参数解析API 一个好的命令行参数解析库一般涉及到这几个常见的方面: 1) 支持方便地生成帮助信息 2) 支持子命令,比如:git包含了pu ...

  几个小伙伴在考虑下面这个各个语言都会遇到的问题:



  问题:设计一个命令行参数解析API

一个好的命令行参数解析库一般涉及到这几个常见的方面:

1) 支持方便地生成帮助信息

2) 支持子命令,比如:git包含了push, pull, commit等多种子命令

3) 支持单字符选项、多字符选项、标志选项、参数选项等多种选项和位置参数

4) 支持选项默认值,比如:–port选项若未指定认为5037

5) 支持使用模式,比如:tar命令的-c和-x是互斥选项,属于不同的使用模式


经过一番考察,小伙伴们发现了这个几个有代表性的API设计:

1. getopt():

getopt()是libc的标准函数,很多语言中都能找到它的移植版本。

 

01//C
02while ((c = getopt(argc, argv, "ac:d:")) != -1) {
03    int this_option_optind = optind ? optind : 1;
04    switch (c) {
05    case 'a':
06        printf ("option a");
07        aopt = 1;
08        break;
09    case 'c':
10        printf ("option c with value '%s'", optarg);
11        copt = optarg;
12        break;
13    case 'd':
14        printf ("option d with value '%s'", optarg);
15        dopt = optarg;
16        break;
17    case '?':
18        break;
19    default:
20        printf ("?? getopt returned character code 0%o ??", c);
21    }
22}

getopt()的核心是一个类似printf的格式字符串的命令行参数描述串,如上面的”ac:d:”定义了”a”, “c”,”d”3个命令行参数,其中,a是一个标志符不需要参数,”c”和”d”需要跟参数。getopt()功能非常弱,只支持单个字符的标志选项和参 数选项。如果按上面的5点来比对,基本上只能说是勉强支持第3点,其他几项只能靠程序自己来实现了,所以,想直接基于getopt()实现一个像git这 样复杂的命令行参数是不可能的,只有自己来做很多的解析工作。小伙伴们看过getopt()之后一致的评价是:图样图森破。


2. Google gflags

接着,小伙伴们又发现了gflags这个Google出品C++命令行参数解析库。

01//C++
02DEFINE_bool(memory_pool, false, "If use memory pool");
03DEFINE_bool(daemon, true, "If started as daemon");
04DEFINE_string(module_id, "", "Server module id");
05DEFINE_int32(http_port, 80, "HTTP listen port");
06DEFINE_int32(https_port, 443, "HTTPS listen port");
07 
08int main(int argc, char** argv) {
09    ::google::ParseCommandLineFlags(&argc, &argv, true);
10 
11    printf("Server module id: %s", FLAGS_module_id.c_str());
12 
13    if (FLAGS_daemon) {
14      printf("Run as daemon: %d", FLAGS_daemon);
15    }
16    if (FLAGS_memory_pool) {
17      printf("Use memory pool: %d", FLAGS_daemon);
18    }
19 
20    Server server;
21 
22    return 0;
23}

小伙伴们看了后不由得感叹“真心好用啊”!的确,gflags简单地通过几个宏就定义了命令行选项,基本上很好的支持了上面提到的1,3,4这几 项,比起getopt()来强多了。对于类似cp这样的小命令,gflags应该是够用了,但要达到git这种级别就显得有些单薄了。


3. Ruby Commander

接下来小伙伴们又发现了Ruby Commander库:

01//Ruby
02# :name is optional, otherwise uses the basename of this executable
03program :name, 'Foo Bar'
04program :version, '1.0.0'
05program :description, 'Stupid command that prints foo or bar.'
06command :bar do |c|
07  c.syntax = 'foobar bar [options]'
08  c.description = 'Display bar with optional prefix and suffix'
09  c.option '--prefix STRING', String, 'Adds a prefix to bar'
10  c.option '--suffix STRING', String, 'Adds a suffix to bar'
11  c.action do |args, options|
12    options.default :prefix => '(', :suffix => ')'
13    say "#{options.prefix}bar#{options.suffix}"
14  end
15end
16$ foobar bar
17# => (bar)
18$ foobar bar --suffix '}' --prefix '{'
19# => {bar}

Commander库利用Ruby酷炫的语法定义了一种描述命令行参数的内部DSL,看起来相当高端大气上档次。除了上面的第5项之外,其他几项都 有很好的支持,可以说Commander库的设计基本达到了git这种级别命令行参数解析的要求。只是,要搞懂Ruby这么炫的语法和这个库的使用方法恐 怕就不如getopt()和gflags容易了。有小伙伴当场表示想要学习Ruby,但是也有小伙伴表示再看看其他库再说。


酷毙
1

雷人

鲜花

鸡蛋

漂亮

刚表态过的朋友 (1 人)

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部