2009-12-24 70 views
0

的外部全局的方法,我想這樣寫:使用define_method定義模塊

[:p, :h1, :h3].each do |tag| 
    define_method(tag) { |text| "<#{tag}>#{text}</#{tag}>" } 
end 

這只是一些簡單的方法,以HTML標籤的文本換行。我希望能夠在腳本的其餘部分使用這些方法。不幸的是,define_method方法似乎只適用於模塊內部。但是如果我在一個模塊中做了這個,我將無法完整地寫出p "This is a paragraph.",它會像HTML::p "This is a paragraph."這樣會非常糟糕。

那麼我該如何定義全局這樣的方法呢?

回答

3

我不知道你的整個情況,但你可能並不想真正地定義全局方法。如果您不想輸入HTML::,請在代碼的開頭添加一條include HTML聲明。

+0

這似乎哈克在第一但我想它非常乾淨,而且完美。謝謝! – 2009-12-24 03:51:19

2

一個黑客是創建內部對象的方法,那麼這將是你的願望全局方法:

class Object 
    def create_method(name, &block) 
    self.class.send(:define_method, name, &block) 
    end 
end 

tag = 'p' 
a = Object.new 
a.create_method(tag.intern) {|v| puts "<#{tag}>#{v}</#{tag}>"} 

send(tag.intern, 'content') # => <p>content</p> 
+0

這段代碼沒有定義'全局'方法,它只定義了接收者類的方法。在這個例子中'a'是Object的一個實例,所以這些方法將是'全局'的,但是通常情況下,這不適用於你的代碼。 – horseyguy 2009-12-24 05:06:17

+0

這當然只適用於類Object ...,其中我添加了方法create_method。要明確一點,從我個人的感受來看,這不是一種好的風格,而只是滿足原始​​問題內涵的一種方式。 – bryantsai 2009-12-24 05:11:10

5

如果你真的需要做的是:

[:p, :h1, :h3].each do |tag| 
    Object.send(:define_method, tag) { |text| "<#{tag}>#{text}</#{tag}>" } 
end