The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Whatever.Object

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
Whatever.Object Posted: Dec 7, 2007 10:14 AM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: Whatever.Object
Feed Title: Michael Lucas-Smith
Feed URL: http://www.michaellucassmith.com/site.atom
Feed Description: Smalltalk and my misinterpretations of life
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Michael Lucas-Smith

Advertisement

I have just gotten to a release point on my Whatever project. There are lots of projects around that want to treat objects more like dictionaries where you don't have to pre-define what instance variables you're going to use. These sorts of objects are like Self objects and are usually implemented with a dictionary instance variable and a DNU to act like getters and setters.

Several weeks ago it dawned on me that I wanted to make yet another one of these - but do it the most efficient way. The 'efficient' way is usually done by using at:'s and at:put:'s to access in to array slots and resizing the array when you run out of room. This is a lot faster than using a dictionary. Smarter implementations install methods on to a copy of the class to do the at: and at:put:

However, at: and at:put: are actually slower than instance variable access bytecodes. So in this implementation, we install methods on to our class copy that treat the shape of the class as if those slots were instance variables and not object slots in an array. This results in the fastest way we could have shapeless objects.

I'm now using Whatever.Object in Seaside-Mootools and Seaside-Javascript to represent a client side javascript object, since javascript objects are like Self objects and can have any slots you want on them. This greatly reduces the amount of code on the server side when trying to represent javascript objects and their subdry combinations of options.

The package is published in to public store as Whatever v29. Enjoy!

And now the package comment:


Whatever provides an efficient shapeless Object, much like a self object. You can set any slots you want on each instance, give it custom behavior and even inherit that behavior with new sub-instances. Consider this 'classless' objects.

Whatever.Object new
	name: 'My name';
	age: 76;
	gender: #happy;
	lifeStory: (Whatever.Object new
		title: 'My epic tale of classlessness';
		content: 'It was a dark and stormy night...';
		yourself);
	methodAt: 'printString' put: '^self name, '', aged: '', self age printString';
	yourself

This package implements these shapeless objects in one of the most efficient ways possible. It makes a copy of the class you're instantiating and when it receives a DoesNotUnderstand, if the selector looks like a getter or setter, the copy of the class will install getter and setter methods that directly access array slots so that the code runs as fast as a defined class would.

Each Whatever is technically an Array, but that is hidden to treat it like an object. Because you can define your own behavior on the instance, we can pretend there is no class at all.

In fact, there are two classes per instance - this may seem heavy weight, but the VM doesn't mind and it actually doesn't cost us that much. The class you instantiate from is first copied as a behaviorClass and then copied again for a shapeClass. When you add methods to your Whatever.Object, they are added to behaviorClass and when you add instance variables, they are added to the shapeClass.

When you subclass a Whatever.Object instance with #new or #clone, you do not inherit the shape methods from the superclass, such that you don't get shape change paradoxes between parent and child whatevers.

"Make a sub instance"
(Whatever.Object new
	methodAt: 'test' put: '^true';
	new) test

"Make a clone instance"
(Whatever.Object new
	methodAt: 'test' put: '^true';
	clone) test

Read: Whatever.Object

Topic: Smalltalk Daily 12/5/07: Less Progress Reporting Previous Topic   Next Topic Topic: Seaside in Ottawa

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use