所以我正在尝试在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
提前致谢!
答案 0 :(得分:3)
有一个错误:
self.keywords.include?(keywords.to_s)
keywords
返回一个数组。您不能将keywords.to_s
用作keywords.include?
的参数,并希望它找到匹配项:
irb(main):002:0> keywords = %w[a b c] => ["a", "b", "c"] irb(main):003:0> keywords.to_s => "[\"a\", \"b\", \"c\"]" irb(main):004:0> keywords.include?(keywords.to_s) => false irb(main):005:0> keywords.include?('a') => true
因为如果要查找它,您需要在keywords
数组中使用单个元素。请注意,keywords.to_s
是数组的字符串化版本,也可以是:'["a", "b", "c"]'
。希望这会帮助您在下次遇到问题时识别问题。
来自include?
的{{1}}:
a = [ "a", "b", "c" ] a.include?("b") #=> true a.include?("z") #=> false
所以,改变:
def include?(key) self.keywords.include?(keywords.to_s) end
为:
def include?(key) self.keywords.include?(key) end
“不作弊”是什么意思?代码怎么骗?它只做你说的话。之前的所有测试看起来都像是排除了“不作弊”区块中正在测试的条件,而这只是:
@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 include?(key) @entries.key?(key) end
答案 1 :(得分: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
答案 2 :(得分:0)
这是否能让您了解如何通过“在检查给定关键字是否存在时不作弊”?
@h = Hash.new{|h,k,v| h[k] = nil}
@h["fish"]
p @h #=> {"fish"=>nil}
当哈希中的键不时,{|h,k,v| h[k] = nil}
部分运行。它添加了密钥并给它一个零值。