0

I'm just getting started with itcl and I have found How to pass itcl object from one class to another? but that did not help me.

I have the following objects defined:

package require Itcl

namespace eval FEM {

   itcl::class Node {
       variable nid
       variable x
       variable y
       variable z

       constructor {{NID 0} {coordX 0} {coordY 0} {coordZ 0}} {
         set nid $NID
         set x $coordX
         set y $coordY
         set z $coordZ
         return $this}

       method is {nid coordX coordY coordZ}
       method printString  
      }

   itcl::body Node::is {NID coordX coordY coordZ} {
       set nid $NID  
       set x $coordX
       set y $coordY
       set z $coordZ}       

   itcl::body Node::printString {} {
       return "$nid $x $y $z"}

# #######################################################

   itcl::class CQUAD {
       variable eid
       variable pid
       variable node1
       variable node2
       variable node3
       variable node4

       constructor {{EID 0} {PID 0} {NODE1 0} {NODE2 0} {NODE3 0} {NODE4 0}} {
         set eid $EID
         set pid $PID
         set node1 $NODE1
         set node2 $NODE2
         set node3 $NODE3
         set node4 $NODE4
         return $this}

       method is {EID PID NODE1 NODE2 NODE3 NODE4}
       method printString  

      }  

   itcl::body CQUAD::is { EID PID NODE1 NODE2 NODE3 NODE4 } {
       set eid $EID
       set pid $PID  
       set node1 $NODE1
       set node2 $NODE2
       set node3 $NODE3
       set node4 $NODE4}       

   itcl::body CQUAD::printString {} {
       return "$eid $pid $node1 $node2 $node3 $node4"}
  }

}

# ########################################################
# Test  

for {set n 1} {$n <= 4} {incr n} {  
   set coord1 [expr {$n+1} ]
   set coord2 [expr {$n+2} ]
   set coord3 [expr {$n+3} ]   
   set NID N$n
   ::FEM::Node $NID $n $coord1 $coord2 $coord3
   puts "[$NID printString]"
 }

set PID 99
set EID 88 

The following is wrong since $N1 simply is N1 and not a "node" N1

::FEM::CQUAD MyQuad $EID $PID $N1 $N2 $N3 $N4

But how do I pass an object of type Node to an Object of type CQUAD ? I also tried:

::FEM::CQUAD MyQuad $EID $PID $::FEM:Node::N1 $::FEM:Node::N2 $::FEM:Node::N3 $::FEM:Node::N4

Also, how do I delete an object? unset $N1 is wrong unset $::FEM::Node::N1 is also bogus

Final question: Assume that I have a CQUAD object with objects of type Node in it: How could I eg get the y coordinate of Node2 of CQUAD 1 ?

Community
  • 1
  • 1
Lumpi
  • 2,697
  • 5
  • 38
  • 47

1 Answers1

2

In Itcl (as in the rest of Tcl), you don't pass the object itself, you pass the name of the object which the consuming command resolves to a reference to the object.

Generally speaking, an object's name should be passed around as its fully-qualified name so that the names are understood everywhere in Tcl as meaning the same thing. You can get this for N1 by using namespace which N1. (The exceptions to this are Tk widget names, which have to be in the global namespace, passed around unqualified, and always start with ..)

To delete an object (as opposed to a variable containing the name of an object) you use:

itcl::delete object $theObjectName

Note that Itcl objects are not garbage collected (but it is possible to simulate this in simple cases using a delete trace on a variable in a suitable stack frame; the itcl::local command makes this easier).

To access a public variable of an Itcl object, use the cget method (if you've used Tk, this should be very familiar).

set theYcoord [[$CQUAD cget -Node2] cget -y]

To make a variable be public, your class definition should say, for example:

public variable y
public {
    # Both x and y are to be public variables
    variable x
    variable y
}

I recommend keeping the number of public variables to a minimum, but that's your business.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • using namespace which N1 i get: ::N1 So itcl::delete Node $::N1 should delete it, but I get: bad option node, should be one of.... Just for me: N1 is the object name, "Node" is the object type ? – Lumpi Jan 27 '14 at 17:34
  • To delete, 'object' is a literal string. So for your case it would be: itcl::delete object ::N1 – Robert Lugg Jun 26 '15 at 17:47