gpt4 book ai didi

scheme - 我将如何使这个 Racket 代码干燥?

转载 作者:行者123 更新时间:2023-12-04 11:50:27 24 4
gpt4 key购买 nike

我正在将 Python 脚本移植到 Racket 作为学习经验,并且我有这个功能:

(define (check-status)
(define git [find-executable-path "git"])
(define-values (ckot out in err)
(subprocess #f #f #f git "checkout" "-q" "master"))
(define-values (local lout lin lerr)
(subprocess #f #f #f git "rev-parse" "@"))
(define-values (remote rout rin rerr)
(subprocess #f #f #f git "rev-parse" "@{u}"))
(define-values (merge-base mbout mbin mberr)
(subprocess #f #f #f git "merge-base" "@" "@{u}"))
(display-lines (port->lines mbout))
(define ports '(ckot out in err local lout lin lerr remote rout rin rerr merge-base mbout mbin mberr))
(map (lambda (x)
(cond ((input-port? x) (close-input-port x))
((output-port? x) (close-output-port x)))) ports))

问题是它不是很干燥。由于我使用的是 Lisp,而 Lisp 以能够做疯狂的事情而闻名,我想知道是否有办法获取所有子流程代码并提取它,以便我可以执行以下操作:
(define (check-status)
(define commands '(
'("checkout" "-q" "master")
'("rev-parse" "@")
'("rev-parse" "@{u}")
'("merge-base" "@" "@{u}"))
(map currently-immaginary-git-command-fn commands))

最后得到命令列表中每个命令的输出列表。我该怎么做?由于我是整个 Lisp/Scheme 的新手,所以我正在弄清楚语法,我并不完全了解我可用的资源。

最佳答案

首先,对您想要提出更清洁的解决方案有好处!你是对的,有一种更优雅的方式来做你尝试过的事情。

首先,使用 subprocess在您的特定用例中几乎可以肯定是矫枉过正。 racket/system 模块提供了一个更简单的接口(interface),应该足以满足您的需求。具体来说,我会使用 system* 函数,它使用提供的参数执行单个进程,然后将其输出打印到标准输出。

使用 system* ,可以创建一个非常通用的帮助函数,该函数可以为特定的可执行文件执行命令并将其输出作为字符串返回。

(define (execute-command proc-name)
(define proc (find-executable-path proc-name))
(λ (args)
(with-output-to-string
(thunk (apply system* proc args)))))

这个函数本身在被调用时会返回一个新函数。这意味着使用它来调用 Git 命令将如下所示:
((execute-command "git") '("checkout" "-q" "master"))

其原因很快就会显现出来。

实际查看 execute-command 的实现, 我们使用 with-output-to-string 重定向 system* 的所有输出调用一个字符串(而不仅仅是将其打印到标准输出)。这实际上只是使用 parameterize 的缩写。设置 current-output-port参数,但它更简单。

有了这个函数,我们可以实现 check-status非常简单地。
(define (check-status)
(define commands
'(("checkout" "-q" "master")
("rev-parse" "@")
("rev-parse" "@{u}")
("merge-base" "@" "@{u}")))
(map (execute-command "git") commands))

现在拥有 (execute-command "git") 的原因return a new function 变得很明显:我们可以使用它来创建一个函数,然后映射到 commands list 生成一个新的字符串列表。

另外,请注意 commands 的定义列表仅使用单个 '一开始。您提供的定义不起作用,事实上, ports您在原始实现中定义的列表不是您所期望的。这是因为 '(...)(list ...) 不完全相同——它们是不同的,所以在使用它们时要小心。

关于scheme - 我将如何使这个 Racket 代码干燥?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30625909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com