2011-08-30 42 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塊只是這種東西的語法糖。

相關問題