自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入解讀Ruby DSL概念

開發(fā) 開發(fā)工具
Ruby DSL是一種專注于某一特定領(lǐng)域的語言。在Ruby中,內(nèi)部的Ruby DSL是的編寫和規(guī)范變得非常容易。下面將會對此做一個深入的介紹。

對于一個初學(xué)Ruby語言的朋友來說,對于Ruby DSL的理解還不是很清晰。在這篇文章中我們將會為大家詳細(xì)介紹有關(guān)Ruby DSL的一些使用方法。#t#

DSL是一種專注于某一特定領(lǐng)域的語言,使用通用語言(如C或者Java)當(dāng)然可以得到與DSL相同的功能。但是這樣會產(chǎn)生大量繁瑣的代碼并導(dǎo)致大量的領(lǐng)域知識被隱藏在通用語言構(gòu)造中(如for循環(huán),if條件,方法調(diào)用,import聲明等等)。

生成以及維護(hù)通用語言編寫的代碼本身也是問題所在:專家們必須將他們的知識變?yōu)榇a。通常這些專家(銷售人員,經(jīng)理或者園?。┤鄙倬幊讨R,這意味著他們必須與程序員進(jìn)行協(xié)作。當(dāng)然,這也意味對代碼的任何一次修改都包括許多繁瑣的步驟:如果一個領(lǐng)域?qū)<倚枰淖兡承┕δ?,她必須首先與程序員進(jìn)行交流,由程序員實現(xiàn)這些修改,然后領(lǐng)域?qū)<覚z查這些代碼是否表現(xiàn)出期望的行為,諸如此類。

對于上述問題,其中一個可能的解決方案是開發(fā)一種適應(yīng)特定環(huán)境的語言,非技術(shù)人員可以用它來解決問題。這種語言較通用語言更簡潔并且僅僅提供目標(biāo)領(lǐng)域所需要的類型以及特定的語言構(gòu)造。

在訪談中,Obie將DSL類比為自然語言中的俚語或者行話。全世界喜愛咖啡的人對下面這句話一定非常熟悉:

Venti half-caf, non-fat, no foam, no whip latte

在正常的對話中,上述語言不能傳遞正確的語義。并且世界上大多數(shù)的咖啡館里可能僅僅提供最普通的牛奶加咖啡。但是在合適的場所使用上述語言(例如,星巴克),它將讓你使用最少的詞語喝到想要的飲料并且很少會造成誤解。

有多種方式可以實現(xiàn)DSL。其中一個選擇是定義一種語法并使用解析器生成工具(如ANTLR或者YACC)來生成解析器。通過它可以將Ruby DSL代碼轉(zhuǎn)化為某種可以被解釋的數(shù)據(jù)結(jié)構(gòu)(語法樹)。其中一個例子是Make文件,它被用來定義構(gòu)建過程(編譯,打包,部署)。

另一種方式是使用XML而不是解析器,它將對于解析器生成工具的依賴變?yōu)閷τ赬ML解析器的依賴,有許多工具可以用來支撐XML處理(使用DOM解析器可以得到類似語法樹的數(shù)據(jù)結(jié)構(gòu),同時使用XPATH來提取數(shù)據(jù),等等)。Ant,是一個基于XML的DSL, 構(gòu)建過程被定義為XML格式。Make和Ant就是外部DSL最典型的實現(xiàn)。

另一個解決方案是內(nèi)部Ruby DSL,它不需要使用任何解析器生成工具以及XML解析器,取而代之的是使用現(xiàn)有的合法的通用語言的構(gòu)造,很明顯,這種語言的構(gòu)造必須非常靈活才可以容納各種簡練的DSL代碼。

內(nèi)部DSL的***解決工具非LISP以及類LISP語言莫屬,原因是LISP靈活的語法,它可以被概括為:

原子

幾乎任何字符都可以成為原子,如foo,:::bar:::甚至加號都是合法的原子

零個或多個原子組成的序列

放入圓括號中

LISP宏特性使得開發(fā)者可以很輕易的在LISP中定義DSL并且將其解釋或者展開為可以執(zhí)行的通常的LISP代碼。

另外一種適于使用內(nèi)部DSL的語言是Ruby, 沒什么可驚奇的,想想Ruby豐富的語法吧,它是Ruby得以支持內(nèi)部Ruby DSL的部分特性。下面是Obie在PPT上所使用到的觀點以及相應(yīng)的示例代碼:

方法調(diào)用中括號可以省略。這看起來沒什么大不了的, 但是它使得下面的聲明成為合法的Ruby代碼:

order = latte venti, half_caf, non_fat, no_foam, no_whip在上面的例子中,latte(拿鐵咖啡)以及我們所需要的特別的口味兒都是方法調(diào)用的一部分。latte方法返回一個將咖啡各個屬性進(jìn)行了初始化的對象。
類的定義在載入時可以被動態(tài)執(zhí)行

class RuleSet < ActiveRecord::Base has_many :commends, :dependend => :delete_all # ... more... end這是一個內(nèi)部DSL在Rails的ActiveRecord中的例子。has_many調(diào)用會在類***次被載入時執(zhí)行。這個調(diào)用被用來設(shè)定類的關(guān)聯(lián)以及行為,例如,它可以通過define_method調(diào)用向類添加一些方法。這樣這段Ruby DSL代碼的用戶可以使用非常簡潔,描述性的方式來定義類某些方面的行為。事實上,這與LISP宏有很多相似的地方,他們都在代碼被載入時進(jìn)行工作。

簡潔的代碼塊書寫格式(Block)

塊是自包含的Ruby代碼。它可以被保存,當(dāng)作參數(shù)傳遞并在以后執(zhí)行,這個概念也被稱做是匿名方法,lamda演算或者閉包(Closures),在Ruby中向方法傳遞塊非常簡潔緊湊,它使得實現(xiàn)特定語言構(gòu)造變得非常容易,Rake是與Make和Ant非常相似的構(gòu)建工具,我們來看一個例子:

task :default => [:test] task :test do ruby "test/unittest.rb" end上面的類使用了我們在這里提到的所有的三種概念。task是一種方法調(diào)用,但是沒有圓括號讓它變的更具描述性。task調(diào)用在載入時被執(zhí)行,對內(nèi)部數(shù)據(jù)結(jié)構(gòu)進(jìn)行設(shè)置。test任務(wù)的邏輯在塊中進(jìn)行定義(在do和end之間的代碼),并在適當(dāng)?shù)臅r候被執(zhí)行。

在Ruby中,內(nèi)部DSL使得編寫簡潔和描述性的規(guī)范變得非常容易。正如我們從has_many例子中看到的,內(nèi)部Ruby DSL也可以很容易的與通常命令式的Ruby代碼進(jìn)行混合。

責(zé)任編輯:曹凱 來源: 新浪博客
相關(guān)推薦

2009-12-15 14:16:13

Ruby Contin

2009-12-16 14:33:21

Ruby哈希表

2009-12-14 18:23:38

Ruby DSL測試

2009-12-16 16:44:31

Ruby on Rai

2009-12-14 18:30:59

Ruby DSL特點

2009-12-14 10:20:12

Ruby自動化測試

2009-12-15 15:35:56

Ruby symbol

2009-12-16 14:51:26

Ruby nil

2009-12-18 15:56:05

Ruby特殊語法

2009-12-15 15:55:43

Ruby模塊

2009-12-17 11:27:31

Ruby時間方法

2009-12-18 15:24:52

2010-09-25 14:39:29

Bruce Tate

2009-12-15 10:10:42

Ruby過程對象

2009-12-16 10:57:16

Ruby文件鎖

2009-12-16 16:24:00

Ruby on Rai

2009-12-14 14:50:46

Ruby傳參數(shù)

2010-06-29 10:17:06

連續(xù)ARQ協(xié)議

2009-12-18 17:20:00

Ruby核心類

2009-12-14 14:40:10

Ruby全局域變量
點贊
收藏

51CTO技術(shù)棧公眾號