所以我首先通过测试并且有点卡住了。到目前为止,这是我的代码:
class Dictionary
attr_accessor :entries, :keywords, :item
def initialize
@entries = {}
end
def add(item)
item.each do |words, definition|
@entries[words] = definition
end
end
def keywords
@entries.keys
end
end#class
我在这里停留在rspec测试中:
it 'add keywords (without definition)' do
@d.add('fish')
@d.entries.should == {'fish' => nil}
@d.keywords.should == ['fish']
end
如何切换我的add方法以获取键/值对,或只是将值设置为nil的键?第一个测试指定哈希在创建时是空的,所以我不能在那里给它默认值。
答案 0 :(得分:3)
可以检查传递给add
方法的参数的类型。不管它是Enumerable
,显然是Array
s,Hash
es等中包含的mixin,只需将其值分配给nil
:
def add(item)
case item
when Enumerable
item.each do |words, definition|
@entries[words] = definition
end
else
@entries[item] = nil
end
end
请注意case
使用“case equality”来检查参数类型。
答案 1 :(得分:2)
如果你总是将Strings传递给方法,你可能只有第二个字符串的默认值......如下所示:
def add(word, definition = nil)
@entries[word] = definition
end
所以你的代码看起来像这样:
class Dictionary
attr_accessor :entries, :keywords, :item
def initialize
@entries = {}
end
def add(word, definition = nil)
@entries[word] = definition
end
def keywords
@entries.keys
end
end#class
如果您想要多次添加(即add key: "word", with: "many", options: nil
),那么该设计可能对您不起作用,您需要创建一个可以在@mudasobwa建议的方面工作的解决方案。也许:
def add(word, definition = nil)
return @entries[word] = definition unless word.is_a?(Enumerable)
return @entries.update word if word.is_a?(Hash)
raise "What?!"
end
以par请求更新
我更新了上面的方法以允许不是字符串的单词(正如您所指出的那样)。
将哈希传递给方法时,它被视为单个参数。
Key =>值对是隐含的哈希,因此在将哈希传递给方法时,以下内容通常是相同的:
Hash.new.update key: :value
Hash.new.update({key: :value})
请考虑以下事项:
def test(a,b = nil)
puts "a = #{a}"
puts "b = #{b}"
end
test "string"
# => a = string
# => b =
test "string", key: :value, key2: :value2
# => a = string
# => b = {:key=>:value, :key2=>:value2}
test key: :value, key2: :value2, "string"
# Wrong Ruby Syntax due to implied Hash, would raise exception:
# => SyntaxError: (irb):8: syntax error, unexpected '\n', expecting =>
test({key: :value, key2: :value2}, "string")
# correct syntax.
这就是为什么当你通过add 'fish' => 'aquatic'
时,它只被认为是一个参数,一个哈希 - 而不是add 'fish', 'aquatic'
,它将两个参数传递给方法。
如果您的方法必须接受不同类型的参数(字符串,散列,数字,符号,数组),您将需要以不同的方式处理每个选项。
这就是为什么@mudasobwa建议检查第一个参数的类型。他的解决方案相当不错。
我的版本对代码来说有点短,但它的运行方式相同。
def add(word, definition = nil)
return @entries[word] = definition unless word.is_a?(Enumerable)
return @entries.update word if word.is_a?(Hash)
raise "What?!"
end