我开始在Test-First上解决一些示例问题,并制定了一个解决方案,该解决方案通过使用Ruby 1.8.7通过了所有RSpec测试。我刚刚升级了我的操作系统,Ruby 也升级了;我的代码不再通过 RSpec 测试。谁能帮我理解为什么这不再有效了?
我的代码
def entries
@d
end
错误消息
失败:
1)字典可以添加带有关键字和定义的整个条目
Failure/Error: @d.entries.should == {'fish' => 'aquatic animal'}
expected: {"fish"=>"aquatic animal"}
got: {["fish"]=>["aquatic animal"]} (using ==)
差异:
@@ -1,2 +1,2 @@
-"fish" => "aquatic animal"
+["fish"] => ["aquatic animal"]
#
我不知道要更改格式的内容。(RSpec 测试之一是@d在创建时必须为空,因此当我尝试通过输入显式格式来修改@d时,它也失败了,但我想象这里有一个简单的类型问题我不明白。
更新:更多代码
class Dictionary
def initialize d = {}
@d = d
end
def entries
@d
end
def keywords
@d.keys.sort
end
def add words
n_key = words.keys
n_val = words.values
@d[n_key] = n_val
end
end
看起来您正在尝试通过一次添加几个单词来进行某种大规模分配,但这不是这样做的方法。
Ruby Hash可以有任何东西作为键,这包括事物数组。它不像JavaScript,它会自动转换为字符串,或者其他语言,这些语言具有相同类型的转换为特定的字典键类型。在 Ruby 中,任何对象都可以。
所以你的添加单词方法应该是:
def add words
words.each do |word, value|
@d[word] = value
end
end
作为注释,使用像@d
这样的名称是非常糟糕的形式。试着更具体地说明那是什么,否则你就有可能无休止地混淆人们。充满@d
、x
和S
的程序很难调试和维护。如果有点冗长,最好清楚,而不是简洁和模棱两可。
其次,不清楚你的Dictionary
类与Hash
本身有什么不同。也许你可以把它做成一个子类,省去一些麻烦。例如:
class Dictionary < Hash
def keywords
keys.sort
end
def add words
merge!(words)
end
end
一般来说,最好使用核心 Ruby 类来做你想做的事情,然后从那里开始构建。重新发明轮子会导致不兼容和沮丧。内置的 Hash 类有一大堆实用工具方法,这些方法对于进行数据转换、转换和迭代非常方便,而创建自己的不透明包装类会丢失这些东西。
特别是merge!
方法将数据添加到现有哈希中,这正是您想要的。