new hash as part of a class construct

9 views
Skip to first unread message

Roman Land

unread,
Jan 31, 2010, 3:15:04 PM1/31/10
to mootool...@googlegroups.com
Hi,

I found out (the "bug" way ;) ) that if I write a class like so:

MyClass = new Class({
   
    myHash : new Hash()
   
})

Later I will use this class

a = new MyClass();

b = new MyClass();

I would seem that the hash is actually being shared :P
My work around is to init the hash in the "initialize" method.

Any thought about this? I dont like the aesthetics of this implementation...

Cheers
Roman

--
---
"Make everything as simple as possible, but not simpler."

- Albert Einstein

אריה גלזר

unread,
Jan 31, 2010, 3:21:32 PM1/31/10
to mootool...@googlegroups.com
this might actually prove to be quite useful - i can see how this might let you share variables between different instances of a class without using a global object. this is sometimes a very desirable functionality!
-----------
אריה גלזר
052-5348-561
5561

Roman Land

unread,
Jan 31, 2010, 3:35:22 PM1/31/10
to mootool...@googlegroups.com
haha, classic :) "this is not a bug! its a feature!" :)

I am happy you find it useful, although if there's no documentation that says something of the sorts I wouldnt build my application around a possible bug..

What says moo dev team?

Aaron Newton

unread,
Jan 31, 2010, 3:43:41 PM1/31/10
to mootool...@googlegroups.com
1) if you have shared objects between classes, put them in closures to avoid global scope:

(function(){

var foo = new Hash();

this.MyClass = new Class({...}); //"this" here is the window

})();

2) the proper solution here is what you have; to declare the hash on instantiation. If you want to be able to extend that object with subclasses, then you can make the property an object and cast it to a hash on init:

var Foo = new Class({
  bar: {...},
  initialize: function(){
    this.h_bar = new Hash(this.bar);
  }
});
var Foo2 = new Class({
  Extends: Foo,
  bar: { ...some other stuff...},
  etc...
});

Eneko Alonso

unread,
Jan 31, 2010, 3:54:19 PM1/31/10
to mootool...@googlegroups.com
From my understanding, without getting in depth of how Mootools works, here is what happens:

When the js parser executes the line "MyClass = new Class.." it creates the native object that is passed to the Class function. In order to create this native object, it has to create an instance of a Hash, which gets assigned to the myHash property.

So far, we have a hash object created in memory and the result object returned by Class. This resulting object has a pointer to the Hash object in memory: the myHash property.

When you create new instances of this object, you are just cloning that pointer, which keeps pointing to the same Hash object in memory. Again, these two lines do not create a new instance of a Hash, but just clone the pointer to the original instance.

a = new MyClass();
b = new MyClass();

If I'm not mistaken, this would happen with any object instanced in the declaration of a class.

In the other hand, when you put something in the initialize method (class constructor), it does not get executed until the class (MyClass) is instantiated.

That's why, in general, class properties should be only static values and everything that requires instantiating new objects should be done in the constructor.

Please, let me know if I'm wrong.

Roman Land

unread,
Jan 31, 2010, 4:04:03 PM1/31/10
to mootool...@googlegroups.com
@Aaron, good tip, will see if I can use that also.

@Eneko, that is my understanding also, although knowing JS I am not sure how it will behave further down the road when they overwrite the same value, they might split into two different objects with overlaps and complement each other.. (my JS experience with this is limited.. please someone correct me if I am wrong..)
Also, I dont want to overload the initialization class, this looks messy and hard to understand what are the instance variables are..

Might I suggest this "feature" be documented somehow? :)

I will open a light house ticket to see if I can pass this ..

Roman Land

unread,
Jan 31, 2010, 4:05:11 PM1/31/10
to mootool...@googlegroups.com
errr not initialization class - initialization method ..

Aaron Newton

unread,
Jan 31, 2010, 8:59:06 PM1/31/10
to mootool...@googlegroups.com
When you create a new class MooTools dereferences any objects using the Object.reset method (not documented). Go look at the source of Class.js.

You'll see that this method iterates over all the properties, dereferencing all the objects and arrays to prevent this pollution. However, it switches on the type of property, dereferencing arrays and object. Hash, however, returns $type "hash" ($type($H({})) == "hash"), so it doesn't dereference. That's why instantiating the hash from a property on instantiation will work.

Eneko Alonso

unread,
Jan 31, 2010, 11:13:41 PM1/31/10
to mootool...@googlegroups.com
Interesting, thanks for the clarification, Aaron.

אריה גלזר

unread,
Feb 1, 2010, 2:19:18 AM2/1/10
to mootool...@googlegroups.com
On Sun, Jan 31, 2010 at 22:43, Aaron Newton <aa...@iminta.com> wrote:
1) if you have shared objects between classes, put them in closures to avoid global scope:

i know this. It just seems cool to be able to point to a shared variable using this (same as using private static variables in other OOP languages such as PHP). but i guess that in order for this to work it needs to be much more transparent (for example adding a statics member that will contain these static variables). i would have tried to implement something like this but if you say this is deep within the core file i doubt this will be easy to overload. 

You'll see that this method iterates over all the properties, dereferencing all the objects and arrays to prevent this pollution. However, it switches on the type of property, dereferencing arrays and object. Hash, however, returns $type "hash" ($type($H({})) == "hash"), so it doesn't dereference. That's why instantiating the hash from a property on instantiation will work.

 the querstion is if this is simply an overlooked scenario or if this is a wanted behavior

Aaron Newton

unread,
Feb 1, 2010, 10:53:23 AM2/1/10
to mootool...@googlegroups.com
 the querstion is if this is simply an overlooked scenario or if this is a wanted behavior

That is a decent question. It would require a minor fix (Object.reset would check for type == array || object || hash). Why don't you open a lighthouse ticket for it? 
Reply all
Reply to author
Forward
0 new messages