I have a dictionary class and want to be able to push keys (as keywords) and values (as definitions) into an empty hash with an 'add' method. I don't understand how to syntactically write that. I have included an RSPEC file too.
ruby:
class Dictionary
attr_accessor :keyword, :definition
def entries
@hash = {}
end
def add(options)
options.map do |keyword, definition|
@hash[keyword.to_sym] = definition
end
end
end
Rspec:
require 'dictionary'
describe Dictionary do
before do
@d = Dictionary.new
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
Any help is appreciated. Thank you!
UPDATE: Thank you Dave Newton for replying. I used your code and got this error:
ERROR:
*Failure/Error: @d.keywords.should == ['fish']
NoMethodError:
undefined method `keywords' for #<Dictionary:0x007fb0c31bd458
@hash={"fish"=>"aquatic animal"}>*
I get a different error when I convert 'word' into a symbol using @hash[word.to_sym] = defintion
*Failure/Error: @d.entries.should == {'fish' => 'aquatic animal'}
expected: {"fish"=>"aquatic animal"}
got: {:fish=>"aquatic animal"} (using ==)
Diff:
@@ -1,2 +1,2 @@
-"fish" => "aquatic animal"
+:fish => "aquatic animal"*
Hash literals use the curly braces instead of square brackets and the key value pairs are joined by =>. For example, a hash with a single key/value pair of Bob/84 would look like this: { "Bob" => 84 }. Additional key/value pairs can be added to the hash literal by separating them with commas.
Creating an array of hashes You are allowed to create an array of hashes either by simply initializing array with hashes or by using array. push() to push hashes inside the array. Note: Both “Key” and :Key acts as a key in a hash in ruby.
To append a new value to the array of values associated with a particular key, use push : push @{ $hash{"a key"} }, $value; The classic application of these data structures is inverting a hash that has many keys with the same associated value. When inverted, you end up with a hash that has many values for the same key.
Instantiate your hash in Dictionary
's initialize
:
class Dictionary
def initialize
@hash = {}
end
def add(defs)
defs.each do |word, definition|
@hash[word] = definition
end
end
end
Right now you have no hash until you call entries
, which you don't.
entries
should return the existing hash, not create a new one.
keywords
should return the hash's keys.
You do not need accessors for keyword
and definition
. Such singular items are meaningless in a dictionary class. You might want something like lookup(word)
that returned a definition.
Also, you convert words to symbols, but I don't know why–particularly since you use string keys in your spec. Pick one, although I'm not convinced this is a case where symbols add value.
Please consider variable naming carefully to provide as much context as possible.
Looking at your Rspec, It looks like you need this setup.
class Dictionary
def initialize
@hash = {}
end
def add(key_value)
key_value.each do |key, value|
@hash[key] = value
end
end
def entries
@hash
end
def keywords
@hash.keys
end
end
Do not use key.to_sym
in add method, just key
To give flexibility to add method, I can return the self object to continuesly add.
def add(key_value)
key_value.each do |key, value|
@hash[key] = value
end
self
end
So, I can do this now.
@d.add("a" => "apple").add("b" => "bat")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With