Permalink
Browse files

Traits

In this version of traits for Io, we don't copy just activatable behaviour (i.e., methods), we copy everything. True to traits, we should only copy behaviour, and not state -- i.e., anything that activates. Perhaps this change will make it in, in the future.
  • Loading branch information...
1 parent 838ebe3 commit 6b0be80e81ed9f10e15e9bb30b9fd6cf8392b60a @jeremytregunna jeremytregunna committed Feb 4, 2012
Showing with 42 additions and 0 deletions.
  1. +1 −0 libs/iovm/CMakeLists.txt
  2. +17 −0 libs/iovm/io/A0_Object.io
  3. +24 −0 libs/iovm/tests/correctness/TraitsTest.io
@@ -13,6 +13,7 @@ set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/_build/dll)
#file(GLOB IO_SRCS "io/*.io")
set(IO_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/io/A0_List.io
+ ${CMAKE_CURRENT_SOURCE_DIR}/io/A0_Object.io
${CMAKE_CURRENT_SOURCE_DIR}/io/A1_OperatorTable.io
${CMAKE_CURRENT_SOURCE_DIR}/io/A2_Object.io
${CMAKE_CURRENT_SOURCE_DIR}/io/A3_List.io
@@ -0,0 +1,17 @@
+//doc Object addTrait Takes another object, whose slots will be copied into the receiver. Optionally takes a second argument, a Map object containing string -> string pairs, holding conflicting slot names and names to rename them to. I.e., if you have two objects A and B, both have a slot named foo, you issue A addTrait(B, Map clone atPut("foo", "newFoo")) the value of B foo will be placed in A newFoo.
+Object addTrait := method(obj,
+ resolutions := call evalArgAt(1)
+ if(resolutions isNil, resolutions = Map clone)
+
+ getSlot("obj") foreachSlot(name, value,
+ if(getSlot("self") hasLocalSlot(name),
+ if(name == "type", continue)
+ if(resolutions at(name) isNil, Exception raise("""Slot '#{name}' already exists in #{getSlot("self") type}[#{getSlot("self") uniqueId}]. Give it a new name in the map argument.""" interpolate))
+ getSlot("self") setSlot(resolutions at(name), getSlot("value"))
+ continue
+ )
+ getSlot("self") setSlot(name, getSlot("value"))
+ )
+
+ getSlot("self")
+)
@@ -0,0 +1,24 @@
+TraitsTest := UnitTest clone do(
+ setUp := method(
+ super(setUp)
+ self A := Object clone do(foo := 42)
+ )
+
+ testNoConflicts := method(
+ B := Object clone
+ B addTrait(A)
+ assertEquals(42, B foo)
+ )
+
+ testConflict := method(
+ B := Object clone do(foo := 23)
+ assertRaisesException(B addTrait(A))
+ )
+
+ testConflictRename := method(
+ B := Object clone do(foo := 23)
+ B addTrait(A, Map clone atPut("foo", "fooFromA"))
+ assertEquals(42, B fooFromA)
+ assertEquals(23, B foo)
+ )
+)

0 comments on commit 6b0be80

Please sign in to comment.