Я работаю над чем-то похожим, основываясь на каком-то умном рубиновом коде, который я видел однажды, но теперь не могу найти снова. У меня есть вещи, которые почти работают, но они портят такие вещи, как self.included и self.extended в вашем модуле, по несколько очевидным причинам, которые можно обойти, но мне не нравится, насколько сложным это будет , Я думаю, что есть одна хитрость, о которой я еще не думал, которая сделает эту работу более совершенной.
Так что это может или не может работать для вас, но я пытаюсь представить идею анонимного модуля, создаваемого динамически на основе ваших опций. (Я думаю, что «type» может быть зарезервированным словом, но я не уверен, поэтому давайте вместо этого скажем «options»). Проверьте эту идею:
Module HelperModule
def[](options)
Module.new do
include HelperModule
define_method(:options) { options }
end
end
def options
raise TypeError.new("You need to instantiate this module with [], man!")
end
end
obj = Object.new
obj.extend(HelperModule)
obj.options => raises TypeError
obj = Object.new
obj.extend(HelperModule[ :my_option => "my_option" ]
obj.options => { my_option => "my_option }
Вроде аккуратно, а? Но для меня это пока недостаточно хорошо, потому что сам модуль, который вы получаете из HelperModule [options], не имеет self.included и self.extended из исходного HelperModule. Я думаю, я мог бы просто определить self.included и self.extended в модуле anon, но мне не нравится путаница в коде. Мне также не нравится явно указывать «включить HelperModule» в анонимный модуль, я бы предпочел, чтобы, как «я», за исключением того, что «я» не означает, что правильно, так что это не работает ,
Ах, подождите, угадайте, что я только что обнаружил: если этот общий подход кажется вам подходящим, он может быть предоставлен гемом paramix:
http://rubyworks.github.com/paramix/