在Ruby中,一个方法可以使用块/ lambda,并使您能够编写看起来像是语言一部分的构造.例如,类times上的方法Fixnum:
2.times do
# whatever code is between do and end, will be executed 2 times
end
Run Code Online (Sandbox Code Playgroud)
或者例如,类中的open方法File:
File.open(some_file) do |file|
# do something with the file; once the block finishes execution, the handle is automatically closed
end
Run Code Online (Sandbox Code Playgroud)
open方法可以有类似的实现(借用Ruby"伪代码"):
class File
def open(file,mode="r",&blk)
begin
handle = probably_sys_open(file)
if block_given?
blk.call(handle)
close(handle)
else
return handle
end
rescue SomeException => e
# whatever error handling goes on here
end
end
end
Run Code Online (Sandbox Code Playgroud)
我怎样才能在elisp中编写这样的函数/方法,这样当我使用它们时,我只需要关心任务的"相关"部分,而不是一直遍历所有的样板?
我怎样才能在elisp中编写这样的函数/方法,这样当我使用它们时,我只需要关心任务的"相关"部分,而不是一直遍历所有的样板?
您可以使用宏.
例如,如果没有dotimes,您可以轻松地自己编写类似的内容:
(defmacro do-times (n &rest body)
(let ((i (gensym)))
`(do ((,i 0 (1+ ,i)))
((= ,i ,n))
,@body)))
Run Code Online (Sandbox Code Playgroud)
现在,(do-times 3 (princ 'x))将做你期望的事情(你可能需要先做(require 'cl)).
这可以通过编写为您编写样板文件的代码来实现.我不会在这里给你一个完整的宏教程 - 快速谷歌搜索将为你提供足够的教程和其他信息来开始.
您可以对文件处理执行相同的操作.看一下with-temp-fileemacs lisp示例.例如,在CL中with-open-file,它与第二个Ruby片段具有几乎相同的功能.所以:
File.open(some_file) do |file|
# do something with the file; once the block finishes execution, the handle is automatically closed
end
Run Code Online (Sandbox Code Playgroud)
变为:
(with-open-file (file "some_file")
# do something ...
)
Run Code Online (Sandbox Code Playgroud)
除了你可以用宏做的语法抽象,你还可以编写更高阶的函数:
(defun times (n function)
(do-times n (funcall function)))
Run Code Online (Sandbox Code Playgroud)
现在,此函数将采用计数和另一个将执行的函数n.(times 3 (lambda () (princ 'x)))会做你所期望的.或多或少,Ruby块只是这类事物的语法糖.
| 归档时间: |
|
| 查看次数: |
147 次 |
| 最近记录: |