Editing Topic: RCR261 Project: RCR | RCRchive home

RCR 261: introducing Hash-like mixin

submitted by grenzi on Fri Jun 18 2004 08:54:53 AM -0700

Status: pending


Abstract

provide a mixin for key->value mappings

Problem

there are many classes that implements key->value mappings, mostly via #[] and #[]=, but they are not build around a common base, so they show up little quirks . Furthermore, it is hard to write a new hash-like class or inherit from Hash.

Proposal

Introducing a Map module would reduce code and allow developers to write their own Hash-like objects trusting that those could fit where others does.

Analysis

Please consider that Map is just a placeholder while people think of a name like Mappable that is more Likeable.

As of now writing an object that provides key->value mappings is hard. More than this, inherithing from an hash is hard cause it requires you to override near every method.

Key->value maps are extremely commons even in the stdlib (grepping "def []=" gives >30 results), yet the complete interface is somewhat hidden and hard to use, because few of the users of #[]= implemented the whole mapping functionality (say, PStore does not respond_to #store)

If a mixin is available for this it would be much easier for everyone to write this kind of objects.

As a (useful?) side effect it makes easier for users to use some form of type checking or interface checking (i.e. no confusion beetween Array#[] an Map#[])

Providing a simple set of methods would make classes mixing in this Map module very feature rich.

In the mixin we could rely on:

#[] or #fetch or a private #get method
#[]= or #store or a private #put method
#delete
#key? or #has_key?


This is near to the interface needed in perl to build an object that can override an hash with Tie.

The java Map interface is richer in that it provides a keySet() method that gives a set of the keys contained in the map.

If we choose that an Hashable/Map object can always provide a #keys method (or #each_key)we can include Enumerable in Map trivially, and implement a dumb #key? like #keys.member?

Possibly we could provide two different interfaces: OpaqueMap and Map (better names wanted) with the only difference of the #keys method.

Please note that this is not some kind of modification of the language, it is merely a refactoring based on actual usage.
It could have been useless to provide this in the early ruby days, yet it is important to provide it as of now, beacause the usage for Classes that provide such a behaviour is quite high, so consistence and reliability of an interface is a bigger need

Implementation

Mine would be buggy and long, but you can take a tentative loook at matju's MetaRuby package, where he provides an HollowHash that is mostly like the proposed Map mixin. See: http://artengine.ca/matju/MetaRuby/


Back to RCRchive.


RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog