I am writing a DSL based on a pattern I have successfully used in the past. I thought this would work out of the box but I am getting an error that I just can't figure out, so any help is appreciated.
Here is the method to add a test:
module PPEKit
module Tests
def add_test(id, &block)
@_tests ||= {}
@_tests[id] = Test.new(id, &block) unless @_tests.include? id
end
end
end
Here is the Test class definition:
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
The Tests module is included in a PPEKit::Product class as so:
module PPEKit
class Product
include Tests
I am not showing method_missing because the error I am getting happens during the instance_eval call. I have tried initializing the Test object using both types of block arity with the same result:
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
Both of the definitions above give the following error:
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'
Here is a peek at the Test class in pry right before calling instance_eval:
[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_
Again, thanks in advance.
regards
You don't have description(arg)
, only a getter description()
and a setter description=(arg)
. And so when you do description 'my test description'
it calls the getter with an argument it doesn't expect and you get wrong number of arguments (given 1, expected 0)
.
In the tutorial they don't use attr_accessor
, but regular methods.
You could use description=
or change your code:
module PPEKit
module Tests
def add_test(id, &block)
@tests ||= {}
@tests[id] = Test.new(id, &block)
end
class Test
def initialize(id, &block)
@id = id
@description = nil
block.arity < 1 ? instance_eval(&block) : block.call(self)
end
def description(description)
@description = description
end
end
end
end
include PPEKit::Tests
add_test :create_article do
description 'creating article'
end
add_test :delete_article do |t|
t.description 'deleting article'
end
puts @tests
# {:create_article=>#<Test:0x00000000d91ac0 @id=:create_article, @description="creating article">,
# :delete_article=>#<Test:0x00000000d919d0 @id=:delete_article, @description="deleting article">}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.