From addbe1b85693ee06d67b1acdaee322816c1d3a18 Mon Sep 17 00:00:00 2001 From: Ian White Date: Fri, 20 Aug 2010 20:13:01 +0100 Subject: [PATCH] Pickle::Ref now has responsibility for parsing the index as an integer. The index word is available as #index_word --- lib/pickle/ref.rb | 16 +++++++++++++--- spec/pickle/ref_spec.rb | 19 +++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/pickle/ref.rb b/lib/pickle/ref.rb index 9bec2e09..eba2852c 100644 --- a/lib/pickle/ref.rb +++ b/lib/pickle/ref.rb @@ -7,8 +7,9 @@ class InvalidPickleRefError < RuntimeError # raises an error if the pickle_ref is invalid class Ref include Parser::Matchers + include Parser::Canonical - attr_reader :factory, :index, :label + attr_reader :factory, :index, :index_word, :label def initialize(string) parse_ref(string) @@ -17,7 +18,8 @@ def initialize(string) protected def parse_ref(orig) str = orig.dup - @index = parse_index!(str) + @index_word = parse_index!(str) + @index = index_word_to_i(@index_word) if @index_word @factory = parse_factory!(str) @label = parse_label!(str) raise InvalidPickleRefError, "'#{orig}' has superfluous: '#{str}'" unless str.blank? @@ -34,7 +36,7 @@ def parse_index!(string) # parse the factory name from the given string, remove the factory name and optional prefix # @return factory_name or nil def parse_factory!(string) - remove_from_and_return_1st_capture!(string, /^(?:#{match_prefix} )?(#{match_factory})/) + canonical remove_from_and_return_1st_capture!(string, /^(?:#{match_prefix} )?(#{match_factory})/) end # parse the label, removing it if found @@ -49,5 +51,13 @@ def remove_from_and_return_1st_capture!(string, regexp) match_data[1] end end + + def index_word_to_i(word) + case word + when 'last' then -1 + when 'first' then 0 + else word.gsub(/\D/,'').to_i - 1 + end + end end end \ No newline at end of file diff --git a/spec/pickle/ref_spec.rb b/spec/pickle/ref_spec.rb index b47c2978..7cf2ffff 100644 --- a/spec/pickle/ref_spec.rb +++ b/spec/pickle/ref_spec.rb @@ -5,9 +5,9 @@ describe ".new 'colour'" do subject { Pickle::Ref.new('colour') } - its(:index) { should be_nil } + its(:index) { should be_nil } its(:factory) { should == 'colour' } - its(:label) { should be_nil } + its(:label) { should be_nil } end describe "with a prefix" do @@ -31,22 +31,25 @@ describe ".new('1st colour')" do subject { Pickle::Ref.new('1st colour') } - its(:index) { should == '1st' } + its(:index_word) { should == '1st' } + its(:index) { should == 0 } its(:factory) { should == 'colour' } - its(:label) { should be_nil } + its(:label) { should be_nil } - ['2nd', 'first', 'last', '3rd', '4th'].each do |index| - describe ".new('#{index} colour')" do - subject { Pickle::Ref.new("#{index} colour") } + {'2nd' => 1, 'first' => 0, 'last' => -1, '3rd' => 2, '4th' => 3}.each do |word, index| + describe ".new('#{word} colour')" do + subject { Pickle::Ref.new("#{word} colour") } its(:index) { should == index} + its(:index_word) { should == word } end end describe "the 2nd colour" do subject { Pickle::Ref.new('the 2nd colour') } - its(:index) { should == '2nd' } + its(:index_word) { should == '2nd' } + its(:index) { should == 1 } its(:factory) { should == 'colour' } end end