簡體   English   中英

在ruby中沒有參數的DSL塊

[英]DSL block without argument in ruby

我正在用紅寶石寫一個簡單的dsl。 幾周前,我偶然發現了一些博文,其中展示了如何轉換代碼:

some_method argument do |book|
  book.some_method_on_book
  book.some_other_method_on_book :with => argument
end

更清潔的代碼:

some_method argument do
   some_method_on_book
   some_other_method_on_book :with => argument
end

我不記得如何做到這一點,我不確定缺點,但更清晰的語法是誘人的。 有沒有人對這種轉變有所了解?

def some_method argument, &blk
  #...
  book.instance_eval &blk
  #...
end

更新:但是,這省略了書,但不允許你使用參數。 要透明地使用它,你必須以某種方式運輸它。 我建議在書本身上做:

class Book
  attr_accessor :argument
end

def some_method argument, &blk
  #...
  book.argument = argument
  book.instance_eval &blk
  #...
end

some_method 'argument' do
   some_method_on_book
   some_other_method_on_book argument
end

看一下這篇文章http://www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation - 這個方法有一個概述(具體說明在它的缺點和可能的背景下)他們的解決方案),還有幾個有用的鏈接供進一步閱讀。

基本上,它是關於使用instance_eval在期望的上下文中執行塊。

說到這種技術的缺點:

那有什么問題呢? 嗯,問題是塊通常是閉包。 而且你希望它們實際上是全封閉的。 從你編寫塊的那一點來看,這個塊可能不是一個完整的閉包並不明顯。 當你使用instance_eval時會發生這種情況:你將該塊的self重置為其他東西 - 這意味着該塊仍然是塊外所有局部變量的閉包,但不是方法調用。 我甚至不知道是否改變了常量查找。

使用instance_eval會以一種在讀取塊時不明顯的方式更改語言規則。 你需要考慮一個額外的步驟來弄清楚為什么一個你可以在塊周圍看到的方法調用實際上不能從塊內部調用。

看看溫順的寶石。 它可以處理所有鋒利的邊緣,讓您輕松自如。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM