使用define_method定义模块外部的全局方法

时间:2009-12-24 03:07:24

标签: ruby metaprogramming

我想写这个:

[: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 个答案:

答案 0 :(得分:5)

如果你真的需要这样做:

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

答案 1 :(得分:3)

我不知道你的整个情况,但你可能不想真正定义全局方法。如果您不想输入HTML::,请在代码的开头添加include HTML语句。

答案 2 :(得分:2)

一个hack就是在Object中创建方法,然后它就是你想要的全局方法:

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>