An implementation of slot with type-checking.
In a playground, execute the following script:
Metacello new
repository: 'github://juliendelplanque/TypedSlot/src';
baseline: 'TypedSlot';
loadThis project provides 4 kinds of "type" to provide to TypedSlot:
- Class: The slot will only accept objects that are kind of a given class.
- Trait: The slot will only accept objects for which the class is using a given trait.
- Block: The slot will only accept objects for satisfying a given block (i.e. the block returns true).
- Interface: The slot will only accept object for which the class implement a given interface.
It is possible to enable/disable type checking on multiple level:
- Globally, a setting is available in the "Tools" section of the settings.
- At class-level by overriding class-side method
#isTypeCheckingEnabledto let it returntrue(returnsfalseby default). - At instance-level by overriding instance-side method
#isTypeCheckingEnabledto define a custom policy at instance level (using an instance variable for example).
One can define an object with a slot that can only accept integers.
Object subclass: #ExampleTypedSlotUsingClass
slots: { #integerSlot type: Integer }
classVariables: { }
package: 'TypedSlot-Example'Once this class is defined and the accessor and mutator for #integerSlot are defined, one can expect the following behaviour.
object := ExampleTypedSlotUsingClass new.
object integerSlot. "nil"
object integerSlot: 1.
object integerSlot. "1"
object integerSlot: 'str'. "Raises a TypeViolation exception."One can define an object with a slot that can only accept objects for which the class uses a given trait.
Object subclass: #ExampleTypedSlotUsingTrait
slots: { #assertableSlot type: TAssertable }
classVariables: { }
package: 'TypedSlot-Example'Once this class is defined and the accessor and mutator for #assertableSlot are defined, one will only be able to set assertable objects in the #assertableSlot.
One can define an object with a slot that can only accept integers.
Object subclass: #ExampleTypedSlotUsingBlock
slots: { #greaterThanZeroSlot type: [ :x | x > 0 ] }
classVariables: { }
package: 'TypedSlot-Example'Once this class is defined and the accessor and mutator for #greaterThanZeroSlot are defined, one can expect the following behaviour.
object := ExampleTypedSlotUsingBlock new.
object greaterThanZeroSlot. "nil"
object greaterThanZeroSlot: 1.
object integerSlot. "1"
object greaterThanZeroSlot: -1. "Raises a TypeViolation exception."
object greaterThanZeroSlot: 'test'. "Raises a TypeViolation exception because it does not understand some message."To be documented once this feature is stable. In the meantime, take a look at TypedSlotInterfaceTest and TypedSlotRemoteInterfaceTest.