I’m working on a text game engine, and have run into a snag while developing the exploration module. When I try and instantiate my Location class with a block argument from a fixture, I’m getting this error:
ArgumentError, “wrong number of arguments (3 for 2)
for this code:
# 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
It’s pretty obviously a syntax error somewhere, where a block isn’t getting converted to a proc or vice versa, but I’ve been over the code a dozen times and can’t find it. If any eagle-eyed readers can help me out, I would be eternally grateful.
Source Files:
The full source is available on Github, but is split between two repositories:
To run code or specs, the plugin code needs to be placed inside the engine directory in vendor/modules/plugins/explore.
Backtrace:
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)>'
Edit 2012年06月06日:
- Replaced sample code with actual, non-conforming code
- Added links to full project
rspec sometimes swallows backtraces in ways that aren’t completely helpful (i think you can use the -b option to suppress this ) – the error is (I think) elsewhere.
From my reading of the code, mushroom kingdom’s block is instance_evaled on an instance of
Explore::Parsers::LocationParserThis class defines a
gomethod like sobut mushroom kingdom does
where
value.paramsis the hash of options used to create an edge at the bottom of your edges fixtures file. In at least one case, that hash has 2 objects in it, so when you splat that you end up callinggowith 3 arguments. Given thatgoappears to take a hash as its second argument, was that splat really intentional?