Hi Adrian, I like the idea of your class factory. For years I have been using something very similar to create throwable classes. For example, in the package Spy (available on squeaksource) I have a class AbstractSpyTest and the following methods: AbstractSpyTest>>createClassNamed: AbstractSpyTest>>createClassNamed:superclass:
then, within a test method, I can do: testMyExample | cls | cls := self createClassNamed: #C1. cls compile: 'giveMyFive ^ 5'. ... in the tearDown method I have: AbstractSpyTest>>tearDown super tearDown. classes ifNotNil: [:clss | clss do: #removeFromSystem ]. where 'classes' is an instance variable of AbstractSpyTest I used this piece of code for many years already, and I have always been happy so far. I also take care that the classes are created in a class category different from the one of my application. You propose: > class := ClassFactory newSubclass: Point with: [ :f | > f metaSide compile: 'somePoint ^ self x: 2 y: 3'. > f compile: '+ arg ^ self x + arg x ..... 3' ]. > > ]. I find this difficult to remember. Do you manage automatic class removing in the tearDown? Cheers, Alexandre On 28 Dec 2009, at 23:07, Adrian Kuhn wrote: > `ClassFactoryForTestCase` is a awesome tool when you need to create > throw-away > classes for tests. And the new akuhn/SUnit includes a DSL that makes > creating > anonymous classes even simpler! > > The new DSL is put in a new class to avoid compatibility issues. To > create an > anonymous class just do > > class := ClassFactory newClass. > > this creates a new subclass of Object. The creates classes is > automatically > reclaimed by garbage collection when no longer used. That is, tear > down of > class factory is not required anymore. > > The class is created without logging and not registered with the > system. That > is, `Object subclasses` does not include the created class. > > To create a subclass of a specific class do > > class := ClassFactory newSubclass: Point. > > To create a subclass with accessors do > > class := ClassFactory newSubclass: Point with: [ :f | > f compileAccessorsFor: 'color' ]. > > If you want getters or setters only, use `#compileSetterFor:` or > `#compilerGetterFor:`. If you want an instance variable without > accessor, use > `#declareInstVar:`. > > To create a subclass with methods do > > class := ClassFactory newSubclass: Point with: [ :f | > f compile: 'answer ^ 42' ]. > > NB: please note that class factory compiles silently without logging. > > To create a method on the class side do > > class := ClassFactory newSubclass: Point with: [ :f | > f forClass: [ :cf | > cf compile: 'somePoint ^ self x: 2 y: 3' ]]. > > In fact, the class side factory `cf` supports the same protocol as > the instance > side factory. Please note that creating instance variables on the > class side > creates "class instances variables" and not "instance class > variables". That > is, they are local to the creates class but not to subclasses of the > created > class. Typically this should not be a limitation since you only > create one > class without further subclasses. > > Also, please note that the created classes and all instances created > from that > class are ment to be thrown away after their use. The created class > is not > registered with the system, and thus when you change the instance > size of its > superclass the created instances will not be updated. > > Gofer it > disablePackageCache; > squeaksource: 'akuhn'; > package: 'SUnit'; > package: 'SUnitGUI'; > load > > --AA > > > > _______________________________________________ > Pharo-project mailing list > Pharo-project@lists.gforge.inria.fr > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project