• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 一個巢穴,二十種Ruby DSL(7)

    發表于:2013-02-28來源:圖靈社區作者:Martin Fowler點擊數: 標簽:
    [:item, :small_power_plant, [:provides, [:electricity, 11]], [:depends_on, :secure_air_vent]]] 可變參數方法 有些語言支持可變參數方法,此時在函數調用中使用字面量列表是一

      [:item, :small_power_plant,

      [:provides, [:electricity, 11]],

      [:depends_on, :secure_air_vent]]]

      可變參數方法

      有些語言支持可變參數方法,此時在函數調用中使用字面量列表是一種很有用的技術。在下面的代碼中,我把這種方式應用于uses方法。

      下載 lairs/rules24.rb

      item :secure_air_vent

      item(:acid_bath) do

      uses(acid(:type => :hcl, :grade => 5),

      electricity(12))

      end

      item(:camera) do

      uses(electricity(1))

      end

      item(:small_power_plant) do

      provides(electricity(11))

      depends_on(:secure_air_vent)

      end

      在這種需要把方法調用中的列表組合在一起的情況下,使用可變參數是非常趁手的——尤其是當語言對在何處放置字面量列表限制得非常嚴格時。

      3.7 動態接收

      動態編程語言的一個特性是:它能對沒有在接收對象里定義的方法調用進行響應。

      讓我們在這個例子中探索一下這句話的含義。到目前為止,我們假設巢穴里的資源數量是相對固定的,我們可以編寫相應的代碼來處理這些固定數量的資源。但如果不是假設的這種情況呢?如果有很多資源呢?如果需要把非常多的資源置于配置中呢?

      下載 lairs/rules23.rb

      resource :electricity, :power

      resource :acid, :type, :grade

      item :secure_air_vent

      item(:acid_bath).

      uses(acid(:type => :hcl, :grade => 5)).

      uses(electricity(:power => 12))

      item(:camera).

      uses(electricity(:power => 1))

      item(:small_power_plant).

      provides(electricity(:power => 11)).

      depends_on(:secure_air_vent)

      electricity和acid仍舊是生成器中的方法。我希望這些方法可以創建新定義的資源,但我不希望去定義這些方法,而是希望它們能夠根據資源的數據來自動創建。

      在Ruby中可以通過重寫method_missing方法來實現。在Ruby中,如果一個對象接收了一個沒有定義的方法調用,那么它就會執行method_missing方法。這個方法默認是從Object類中繼承而來,而且會拋出一個異常。我們可以通過重寫這個方法來做一些有趣的事情。

      首先做好對資源方法調用的準備工作。

      下載 lairs/builder23.rb

      def resource name, *attributes

      attributes << :name

      new_resource = Struct.new(*attributes)

      @configuration.add_resource_type name, new_resource

      end

      Ruby有一個用來創建匿名類的工具,叫做struct。當需要一個資源時,調用struct進行定義。以resource方法的第一個參數作為新定義資源的名字,并根據隨后的參數設置新定義資源的屬性(property)。然后把這些新定義的資源保存于配置中。

      接著我重寫了method_missing方法。該方法在一個字面量字典中遍歷了所有新定義的資源,以確定方法名是否與新的struct之一對應。如果有,則加載這個struct。

      下載 lairs/builder23.rb

      def method_missing sym, *args

      super sym, *args unless @configuration.resource_names.include? sym

      obj = @configuration.resource_type(sym).new

      obj[:name] = sym

      args[0].each_pair do |key, value|

      obj[key] = value

      end

      return obj

      end

      在method_missing被調用時,首先確認是否有資源可以響應這個調用。如果沒有,則調用超類中的method_missing以引發一個異常。

      大多數動態語言都可以重寫“處理未知調用的方法”。這是一個很強大的技術,但在使用時需要格外小心,因為它會改變程序方法分派系統的機制。如果沒有合理使用,代碼會變得難以理解。

      Ruby的生成器庫(由Jim Weirich編寫)就是一個如何正確使用method_missing的好例子。生成器庫是用來生成XML標記的,它非常合理地使用了閉包和method_missing。

      可以通過一個簡單的例子來說明這一點。如下代碼,

      下載 lairs/frags

      Builder::XmlMarkup.new("" , 2)

      puts builder.person do |b|

      b.name("jim")

      b.phone("555-1234" , "local" =>"yes")

      b.address("Cincinnati")

      end

      會生成下面這段標記。

      下載 lairs/frags

      

      jim

      555-1234

      

    Cincinnati

      

      3.8 總結

      兩年之前,Dave Thomas在他的博客中提及“代碼拆招”(code katas)的概念:在嘗試使用各種方法來解決一個簡單問題的過程中,研究和比較各種解決方案的優劣。本章就是這樣的一個練習。最后我也沒有給出任何確定的結論,但它確實帶著我們探討和領略了用Ruby編寫內部DSL的各種方法(當然,大部分方法也可以通過其他語言來實現)。

    原文轉自:http://www.ituring.com.cn/article/17818

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>