传入&块时的Ruby参数计数错误

时间:2012-06-06 17:22:58

标签: ruby rspec

我正在开发一个文本游戏引擎,并且在开发探索模块时遇到了麻烦。当我尝试使用fixture中的块参数实例化我的Location类时,我收到此错误:

  

ArgumentError,“错误的参数数量(3为2)

代码:

# in lib/explore/models/location.rb, line 15
class Location < RoundTable::Controllers::ActionDelegate
  # ... code omitted for brevity

  def initialize(slug, params = nil, &block)
    # ... code omitted for brevity

    if block_given?
      parser = Explore::Parsers::LocationParser.new(self)
      parser.instance_eval &block
    end # if
  end # constructor

  # ... code omitted for brevity
end # class Location

# in spec/fixtures/models/locations.rb, line 38
location :mushroom_kingdom, :name => "Mushroom Kingdom" do
  edges = Explore::Fixtures[:edges]
  edges.each do |key, value|
    go value.location, *value.params
  end # each
end # location

# in spec/models/location_spec.rb, line 193
context "initialized with block" do
  let :fixture do fixtures[:mushroom_kingdom] end

  subject { described_class.new fixture.slug, fixture.params, &fixture.block }

  it { puts subject.inspect }
end # context initialized with block

这显然是某个地方的语法错误,其中一个块没有转换为proc或反之亦然,但我已经在代码上打了十几次而找不到它。如果任何一个鹰眼的读者可以帮助我,我会永远感激。

源文件:

完整的源代码可以在Github上获得,但是在两个存储库之间分开:

要运行代码或规范,需要将插件代码放在vendor / modules / plugins / explore中的引擎目录中。

回溯:

1) RoundTable::Vendor::Plugins::Explore::Models::Location initialization with block 
     Failure/Error: it { expect { described_class.new fixture.slug, fixture.params, &fixture.block }.not_to raise_error ArgumentError }
       expected no ArgumentError, got #<ArgumentError: wrong number of arguments (3 for 2)>
     # ./spec/models/location_spec.rb:33:in `block (4 levels) in <top (required)>'

2) RoundTable::Vendor::Plugins::Explore::Models::Location initialized with block 
     Failure/Error: subject { described_class.new fixture.slug, fixture.params, &fixture.block }
     ArgumentError:
       wrong number of arguments (3 for 2)
     # ./lib/explore/parsers/location_parser.rb:39:in `go'
     # ./spec/fixtures/models/locations.rb:41:in `block (2 levels) in <module:Models>'
     # ./spec/fixtures/models/locations.rb:40:in `each'
     # ./spec/fixtures/models/locations.rb:40:in `block in <module:Models>'
     # ./lib/explore/models/location.rb:49:in `instance_eval'
     # ./lib/explore/models/location.rb:49:in `initialize'
     # ./spec/models/location_spec.rb:196:in `new'
     # ./spec/models/location_spec.rb:196:in `block (3 levels) in <top (required)>'
     # ./spec/models/location_spec.rb:198:in `block (3 levels) in <top (required)>'

编辑2012年06月06日:

  • 使用实际的,不符合规范的代码替换示例代码
  • 添加了完整项目的链接

3 个答案:

答案 0 :(得分:2)

rspec有时会以不完全有用的方式吞噬回溯(我认为你可以使用-b选项来抑制它) - 错误是(我认为)其他地方。

从我对代码的阅读中,蘑菇王国的块是Explore::Parsers::LocationParser

的实例上的instance_evaled

此类定义了go方法,如此

def go(location, params = {})

但蘑菇王国确实

go value.location, *value.params

其中value.params是用于在边夹具文件底部创建边的选项的哈希值。在至少一种情况下,该哈希中有2个对象,所以当你发现最后用3个参数调用go时。鉴于go似乎将哈希作为其第二个参数,那splat真的是故意的吗?

答案 1 :(得分:0)

尝试:

Location.new(fixture[:slug], fixture[:params], fixture[:block])

答案 2 :(得分:0)

这是你拥有的东西的复制品。仍在寻找问题。

class Location
   def initialize(slug, params = nil, &block)
     yield
   end
end


mushroom_kingdom = 'mushroom kingdom'
fixture = {
  :slug => mushroom_kingdom,
  :params => { :princess => :toadstool },
  :block => lambda { puts "It'sa me, Mario!" }
}
l = Location.new(fixture[:slug], fixture[:params],&fixture[:block])

要获得相同的错误,我必须Location.new(fixture[:slug], fixture[:params], 'abcd', &fixture[:block])Location.new(fixture[:slug], fixture[:params],fixture[:block])。这几乎就好像你的&不是真正的&符号。是否有其他字符编码?前两个参数中的任何一个都有逗号吗?

并且,您确定错误来自此代码吗?您共享的内容没有语法错误。