Hi all,

I'm new to the group. I've searched for a topic like this and didn't
find any, so here are my thoughts about Prototype's Hash
implementation.

Reading the API, i saw that whenever you add a key to a Hash, that has
the same name of a already existing property in its prototype, that
property is lost to the new value, obviously. You can see that happen
in the API's example.

I managed to overcome this problem by adding an Associative Array
inside the Hash structure, meaning that the Hash class is just a
façade to the proper structure. Although there is no problem of adding
like "keys", "_each" or anything to this improved Hash, I had to
override some Enumerable methods, and I think that I may have to
overide most of them, didn't check it all, leading to more and more
code for just a simple thing, although I like a lot this simples
thing, hehe.

I don't know if you already thought of that, but here is the code for
apreciation, it functions just like a normal Prototype Hash:

var Hash = Class.create();
Object.extend(Hash, {
  toQueryString: function(obj) {
    var parts = [];

          this.prototype._each.call(obj, function(pair) {
      if (!pair.key) return;

      if (pair.value && pair.value.constructor == Array) {
        var values = pair.value.compact();
        if (values.length < 2) pair.value = values.reduce();
        else {
                key = encodeURIComponent(pair.key);
          values.each(function(value) {
            value = value != undefined ? encodeURIComponent(value) :
'';
            parts.push(key + '=' + encodeURIComponent(value));
          });
          return;
        }
      }
      if (pair.value == undefined) pair[1] = '';
      parts.push(pair.map(encodeURIComponent).join('='));
          });

    return parts.join('&');
  }
});

Object.extend(Hash.prototype, Enumerable);
Object.extend(Hash.prototype, {
  hash: [],
  initialize: function(obj) {
    if(obj)
      Object.extend(this.hash, obj);
  },
  _each: function(iterator) {
    for (var key in this.hash) {
      var value = this.hash[key];
      if (value && value == Array.prototype[key]) continue;

      var pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  },

  keys: function() {
    return this.pluck('key');
  },

  values: function() {
    return this.pluck('value');
  },

  merge: function(hash) {
    return $H(hash).inject(this.hash, function(mergedHash, pair) {
      mergedHash[pair.key] = pair.value;
      return mergedHash;
    });
  },

  remove: function() {
    var result;
    for(var i = 0, length = arguments.length; i < length; i++) {
      var value = this.hash[arguments[i]];
      if (value !== undefined){
        if (result === undefined) result = value;
        else {
          if (result.constructor != Array) result = [result];
          result.push(value)
        }
      }
      delete this.hash[arguments[i]];
    }
    return result;
  },

  toQueryString: function() {
    return Hash.toQueryString(this);
  },

  inspect: function() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  },

  put: function(key, value) {
    var old = this.hash[key];
    this.hash[key] = value;
    return old;
  },

  toArray: function() {
    return this.map();
  },

  collect: function(iterator) {
    var results = [];
    this._each(function(value, index) {
      results.push((iterator || Prototype.K)(value, index));
    });
    return results;
  },
});

Cheers,
Rafael


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to