I’m creating a object of hash in order to write a little script that reads in a file a line at a time, and assigns arrays into my hash class. I get wildly different results depending if I subclass Hash or not, plus using super changes things which I don’t’ understand.
My main issue is that without subclassing hash ( < Hash) it works perfectly, but I get no methods of Hash (like to iterate over the keys and get things out of it…. Subclassing Hash lets me do those things, but it seems that only the last element of the hashed arrays is ever stored…. so any insight into how you get the methods of a subclass. The Dictionary class is a great example I found on this site, and does exactly what I want, so I’m trying to understand how to use it properly.
filename = 'inputfile.txt.'
# ??? class Dictionary < Hash
class Dictionary
def initialize()
@data = Hash.new { |hash, key| hash[key] = [] }
end
def [](key)
@data[key]
end
def []=(key,words)
@data[key] += [words].flatten
@data[key]
# super(key,words)
end
end
listData = Dictionary.new
File.open(filename, 'r').each_line do |line|
line = line.strip.split(/[^[:alpha:]|@|\.]/)
puts "LIST-> #{line[0]} SUB-> #{line[1]} "
listData[line[0]] = ("#{line[1]}")
end
puts '====================================='
puts listData.inspect
puts '====================================='
print listData.reduce('') {|s, (k, v)|
s << "The key is #{k} and the value is #{v}.\n"
}
If anyone understands what is going on here subclassing hash, and has some pointers, that would be excellent.
Running without explicit < Hash:
./list.rb:34:in `<main>': undefined method `reduce' for #<Dictionary:0x007fcf0a8879e0> (NoMethodError)
That is the typical error I see when I try and iterate in any way over my hash.
Here is a sample input file:
listA billg@microsoft.com
listA ed@apple.com
listA frank@lotus.com
listB evanwhite@go.com
listB joespink@go.com
listB fredgrey@stop.com
I can’t reproduce your problem using your code:
But of course you won’t get
reduceif you don’t subclass or include a class/module that defines it, or define it yourself!The way you have implemented
Dictionaryis bound to have problems. You should callsuperinstead of reimplementing wherever possible. For example, simply this works:If you want to reimplement how and where the internal hash is stored (i.e., using
@data), you’d have to reimplement at leasteach(since that is what almost all Enumerable methods call to) and getters/setters. Not worth the effort when you can just change one method instead.