DSL类初始化使用instance_eval或block.call存在参数数量问题

时间:2017-09-12 19:19:28

标签: ruby

我正在编写基于我过去成功使用的pattern的DSL。我认为这可以开箱即用,但我收到一个我无法弄清楚的错误,所以任何帮助都表示赞赏。

以下是添加测试的方法:

module PPEKit
  module Tests
    def add_test(id, &block)
      @_tests ||= {}
      @_tests[id] = Test.new(id, &block) unless @_tests.include? id
    end
  end
end

以下是Test类定义:

  module Tests
    class Test
      attr_accessor :id, :description, :conditions, :platforms

      def initialize(id, &block)
        @id = id
        (block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given? # ERROR occurs here
      end
    end
  end

Tests模块包含在PPEKit :: Product类中,如下所示:

module PPEKit
  class Product
    include Tests

我没有显示method_missing,因为在instance_eval调用期间发生了错误。我尝试使用两种类型的块arity初始化Test对象,结果相同:

    add_test :my_test_id do
      description 'my test description'
      conditions  [:minvdd, :maxvdd, :bin1_1300Mhz, :bin2_1200Mhz]
      platforms   [:v93k, :j750]
      meta1       'dkwew'
      meta2       'jkjejkf'
    end

    add_test :my_test_id do |t|
      t.description 'my test description'
      t.conditions  [:minvdd, :maxvdd, :bin1_1300Mhz, :bin2_1200Mhz]
      t.platforms   [:v93k, :j750]
      t.meta1       'dkwew'
      t.meta2       'jkjejkf'
    end

上述两个定义都会出现以下错误:

    COMPLETE CALL STACK
    -------------------
    wrong number of arguments (given 1, expected 0)
    /users/user/origen/ppekit/lib/ppekit/test_list.rb:6:in `block in instantiate_tests'

在调用instance_eval:

之前,先看一下pry中的Test类
    [1] pry(#<PPEKit::Tests::Test>)> id
    => :my_test_id
    [2] pry(#<PPEKit::Tests::Test>)> self
    => #<PPEKit::Tests::Test:0x002b42673ab158>
    [3] pry(#<PPEKit::Tests::Test>)> cd self
    [4] pry(#<PPEKit::Tests::Test>)> block.arity
    => 0
    [5] pry(#<PPEKit::Tests::Test>)> block
    => #       <Proc:0x002ab7aff4cab8@/users/user/origen/ppekit/lib/ppekit/test_list.rb:5>
    [6] pry(#<PPEKit::Tests::Test>):1> ls
    PPEKit::Tests::Test#methods:
      conditions  conditions=  description  description=  id  id=  method_missing  platforms  platforms=
    self.methods: __pry__
    locals: _  __  _dir_  _ex_  _file_  _in_  _out_  _pry_

再次,先谢谢。

问候

1 个答案:

答案 0 :(得分:1)

您没有include(),只有一个getter description(arg)和一个setter description()。因此,当你执行description=(arg)时,它会使用一个它不期望的参数来调用getter,并获得description 'my test description'

在教程中,他们不使用wrong number of arguments (given 1, expected 0),而是使用常规方法。

您可以使用attr_accessor或更改您的代码:

description=