Extending Hash

I’m trying to create a modified version of a Hash that, if it doesn’t contain anything for a given key, will return whatever element it has that most closely matches the key. Here’s what I’ve done so far:

···

class FragHash < Hash
def
index = key.dup
while !self.has_key?(index) and index.chop! != nil
end
return self.default if index.empty?
return fetch(index)
end
end

so if I do the following:


h = FragHash.new
h[‘t’] = 23
puts h[‘test’]

the output is 23. In other words, it didn’t find the index “test” but it kept shortening the index until it found something that matches. The only problem I have now is that I want to make it so that when I call each() it also enumerates through the default value. However, I don’t know how to extend the each function (I’m still a little hazy on how to overload functions that use blocks). It would be nice if I could look at the source for the Hash class itself. Does anyone know where I can find it? Does anyone have any suggestions for how I might modify the each function?

Thanks,
Carl Youngblood

I’m trying to create a modified version of a Hash that, if it doesn’t contain
anything for a given key, will return whatever element it has that most closely
matches the key. Here’s what I’ve done so far:


class FragHash < Hash
def
index = key.dup
while !self.has_key?(index) and index.chop! != nil
end
return self.default if index.empty?
return fetch(index)
end
end

A Ruby-idiomatic way to do the while loop might be:
1 until self.has_key?(index) or index.chop! == nil

Use it if you think it’s more readable.

so if I do the following:


h = FragHash.new
h[‘t’] = 23
puts h[‘test’]

the output is 23. In other words, it didn’t find the index “test” but it kept
shortening the index until it found something that matches. The only problem I
have now is that I want to make it so that when I call each() it also
enumerates through the default value. However, I don’t know how to extend the
each function (I’m still a little hazy on how to overload functions that use
blocks). It would be nice if I could look at the source for the Hash class
itself. Does anyone know where I can find it? Does anyone have any
suggestions for how I might modify the each function?

Thanks,
Carl Youngblood

I’m not actually sure or your problem here Carl. What do you mean by the
“default” value? In your example above, won’t “each” yield [“t”, 23]?

Anyway, overriding each is not too hard. Here’s how you could implement
Hash#each from scratch if you wanted to. You can hopefully use this to
implement the functionality you want. (Warning, not tested.)

class Hash
def each(&block)
self.keys.each do |key|
value = self.[key]
block.call(key, value)
end
end
end

Hope this helps,
Gavin

···

From: “Carl Youngblood” carl@youngbloods.org

Thanks for the help, Gavin!

Carl

···

----- Original Message -----

Anyway, overriding each is not too hard. Here’s how you could implement
Hash#each from scratch if you wanted to. You can hopefully use this to
implement the functionality you want. (Warning, not tested.)

class Hash
def each(&block)
self.keys.each do |key|
value = self.[key]
block.call(key, value)
end
end
end

Hope this helps,
Gavin