Extended properties in EOL

Below is a simple metamodel (in Emfatic) for modelling Trees (however interesting this might be)

package SimpleTree;

class Tree {
	attr String name;
	ref Tree#children parent;
	val Tree[*]#parent children;
}

Now, what we want to do is to traverse a model that conforms to this metamodel and calculate and print the depth of each Tree in it. We can do this using this simple EOL program:

var depths := new Map;

for (n in Tree.allInstances.select(t|not t.parent.isDefined())) {
	n.setDepth(0);
}

for (n in Tree.allInstances) {
	(n.name + ' ' + depths.get(n)).println();
}

operation Tree setDepth(depth : Integer) {
	depths.put(self,depth);
	for (c in self.children) {
		c.setDepth(depth + 1);
	}
}

Because the Tree EClass doesn’t have a depth property, we have to use the depths Map to store the calculated depth of each Tree. Another solution would be to add a depth property to the Tree EClass so that its instances can store such information; but applying this tactic will soon pollute our metamodel with information of secondary importance.

We’ve often come across similar situations where we needed to attach some kind of information (that is not supported by the metamodel) to particular model elements during model management operations (validation, transformation etc.). Until now, we’ve been using Maps to achieve this (similarly to what we’ve done above). However, from version 1.3.0, EOL (and all languages built atop it) support non-invasive extended properties which provide a more elegant solution to this recurring problem.

An extended property is a property that starts with the ~ character. It’s semantics are quite straightforward: the first time a value is assigned to an extended property of an object (e.g. x.~a := b;), the property is created and associated to the object and the value is assigned to it. Similarly, x.~a returns the value of the property or undefined if the property has not been set on the particular object yet. Using extended properties, we can rewrite the above code (without needing to use a Map) as follows:

for (n in Tree.allInstances.select(t|not t.parent.isDefined())) {
	n.setDepth(0);
}

for (n in Tree.allInstances) {
	(n.name + ' ' + n.~depth).println();
}

operation Tree setDepth(depth : Integer) {
	self.~depth := depth;
	for (c in self.children) {
		c.setDepth(depth + 1);
	}
}
About these ads
This entry was posted in Uncategorized. Bookmark the permalink.

One Response to Extended properties in EOL

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s