来自TestFirst.org的Ruby中的字典类

时间:2015-03-10 08:09:55

标签: ruby dictionary

我试图从TestFirst.org解决字典问题。目标是让我的代码与测试规范一起使用。显然我得到了NoMethodError: undefined method '[]=' for nil: NilClass

我在下面发布了我的代码和测试规范。

由于某些原因,测试看起来无法读取我的添加和关键字方法。有人可以帮助我确定它的行为方式吗?

我的代码:

class Dictionary
    #initialization of entries
    def entries
        @hash = {}
    end

    def add(keyvalue)
        keyvalue.each do |key, value|
            @hash[key] = value  #create key-value pair in @hash
        end
    end

    def keywords
        key_array = []
        @hash.each {|key,value| key_array.push(key)}    #push key inside key_array
    end

end

测试规范:

require '11_dictionary'

describe Dictionary do   
  before do
    @d = Dictionary.new   
  end

  it 'is empty when created' do
    @d.entries.should == {}   
  end

  it 'can add whole entries with keyword and definition' do
    @d.add('fish' => 'aquatic animal')
    @d.entries.should == {'fish' => 'aquatic animal'}
    @d.keywords.should == ['fish']   
  end

  it 'add keywords (without definition)' do
    @d.add('fish')
    @d.entries.should == {'fish' => nil}
    @d.keywords.should == ['fish']   
  end

  it 'can check whether a given keyword exists' do
    @d.include?('fish').should be false   
  end

  it "doesn't cheat when checking whether a given keyword exists" do
    @d.include?('fish').should be false # if the method is empty, this test passes with nil returned
    @d.add('fish')
    @d.include?('fish').should be true # confirms that it actually checks
    @d.include?('bird').should be false # confirms not always returning true after add   
  end

  it "doesn't include a prefix that wasn't added as a word in and of itself" do
    @d.add('fish')
    @d.include?('fi').should be false   
  end

  it "doesn't find a word in empty dictionary" do
    @d.find('fi').should be_empty # {}   
  end

  it 'finds nothing if the prefix matches nothing' do
    @d.add('fiend')
    @d.add('great')
    @d.find('nothing').should be_empty   
  end

  it "finds an entry" do
    @d.add('fish' => 'aquatic animal')
    @d.find('fish').should == {'fish' => 'aquatic animal'}   
  end

  it 'finds multiple matches from a prefix and returns the entire entry (keyword + definition)' do
    @d.add('fish' => 'aquatic animal')
    @d.add('fiend' => 'wicked person')
    @d.add('great' => 'remarkable')
    @d.find('fi').should == {'fish' => 'aquatic animal', 'fiend' => 'wicked person'}   
  end

  it 'lists keywords alphabetically' do
    @d.add('zebra' => 'African land animal with stripes')
    @d.add('fish' => 'aquatic animal')
    @d.add('apple' => 'fruit')
    @d.keywords.should == %w(apple fish zebra)   
  end

  it 'can produce printable output like so: [keyword] "definition"' do
    @d.add('zebra' => 'African land animal with stripes')
    @d.add('fish' => 'aquatic animal')
    @d.add('apple' => 'fruit')
    @d.printable.should == %Q{[apple] "fruit"\n[fish] "aquatic animal"\n[zebra] "African land animal with stripes"}   
  end 
end

1 个答案:

答案 0 :(得分:2)

因为每个测试块都是单独执行的,所以,例如,在can add whole entries with keyword and definition执行:

@d.add('fish' => 'aquatic animal')

@hash对象中的@d实例变量未初始化。要修复它,您应该在对象初始化时初始化@hash

class Dictionary
  def initialize
    @hash = {}
  end

  def entries
    @hash
  end
  # etc.
end

或者,您可以创建私有访问者:

,而不是直接在@hash实例变量上操作
class Dictionary
  def entries
    hash
  end

  def keywords
    key_array = []
    hash.each {|key,value| key_array.push(key)}    #push key inside key_array
  end
  # etc.
  private

  def hash
    @hash ||= {}
  end
end