首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby元编程

Ruby元编程
EN

Stack Overflow用户
提问于 2010-05-30 01:00:48
回答 2查看 522关注 0票数 4

我正在尝试编写一个DSL,它允许我这样做

代码语言:javascript
复制
Policy.name do
 author "Foo"
 reviewed_by "Bar"
end

下面的代码几乎可以处理它:

代码语言:javascript
复制
class Policy
  include Singleton
  def self.method_missing(name,&block)
      puts name
      puts "#{yield}"
  end
  def self.author(name)
   puts name
  end
  def self.reviewed_by(name)
   puts name
  end
end

将我的方法定义为类方法(self.method_name),我可以使用以下语法访问它:

代码语言:javascript
复制
Policy.name do
 Policy.author "Foo"
 Policy.reviewed_by "Bar"
end

如果我从方法名中删除"self“,并尝试使用我想要的语法,那么我在Main中收到一个错误"Method not find”,因此它在模块内核之前找不到我的函数。没关系,我理解这个错误。但是我怎么才能修复它呢?我如何修复我的类,使其与我想要的语法一起工作?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-05-30 01:17:36

为了控制块范围内的self (因为author解析为self.author),您可以使用instance_eval

代码语言:javascript
复制
class Policy
  def self.name(&block)
    PolicyNameScope.new(block)
  end

  class PolicyNameScope
    def initialize(block)
      instance_eval(&block)     
    end

    def author(author)
      @author = author
    end

    def reviewed_by(reviewed_by)
      @reviewed_by = reviewed_by
    end
  end
end

policy = Policy.name do
  author "Dawg"
  reviewed_by "Dude"
end

p policy
# => #<Policy::PolicyNameScope:0x7fb81ef9f910 @reviewed_by="Dude", @author="Dawg">

PolicyNameScope类具有name块中允许的实例方法。这是因为来自Policy的方法在块中不可用,这使得领域特定语言变得更加紧凑。

由于您的示例脱离了上下文,因此我不能进一步帮助您--这段代码本身似乎没有多大用处。

票数 4
EN

Stack Overflow用户

发布于 2010-07-13 16:38:02

上面由奥古斯特提出的答案是正确的,但是如果你想将你的构造器用于其他目的,那么上面的方法就失败了。因此,在这种情况下,您必须使用除上述方法之外的其他方法。这是我在不使用类构造函数的情况下准备的解决方案。

代码语言:javascript
复制
class Policy

  def self.method_missing(name,&block)
    self.class_eval(&block)
  end
  def self.author(name)
    p name
  end
  def self.reviewed_by(name)
    p name
  end

end

Policy.name do
  author "Foo"
  reviewed_by "Bar"
end

这不是一个优化的解决方案,而是你所说的问题的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2935894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档