2011-08-30 50 views
3

在Ruby中,一个方法可以使用blocks/lambda表达式,并使您可以编写看起来像是语言一部分的构造。例如,在Fixnumtimes方法:如何在elisp中定义以“块”作为参数的函数?

2.times do 
    # whatever code is between do and end, will be executed 2 times 
end 

或者例如,在File类的open方法:

File.open(some_file) do |file| 
    # do something with the file; once the block finishes execution, the handle is automatically closed 
end 

open方法可能有类似这样的实现(借口红宝石“伪”):

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 

我怎么能写这样的功能/ elisp的方法,这样,当我请使用t下摆,我只需要关心任务的“相关”部分,而不是始终浏览所有的样板文件。

回答

5

我怎么能写这样的功能/ elisp的方法,这样,当我使用 他们,我只需要关心的 而不是通过所有的样板去有关的任务“有关”部分,所有时间?

你可以使用宏。

如果,例如,没有dotimes,你可以轻松地编写类似的东西自己:

(defmacro do-times (n &rest body) 
    (let ((i (gensym))) 
    `(do ((,i 0 (1+ ,i))) 
     ((= ,i ,n)) 
     ,@body))) 

现在,(do-times 3 (princ 'x))会做你所期望(您可能需要(require 'cl)第一)。

这可以通过编写代码来为您编写样板文件。我不会在这里给你一个完整的宏教程 - 快速谷歌搜索将为您提供足够的教程和其他信息来开始。

您可以为文件处理做同样的事情。请查看with-temp-file了解emacs 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 

变为:

(with-open-file (file "some_file") 
    # do something ... 
) 

除了语法抽象,你可以用宏做的,你也可以写高阶函数:

​​

现在,这个功能将采取计数和另一个函数,将执行n次。 (times 3 (lambda() (princ 'x)))会做你所期望的。或多或少,Ruby块只是这种东西的语法糖。

相关问题