help-smalltalk
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]