[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] [ANN] Mirrors for GST
From: |
Gwenaël Casaccio |
Subject: |
[Help-smalltalk] [ANN] Mirrors for GST |
Date: |
Sun, 26 Feb 2012 20:07:55 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 |
Hello,
I am pleased to announce the initial release of Mirrors for GST.
It is common to use reflection in Smalltalk, for getting the class,
changing an instance variable, ... For instance anObject instVarAt: 1
returns the first instance variable. Reflection is often used for
meta-programming or when we create development tools.
But what will happen if the developer has changed #class or #instVarAt:
methods, unexpected results will occurs. This is one the reasons why
Mirrors are used, the paper explain well why they are useful
Mirrors: Design Principles for Meta-level Facilities of Object-Oriented
Programming Languages <http://bracha.org/mirrors.pdf>
You can try the implementation on my github repository:
https://github.com/MrGwen/gst-mirror (this is under the MIT licence)
First you will need to install a small patch in the VM (a new primitive
for executing
compiled method http://smalltalk.gnu.org/project/issue/643). I've tried
in my implementation
to minimize the VM changes (I didn't want to add tons of new primitives
or to change all the basic primitives).
There are three Mirrors right now:
- MirrorPrimitive
- Mirror
- BehaviorMirror
MirrorPrimitive is a dedicated mirror for breaking all the encapsulation
- and it makes primitive as first class entity by the way - but only do that
nothing more, that's the link between the others mirrors and the vm.
For instance you could do something like that for getting a class:
MirrorPrimitive classFor: anObject and as a result you get the class.
MirrorPrimitive for: anObject slotAt: anIndex
The implementation is quite trivial since I haven't created new
primitives (i.e. VMpr_Mirror_classFor, ...)
I've redefined the primitives at the class side:
MirrorPrimitive class >> privateClass [
<primitive: VMpr_Object_class>
]
now at the instance side :
classFor: anObject [
^ ##(MirrorPrimitive class >> privateClass) valueWithReceiver:
anObject withArguments: #()
]
##() is interesting because the compiled method (thus the primitive call)
will be "injected" as a literal thus I don't need to do a lookup all the
time (for getting the compiled method). Now I can execute the primitive
on the object.
Mirror is the class that you will use, unlike MirrorPrimitive they keep the
object as a state, and provide all the API for inspecting the objects.
You can get the class, change the slots, whatever you want. But it will
return all the time a mirror as a result.
Mirror and MirrorPrimitive don't inherit from Object because I don't want
to allow someone to break the mirror encapsulation (only the mirror should
be allowed to do that)
The API and the implementation is very a Saturday hacking ^^ Thus it will
be likely changed.
Hope you find them useful
Cheers,
Gwen
- [Help-smalltalk] [ANN] Mirrors for GST,
Gwenaël Casaccio <=