如何创建一个将散列(有或没有指定值)作为参数的方法?
How can I create a method that takes a hash (with or without an assigned value) as an argument?
所以我首先要完成测试,但有点卡住了。到目前为止,这是我的代码:
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 方法以获取 key/value 对,或者仅获取一个值为 nil 的键?第一个测试指定散列在创建时为空,所以我不能在那里给它默认值。
可能会检查传递给 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”来检查参数类型。
如果您总是将字符串传递给该方法,您可以只为第二个字符串设置默认值...类似于以下内容:
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
更新,作为标准要求
我更新了上面的方法以允许不是字符串的单词(如您所指出的)。
将散列传递给方法时,它被视为单个参数。
Key => Value 对是隐含的散列,因此将散列传递给方法时,以下内容通常相同:
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
所以我首先要完成测试,但有点卡住了。到目前为止,这是我的代码:
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 方法以获取 key/value 对,或者仅获取一个值为 nil 的键?第一个测试指定散列在创建时为空,所以我不能在那里给它默认值。
可能会检查传递给 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”来检查参数类型。
如果您总是将字符串传递给该方法,您可以只为第二个字符串设置默认值...类似于以下内容:
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
更新,作为标准要求
我更新了上面的方法以允许不是字符串的单词(如您所指出的)。
将散列传递给方法时,它被视为单个参数。
Key => Value 对是隐含的散列,因此将散列传递给方法时,以下内容通常相同:
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