0

所以我试图在 Ruby 中创建一个字典对象,并让它作为项目的一部分通过一堆 RSPEC 测试。到目前为止一切都很好,但我被困在一项特定的测试中。这是该测试之前的 RSPEC:

require '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
end

到目前为止,除了最后一个测试“在检查给定关键字是否存在时不作弊”之外,一切都通过了。我正在努力思考如何才能让它通过,但到目前为止还没有成功。任何帮助将不胜感激。这是我到目前为止所拥有的:

class Dictionary
  attr_accessor :keywords, :entries
  def initialize 
    @entries = {}
     end
 def add(defs)
    defs.each do |word, definition|
      @entries[word] = definition
    end
  end
  def keywords
    input = []
    @entries.each do |key, value|
    input << key
    end
    input.sort  
  end
  def  include?(key)
    self.keywords.include?(keywords.to_s) 
  end
end

提前致谢!

4

3 回答 3

3

有一个错误:

self.keywords.include?(keywords.to_s) 

keywords返回一个数组。您不能将keywords.to_s其用作参数keywords.include?并期望它找到匹配项:

irb(main):002:0> 关键字 = %w[abc]
=> [“a”,“b”,“c”]
irb(main):003:0>keywords.to_s
=> "[\"a\", \"b\", \"c\"]"
irb(main):004:0>keywords.include?(keywords.to_s)
=> 假的
irb(main):005:0>keywords.include?('a')
=> 真

keywords因为如果你想找到它,你需要使用数组中的单个元素。请注意,这keywords.to_s是数组的字符串化版本,也可以是:'["a", "b", "c"]'。希望这将帮助您在下次遇到问题时识别问题。

文档include?

  a = [“a”,“b”,“c”]
  a.include?("b") #=> true
  a.include?("z") #=> false

所以,改变:

  def 包括?(键)
    self.keywords.include?(keywords.to_s)
  结尾

到:

  def 包括?(键)
    self.keywords.include?(key)
  结尾

“不作弊”是什么意思?代码如何作弊?它只做你告诉它的事情。之前的所有测试看起来都排除了“不作弊”块中正在测试的条件,这使得:

@d.include?('bird').should be_false # confirms not always returning true after add

值得包括在内。你可以使用:

@d.add('fish')
@d.include?('bird').should be_false # confirms not always returning true after add

如果你真的不确定你的代码是如何工作的。

与其keywords使用数组进行构建,@entries列表越大越慢,并且每次调用它都会导致运行速度变慢,而是利用已经是哈希include?的事实并使用它的方法:@entries

def keywords
  @entries.keys.sort
end

def include?(key)
  !!@entries[key]
end

或将此用于include?

def 包括?(键)
  @entry.key?(key)
结尾
于 2013-03-05T17:02:51.327 回答
1

正如完全迈克在评论中提到的那样,您想要的大多数功能已经存在于Hash. 对于您想要的略有不同的接口,您应该继承Hash.

class Dictionary < Hash
  def add(defs)
    defs = {defs => nil} unless defs.kind_of?(Hash)
    merge!(defs)
  end
  alias entries dup
  def keywords; keys.sort end
end
于 2013-03-05T16:58:42.033 回答
0

这是否让您知道如何通过“检查给定关键字是否存在时不作弊”?

@h = Hash.new{|h,k,v| h[k] = nil}
@h["fish"]
p @h #=> {"fish"=>nil}

当哈希中不存在密钥时运行该{|h,k,v| h[k] = nil}部分。它添加键并给它一个 nil 值。

于 2013-06-12T19:07:04.477 回答