📄 00000004.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人: cybergene (基因~也许以后~~), 信区: Linux <BR>标 题: Objects in TCL <BR>发信站: BBS 水木清华站 (Thu Dec 14 16:00:20 2000) <BR> <BR> <BR>Objects in TCL <BR> <BR> <BR>------------------------------------------------------------------------ <BR>-------- <BR> <BR> <BR>Introduction <BR>C++ and Java are two well-known languages that offer primitives and <BR>in-language support for object oriented programming. That does not <BR>mean that object oriented programming is impossible in other languages. <BR> Object orientation is really just a way of thinking; it has more to <BR>do with design than with implementation. Look at the source code of <BR>the TCL interpreter for a great example of object oriented programming <BR>in C (not C++!). If you are disciplined enough to always pass a <BR>pointer to a struct as the first parameter to a function, you can see <BR>such a function as a 'method' of the struct. You do not need actual <BR>language support to create object-oriented code. <BR> <BR>TCL does not offer object oriented primitives, but it is flexible enough <BR> to accomodate new primitives. This paper decribes a well known <BR>technique, object commands, to add some object primitives to TCL. Once <BR>you understand how object commands work, you will be able to figure <BR>out the code of most object packages and extensions. <BR> <BR>This paper assumes that you are familiar with TCL, and that you have <BR>written at least a few simple scripts in TCL. <BR> <BR>Existing extensions <BR>Many extensions of TCL exist, that add flavours of objects and classes <BR>to the basic language. Some of these extensions are written in C, and <BR>must be compiled and linked to the TCL library to make them available in <BR> the language. A good example is >> [Incr Tcl], an extension that <BR>introduces primitives such as class, method and constructor. Other <BR>extensions, such as Jean-Luc Fontaine's >>Stooop, are written in TCL <BR>itself. They don't require any recompilation. You may wonder how it is <BR>possible to extend TCL with new primitives written in TCL itself. This <BR>paper answers that question by zooming in on the techniques of object <BR>commands and class commands. We will not handle the category of <BR>extensions that requires compilation. <BR> <BR>Another important difference is that between extensions with static <BR>and dynamic classes. With static classes, the members of a class <BR>cannot be changed at runtime. You can introduce new classes into a <BR>running system, but once a class is created, you cannot add new <BR>methods or data members to it. Similarly, you can create new instances <BR>of a class, but you cannot (easily) change the class of an existing <BR>instance. <BR> <BR>[Incr Tcl] is an example of a TCL extension with static classes. You <BR>cannot add methods or variables to an existing class or object. You can, <BR> however, change the implementation of any method of a class (just <BR>like rewriting a procedure body in pure TCL). And of course, you can <BR>inherit from an existing class and add new methods and variables in <BR>the derived class. <BR> <BR>But since TCL is a dynamic language, in which you can introduce new <BR>procedures and new variables at run-time, it seems more appropriate to <BR>also allow the creation of new methods and member variables at run-time. <BR> That requires a dynamic class mechanism such as offered by >> OTcl. <BR> <BR>Both static and dynamic object-oriented extensions of TCL can make use <BR>of the techniques described in this paper. <BR> <BR>Many thanks for bob Techentin for sharing his [Incr Tcl] knowledge. <BR> <BR>A simple example <BR>Suppose we want to manipulate objects that store a single attribute, for <BR> example the name of a color. Each object has its own color. We also <BR>need to give each object a unique identifier or number to distinguish it <BR> from other objects. <BR> <BR>We store the object colors in a TCL array, indexed by the object name. <BR>For example: <BR> <BR> set a_color(a1) green <BR> set a_color(a2) yellow <BR> set a_color(a3) red <BR> <BR>We now have three objects a1, a2, a3, each with its own color. Even an <BR>extremely simple approach like this one is already useful in many <BR>cases where you need to map object attributes to their values. <BR>Simplicity is not a bad property of designs, but a very good one. <BR>We can make this more attractive and hide the array, by writing two <BR>access procedures: <BR> <BR> example1/apples.tcl <BR> proc get_color {obj_name} { <BR> global a_color <BR> if { [info exists a_color($obj_name)] } { <BR> return $a_color($obj_name) <BR> } else { <BR> puts "Warning: $obj_name has no color!" <BR> return "transparent" ; # return a default color <BR> } <BR> } <BR> <BR> proc set_color {obj_name color} { <BR> global a_color <BR> set a_color($obj_name) $color <BR> } <BR> <BR>We now access the colors of objects as follows: <BR> <BR> set_color a1 green <BR> puts "a1 has color [get_color a1]" <BR> <BR>The next step is to introduce some syntactic sugar: just a small <BR>improvement that makes the syntax look better, but does not really <BR>change anything fundamental. We create the following procedure: <BR> <BR> example2/apples.tcl <BR> proc a1 {command args} { <BR> if { $command == "get_color" } { <BR> return [get_color a1] <BR> } elseif { $command == "set_color" } { <BR> set_color a1 [lindex $args 0] <BR> } else { <BR> puts "Error: Unknown command $command" <BR> } <BR> } <BR> <BR>Using this procedure, we can now access the color of the a1 object as <BR>follows: <BR> <BR> a1 set_color yellow <BR> puts "a1 has color [a1 get_color]" <BR> <BR>As you can see, all this really does is swap the positions of the object <BR> name and the name of the get_color or set_color procedure. Not very <BR>useful in itself, but it makes the syntax look more like an object <BR>invocation. It looks as if we invoke the 'method' set_color on the <BR>'object' a1. <BR> <BR>Procedure a1 is called an object command. Its first argument is the name <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -