当前位置:网站首页>Code is data
Code is data
2022-06-27 05:47:00 【guagua070707】
Several friends are considering the following problems that each language will encounter :
problem : Design a command line parameter parsing API
A good command line parameter parsing library generally involves these common aspects :
1) Support easy generation of help information
2) Support subcommands , such as :git Contains push, pull, commit And so on
3) Single character option is supported 、 Multi character options 、 Flag options 、 Parameter options and other options and position parameters
4) The default values of options are supported , such as :—port If the option is not specified, it will be considered as 5037
5) Support usage mode , such as :tar Ordered -c and -x Is a mutually exclusive option , Belong to different usage modes
After some investigation , The partners found several representative API Design :
1. getopt():
getopt() yes libc The standard function of , You can find a ported version of it in many languages .
//Cwhile ((c = getopt(argc, argv, "ac:d:")) != -1) {int this_option_optind = optind ? optind : 1;switch (c) {case 'a':printf ("option a");aopt = 1;break;case 'c':printf ("option c with value '%s'", optarg);copt = optarg;break;case 'd':printf ("option d with value '%s'", optarg);dopt = optarg;break;case '?':break;default:printf ("?? getopt returned character code 0%o ??", c);}}
getopt() The core of is a similar printf The command line parameter description string of the format string , As above ”ac” Defined ”a”, “c”,”d”3 Two command line arguments , among ,a Is an identifier without parameters ,”c” and ”d” Need to follow the parameters .getopt() Very weak , Only single character flag options and parameter options are supported . If you press the above 5 Click to compare , Basically, I can only say that I reluctantly support the 3 spot , Other items can only be realized by the program itself , therefore , Want to base directly on getopt() Implement a program like git Such complex command-line arguments are impossible , I have to do a lot of parsing work myself . My friends have seen getopt() After that, the unanimous evaluation was : too young too simple .
2. Google gflags
next , My friends found out again gflags This Google Produce C++ Parsing command line parameters .
//C++DEFINE_bool(memory_pool, false, "If use memory pool");DEFINE_bool(daemon, true, "If started as daemon");DEFINE_string(module_id, "", "Server module id");DEFINE_int32(http_port, 80, "HTTP listen port");DEFINE_int32(https_port, 443, "HTTPS listen port");int main(int argc, char** argv) {::google::ParseCommandLineFlags(&argc, &argv, true);printf("Server module id: %s", FLAGS_module_id.c_str());if (FLAGS_daemon) {printf("Run as daemon: %d", FLAGS_daemon);}if (FLAGS_memory_pool) {printf("Use memory pool: %d", FLAGS_daemon);}Server server;return 0;}
After watching it, my friends could not help sighing “ It's really easy to use ”! You bet ,gflags Command line options are defined simply through a few macros , Basically, it supports the above mentioned 1,3,4 These items , Compared with getopt() It's much better . For similar cp Such a small order ,gflags It should be enough , But to achieve git This level seems a little thin .
3. Ruby Commander
Then the little friends found out Ruby Commander library :
//Ruby# :name is optional, otherwise uses the basename of this executableprogram :name, 'Foo Bar'program :version, '1.0.0'program :description, 'Stupid command that prints foo or bar.'command :bar do |c|c.syntax = 'foobar bar [options]'c.description = 'Display bar with optional prefix and suffix'c.option '--prefix STRING', String, 'Adds a prefix to bar'c.option '--suffix STRING', String, 'Adds a suffix to bar'c.action do |args, options|options.default :prefix => '(', :suffix => ')'say "#{options.prefix}bar#{options.suffix}"endend$ foobar bar# => (bar)$ foobar bar --suffix '}' --prefix '{'# => {bar}
Commander Library utilization Ruby Cool syntax defines an internal... That describes command line parameters DSL, It looks quite high-end and elegant . Except for the first 5 Beyond item , Several other items are well supported , so to speak Commander The design of the library basically achieves git Requirements for command line parameter resolution at this level . It's just , To understand Ruby I'm afraid that such a dazzling syntax and the use of this library are not as good as getopt() and gflags It's easy . A little friend said on the spot that he wanted to learn Ruby, But there are also small partners who say that they should look at other libraries .
4. Lisp cmdline library
Next , My friends found out Lisp dialect Racket Of cmdline library .
//Lisp(parse-command-line "compile" (current-command-line-arguments)`((once-each[("-v" "--verbose"),(lambda (flag) (verbose-mode #t))("Compile with verbose messages")][("-p" "--profile"),(lambda (flag) (profiling-on #t))("Compile with profiling")])(once-any[("-o" "--optimize-1"),(lambda (flag) (optimize-level 1))("Compile with optimization level 1")][("--optimize-2"),(lambda (flag) (optimize-level 2))(("Compile with optimization level 2,""which implies all optimizations of level 1"))])(multi[("-l" "--link-flags"),(lambda (flag lf) (link-flags (cons lf (link-flags))))("Add a flag <lf> for the linker" "lf")]))(lambda (flag-accum file) file)'("filename"))
This is the god horse floating cloud ? Parentheses cover parentheses , It looks very powerful , But I don't quite understand . See this design , Some of my friends are too lazy to comment , But some friends are right Lisp More worship , Express Lisp Is the so-called ultimate language , No other language can write such code without awareness ! My friends are preparing to finish the work , All of a sudden …
5. Node.js Of LineParser library
Found out Node.js Of LineParser library :
var meta = {program : 'adb',name : 'Android Debug Bridge',version : '1.0.3',subcommands : [ 'connect', 'disconnect', 'install' ],options : {flags : [[ 'h', 'help', 'print program usage' ],[ 'r', 'reinstall', 'reinstall package' ],[ 'l', 'localhost', 'localhost' ]],parameters : [[ null, 'host', 'adb server hostname or IP address', null ],[ 'p', 'port', 'adb server port', 5037 ]]},usages : [[ 'connect', ['host', '[port]'], null, 'connect to adb server', adb_connect ],[ 'connect', [ 'l' ], null, 'connect to the local adb server', adb_connect ],[ 'disconnect', null, null, 'disconnect from adb server', adb_disconnect ],[ 'install', ['r'], ['package'], 'install package', adb_install ],[ null, ['h'], null, 'help', adb_help ],]};try {var lineparser = require('lineparser');var parser = lineparser.init(meta);parser.parse(['install', '-r', '/pkgs/bird.apk']); // adb_install will be invoked}catch (e) {console.error(e);}
Oh my god !? What is it? ? My friends and I were completely shocked ! Just a dozen lines of code 5 Full support for point , The important thing is that the little friends can understand it at once , There is no concealment or deception . Originally thought Ruby and Lisp cool , All my friends want to learn at once Ruby and Lisp 了 , After seeing this code, how do you feel that the front is all installed ? A little friend was so excited that he cried and said : I've been writing code for years , I thought there was no more code that could move me , I didn't expect this code to be so exquisite , I can't help admiring , It's so beautiful !
The story of my friends is over , Do you understand ? If not, take a look at the following analysis .
In most languages, data and code are very distinct , habit C++、Java And other mainstream language programmers rarely think about the relationship between data and code . Unlike most languages Lisp With “ Data is code , Code is data ” Is famous for its ,Lisp use S Expressions are unique because they unify the form of data and code .Lisp strange S Expressions and complex macro systems make many people feel Lisp It's mysterious , The majority Lisp Tutorials either emphasize functional programming , Or preach how powerful the macro is , Instead, it covers up Lisp What is really essential , For this reason, I once wrote an article 《Lisp The eternal way of 》 Introduce Lisp thought .
The difference between design ideas and specific technologies is that the former can often be displayed in different forms in different environments . such as , Programmers who are familiar with functional programming understand the advantages of pure functions, even if they use C Languages also tend to write functions that have no side effects , This is the application of functional thinking in imperative environment . therefore , understand Lisp The thought must be able to be in the wrong Lisp Environmental applications , It can be regarded as integration .
If you really understand Lisp The essence of , So called “ Data is code , Code is data ” It's not mysterious at all , This is the configuration file we deal with everyday !? If you don't quite understand , We will analyze the following questions slowly :
1) What is the nature of configuration ? Why use configuration files in programs ?
I wonder if you realize , We use all kinds of... Every day Configuration is essentially a kind of metadata and a kind of DSL, This sum Lisp be based on S Of expression “ Data is code , Code is data ” There is no essential difference . stay C++、Java The purpose of introducing the configuration file into the program is to use DSL Make up for the lack of common language expression ability and flexibility . I know that many people like to see programs and languages from the perspective of computation , It seems that only Turing's complete language such as C++、Java、Python And so on is called programming language , But similar CSS and HTML Such a thing cannot be called a programming language at all . Actually , In my opinion, this view is too narrow , The essence of a program is the expression of semantics , Semantic expression does not have to be calculated .
2) Configuration is data or code ?
Obviously ,Both! Configuration is data , Because it is a declarative description , It can be easily modified and transmitted ; Say that configuration is code , Because it expresses logic , Your program is actually a configuration interpreter .
3) What is the configuration format ?
The configuration format is arbitrary , You can define your own grammar , As long as the corresponding interpreter is provided . But the simpler and more general approach is based on XML、JSON、 or S Expressions and other standard structures , Define further on this schema. It doesn't even have to be a file at all , In our projects, the configuration is often put into the relational database .
4) Can the business logic be put into the configuration ?
The answer to this question is obviously :Yes! I haven't encountered any logic that can't be put into the configuration , The question is whether it is worth it , What can be achieved . For the need to be flexible , Recurring , It is a wise choice to put something of reuse value into the configuration . The main purpose of this article is to introduce The main business logic is put into the configuration , Then the design method of execution configuration is explained through the program , I call it meta - driven programming (Meta Driven Programming).
边栏推荐
- Execution rules of pytest framework
- Implementation of easyexcel's function of merging cells with the same content and dynamic title
- Win 10 如何打开环境变量窗口
- Senior [Software Test Engineer] learning route and necessary knowledge points
- Asp. Net core6 websocket simple case
- Codeforces Round #802 (Div. 2)
- [FPGA] UART serial port_ V1.1
- Niuke practice 101-c reasoning clown - bit operation + thinking
- Netease cloud music params and encseckey parameter generation code
- Acwing's 57th weekly match -- BC question is very good
猜你喜欢

Nlp-d62-nlp competition d31 & question brushing D15

树莓派4B上运行opcua协议DEMO接入kubeedge

竣达技术丨多品牌精密空调集中监控方案

微信小程序WebSocket使用案例

Asp.Net Core6 WebSocket 简单案例

Basic concepts of neo4j graph database

Discussion on streaming media protocol (MPEG2-TS, RTSP, RTP, RTCP, SDP, RTMP, HLS, HDS, HSS, mpeg-dash)

Two position relay rxmvb2 r251 204 110dc

多线程基础部分Part2

What is BFC? What's the usage?
随机推荐
Ad22 Gerber files Click to open the Gerber step interface. Official solutions to problems
微信小程序WebSocket使用案例
Web3还没实现,Web5乍然惊现!
Pytest框架的执行规则
[cocos creator 3.5.1] addition of coordinates
RTP 发送PS流工具(已经开源)
Edge loads web pages in IE mode - edge sets ie compatibility
Two position relay xjls-8g/220
Vue学习笔记(五)Vue2页面跳转问题 | vue-router路由概念、分类与使用 | 编程式路由导航 | 路由组件的缓存 | 5种路由导航守卫 | 嵌套路由 | Vue2项目的打包与部署
Codeforces Round #802 (Div. 2)
函数式 连续式
Built in functions of spark
Interview: what are the positioning methods in selenium? Which one do you use most?
程序猿学习抖音短视频制作
数据库-索引
leetcode299周赛记录
js实现双向数据绑定
How JQ gets the reciprocal elements
认知篇----2022高考志愿该如何填报
双位置继电器RXMVB2 R251 204 110DC