创建DSL语法的问题

时间:2014-03-27 11:43:22

标签: ruby metaprogramming

我有以下代码:

module A
  def self.included(base)
    base.extend(ClassMethods)
  end
  def foo
    a = bar
    puts a
  end
  def bar(str="qwe")
    str
  end

  module ClassMethods
  end
end

class B
  include A
  def bar(str="rty")
    str
  end
end

B.new.foo #=> "rty"

我希望课程B看起来像这样:

class B
  include A
  bar "rty"
end

B.new.foo #=> rty

class B
  include A
  HelperOptions.bar "rty"  # HelperOptions class should be in module A
end

B.new.foo #=> rty

我尝试使用define_methodclass_evalinitialize。如何实现语法bar 'rty'HelperOptions.bar 'rty'以及在模块A中应该做什么?

1 个答案:

答案 0 :(得分:2)

如果我正确地得到了你的问题,你想要定义一个类方法A.bar来定义一个返回它的参数的实例方法B#bar,你可以这样做:

module A
  def self.included(base)
    base.extend(ClassMethods)
  end
  def foo
   puts bar
  end

  module ClassMethods
    def bar(str)
      define_method(:bar) { str }
    end
  end
end

class B
  include A
  bar 'rty'
end

B.new.bar
# => "rty"

B.new.foo
# Output: rty