summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2015-03-26 19:46:42 +0100
committerAndreas Rumpf <rumpf_a@web.de>2015-03-26 19:46:42 +0100
commit96d15e92587f37228213ba0e7ec6e67997e5d39c (patch)
treec12e310de1e81862db5dcfbc70995aec33ae781f
parent95ccb3c035921f9c7247f1d5ca5e6ce35cdaaf3d (diff)
parentf8472402d501126122780c7e998516fd6863bbd3 (diff)
downloadNim-96d15e92587f37228213ba0e7ec6e67997e5d39c.tar.gz
Merge pull request #2410 from def-/refobj
Use ref objects with inheritance in Tut2 (fixes #1817)
-rw-r--r--doc/manual/procs.txt43
-rw-r--r--doc/manual/types.txt2
-rw-r--r--doc/tut2.txt25
3 files changed, 38 insertions, 32 deletions
diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt
index 9b04bf518..9de984ecf 100644
--- a/doc/manual/procs.txt
+++ b/doc/manual/procs.txt
@@ -121,7 +121,7 @@ different; for this a special setter syntax is needed:
 .. code-block:: nim
   
   type
-    Socket* = object of RootObj
+    Socket* = ref object of RootObj
       FHost: int # cannot be accessed from the outside of the module
                  # the `F` prefix is a convention to avoid clashes since
                  # the accessors are named `host`
@@ -134,8 +134,8 @@ different; for this a special setter syntax is needed:
     ## getter of hostAddr
     s.FHost
 
-  var
-    s: Socket
+  var s: Socket
+  new s
   s.host = 34  # same as `host=`(s, 34)
 
 
@@ -351,32 +351,32 @@ dispatch.
 
 .. code-block:: nim
   type
-    Expression = object of RootObj ## abstract base class for an expression
-    Literal = object of Expression
+    Expression = ref object of RootObj ## abstract base class for an expression
+    Literal = ref object of Expression
       x: int
-    PlusExpr = object of Expression
-      a, b: ref Expression
-      
-  method eval(e: ref Expression): int =
+    PlusExpr = ref object of Expression
+      a, b: Expression
+  
+  method eval(e: Expression): int =
     # override this base method
     quit "to override!"
   
-  method eval(e: ref Literal): int = return e.x
-
-  method eval(e: ref PlusExpr): int =
+  method eval(e: Literal): int = return e.x
+  
+  method eval(e: PlusExpr): int =
     # watch out: relies on dynamic binding
     result = eval(e.a) + eval(e.b)
   
-  proc newLit(x: int): ref Literal =
+  proc newLit(x: int): Literal =
     new(result)
     result.x = x
-    
-  proc newPlus(a, b: ref Expression): ref PlusExpr =
+  
+  proc newPlus(a, b: Expression): PlusExpr =
     new(result)
     result.a = a
     result.b = b
-  
-  echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
+
+echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
   
 In the example the constructors ``newLit`` and ``newPlus`` are procs
 because they should use static binding, but ``eval`` is a method because it
@@ -387,8 +387,8 @@ dispatching:
 
 .. code-block:: nim
   type
-    Thing = object of RootObj
-    Unit = object of Thing
+    Thing = ref object of RootObj
+    Unit = ref object of Thing
       x: int
       
   method collide(a, b: Thing) {.inline.} =
@@ -400,8 +400,9 @@ dispatching:
   method collide(a: Unit, b: Thing) {.inline.} =
     echo "2"
   
-  var
-    a, b: Unit
+  var a, b: Unit
+  new a
+  new b
   collide(a, b) # output: 2
 
 
diff --git a/doc/manual/types.txt b/doc/manual/types.txt
index c78984db8..e9d33045b 100644
--- a/doc/manual/types.txt
+++ b/doc/manual/types.txt
@@ -568,7 +568,7 @@ the ``of`` operator can be used to determine the object's type.
       name*: string   # the * means that `name` is accessible from other modules
       age: int        # no * means that the field is hidden
 
-    Student = object of Person # a student is a person
+    Student = ref object of Person # a student is a person
       id: int                  # with an id field
 
   var
diff --git a/doc/tut2.txt b/doc/tut2.txt
index 4d30b1445..e1ac20074 100644
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -56,12 +56,12 @@ Objects have access to their type at runtime. There is an
 
 .. code-block:: nim
   type
-    Person = object of RootObj
+    Person = ref object of RootObj
       name*: string  # the * means that `name` is accessible from other modules
       age: int       # no * means that the field is hidden from other modules
 
-    Student = object of Person # Student inherits from Person
-      id: int                  # with an id field
+    Student = ref object of Person # Student inherits from Person
+      id: int                      # with an id field
 
   var
     student: Student
@@ -69,6 +69,7 @@ Objects have access to their type at runtime. There is an
   assert(student of Student) # is true
   # object construction:
   student = Student(name: "Anton", age: 5, id: 2)
+  echo student[]
 
 Object fields that should be visible from outside the defining module have to
 be marked by ``*``. In contrast to tuples, different object types are
@@ -82,6 +83,9 @@ no ancestor are implicitly ``final``. You can use the ``inheritable`` pragma
 to introduce new object roots apart from ``system.RootObj``. (This is used
 in the GTK wrapper for instance.)
 
+Ref objects should be used whenever inheritance is used. It isn't strictly
+necessary, but with non-ref objects assignments such as ``let person: Person =
+Student(id: 123)`` will truncate subclass fields.
 
 **Note**: Composition (*has-a* relation) is often preferable to inheritance
 (*is-a* relation) for simple code reuse. Since objects are value types in
@@ -228,7 +232,7 @@ is needed:
 .. code-block:: nim
 
   type
-    Socket* = object of RootObj
+    Socket* = ref object of RootObj
       FHost: int # cannot be accessed from the outside of the module
                  # the `F` prefix is a convention to avoid clashes since
                  # the accessors are named `host`
@@ -241,8 +245,8 @@ is needed:
     ## getter of hostAddr
     s.FHost
 
-  var
-    s: Socket
+  var s: Socket
+  new s
   s.host = 34  # same as `host=`(s, 34)
 
 (The example also shows ``inline`` procedures.)
@@ -313,8 +317,8 @@ dispatching:
 .. code-block:: nim
 
   type
-    Thing = object of RootObj
-    Unit = object of Thing
+    Thing = ref object of RootObj
+    Unit = ref object of Thing
       x: int
 
   method collide(a, b: Thing) {.inline.} =
@@ -326,8 +330,9 @@ dispatching:
   method collide(a: Unit, b: Thing) {.inline.} =
     echo "2"
 
-  var
-    a, b: Unit
+  var a, b: Unit
+  new a
+  new b
   collide(a, b) # output: 2