gt0460d@prism.gatech.EDU (DSOUZA,ROSARIO JOHN) (01/22/91)
I have a curious problem. I am writing an application in Eiffel that makes use of the graphics library. In particular, I need to use objects that are similar to the class COMPLEX_FIG in the library, yet a little different from it. My class is similar in the sense that it is to have a list of figures and the whole list has to behave like a figure. But it is different because the figures in the list are really going to be a special type of figure that is a descendant of class FIGURE. At first I thought that I could make my class a descendent of the class COMPLEX_FIG and proceed from there. This is the most natural solution. However, it turns out that COMPLEX_FIG inherits from FIG and LINKED_LIST, and the generic parameter of the linked list is FIGURE. This causes a problem because I need the generic parameter to be something that is capable of responding to feature calls of my special figure. This seemingly cannot be done because the generic parameter is hardwired, so to speak, to the class FIGURE. My question is: short of duplicating the code for COMPLEX_FIG with the generic parameter of the inherited linked list now as my special figure, is there any other better way to solve the problem? I suspect that the problem is not just a matter of good library design, but also a problem of language design. Could someone enlighten me? ..Ross D'Souza Georgia Tech. ross@cc.gatech.edu
nosmo@eiffel.UUCP (Vince Kraemer) (01/23/91)
The solution is simple; depending upon the use of the language feature "association types". Association types appear as declarations in Eiffel code as ": like <anchor-object>". By redefining the anchor object in a class which takes advantage of this feature, all the associated objects are effectively redeclared. The library classes (specifically LINKED_LIST) were written with just such a problem in mind and allow the user to take advantage of this technique. By reviewing the code for linked_list, it is easy to determine that first and first_element are the anchors for the the routines in linked list which are originally declared as FIGURES. The sample code to illustrate the solution to this "problem" is appended to this message as a shar-chive file. (Note: this code has been tested using both the 2.2B and 2.3 releases. You will have to modify the .eiffel file to compile it under 2.2B, though) Vince Kraemer ISE Tech. Support (technical correspondence to: eiffel@eiffel.com) --------------------------------------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by geneve!nosmo on Tue Jan 22 09:15:40 PST 1991 # Contents: .eiffel special_c_f.e special_f.e special_test.e echo x - .eiffel sed 's/^@//' > ".eiffel" <<'@//E*O*F .eiffel//' ------------ EIFFEL SYSTEM DESCRIPTION FILE ------------------- ROOT: special_test UNIVERSE: $EIFFEL/library/support $EIFFEL/library/structures $EIFFEL/library/graphics/figure $EIFFEL/library/graphics/window EXTERNAL: $EIFFEL/files/graphiclib.a -lX11 -lm PRECONDITIONS (y): ALL ---------------------------------------------------------------- @//E*O*F .eiffel// chmod u=rw,g=rw,o=r .eiffel echo x - special_c_f.e sed 's/^@//' > "special_c_f.e" <<'@//E*O*F special_c_f.e//' --|--------------------------------------------------------------- --| Copyright (C) Interactive Software Engineering, Inc. -- --| 270 Storke Road, Suite 7 Goleta, California 93117 -- --| (805) 685-1006 -- --| All rights reserved. Duplication or distribution prohibited -- --|--------------------------------------------------------------- --| Author: Vincent Kraemer @ Interactive Software Engineering --| Created: Tue Jan 22 07:59:21 1991 class SPECIAL_C_F export repeat complex_fig inherit COMPLEX_FIG redefine first, first_element feature first: SPECIAL_F is require not_empty: not empty do Result := first_element.item end; first_element: LINKABLE [special_f]; invariant end -- class SPECIAL_C_F @//E*O*F special_c_f.e// chmod u=rw,g=rw,o=r special_c_f.e echo x - special_f.e sed 's/^@//' > "special_f.e" <<'@//E*O*F special_f.e//' --|--------------------------------------------------------------- --| Copyright (C) Interactive Software Engineering, Inc. -- --| 270 Storke Road, Suite 7 Goleta, California 93117 -- --| (805) 685-1006 -- --| All rights reserved. Duplication or distribution prohibited -- --|--------------------------------------------------------------- --| Author: Vincent Kraemer @ Interactive Software Engineering --| Created: Tue Jan 22 08:04:34 1991 class SPECIAL_F export repeat FIGURE, special_call inherit FIGURE feature create is do closure.Create; end; special_call is do io.putstring ("Called special_call.\n"); end; recompute_closure is do end; convert_to_resolution (rv: REAL) is do end; origin: POINT; barycenter: POINT; duplicate: like Current is do end; translate (V: VECTOR) is do end; rotate (a: REAL; p: like origin) is do end; scale (f: REAL; a: like origin) is do end; display (w: graph_window) is do end; erase (w: GRAPH_WINDOW) is do end; contains (p: like origin): BOOLEAN is do end; invariant end -- class SPECIAL_F @//E*O*F special_f.e// chmod u=rw,g=rw,o=r special_f.e echo x - special_test.e sed 's/^@//' > "special_test.e" <<'@//E*O*F special_test.e//' --|--------------------------------------------------------------- --| Copyright (C) Interactive Software Engineering, Inc. -- --| 270 Storke Road, Suite 7 Goleta, California 93117 -- --| (805) 685-1006 -- --| All rights reserved. Duplication or distribution prohibited -- --|--------------------------------------------------------------- --| Author: Vincent Kraemer @ Interactive Software Engineering --| Created: Tue Jan 22 08:13:14 1991 class SPECIAL_TEST feature create is local sf: SPECIAL_F; scf: SPECIAL_C_F; do sf.create; scf.create; scf.put_right (sf); sf := scf.i_th (1); sf.special_call end; end -- class SPECIAL_TEST @//E*O*F special_test.e// chmod u=rw,g=rw,o=r special_test.e exit 0
paj@mrcu (Paul Johnson) (01/23/91)
>I have a curious problem. I am writing an application in Eiffel that >makes use of the graphics library. In particular, I need to use >objects that are similar to the class COMPLEX_FIG in the library, yet >a little different from it. My class is similar in the sense that it >is to have a list of figures and the whole list has to behave like a >figure. But it is different because the figures in the list are >really going to be a special type of figure that is a descendant of >class FIGURE. >At first I thought that I could make my class a descendent of the class >COMPLEX_FIG and proceed from there. This is the most natural solution. >However, it turns out that COMPLEX_FIG inherits from FIG and LINKED_LIST, >and the generic parameter of the linked list is FIGURE. This causes a >problem because I need the generic parameter to be something that is >capable of responding to feature calls of my special figure. This >seemingly cannot be done because the generic parameter is hardwired, >so to speak, to the class FIGURE. >My question is: short of duplicating the code for COMPLEX_FIG with the >generic parameter of the inherited linked list now as my special figure, >is there any other better way to solve the problem? >I suspect that the problem is not just a matter of good library design, >but also a problem of language design. Could someone enlighten me? I will try, although I have not checked the following against the Eiffel type rules. Hence it may not work. When you produce your child of COMPLEX_FIG (say, MY_COMPLEX_FIG, although this would be a bad name in practice) you should say `redefine first; rename first as old_first' and then define `first' as being of the appropriate type and returning (using the reverse assignment operator `?=') the value of `old_first'. All the other features of LINKED_LIST are `like first', so this will make the change to all of them. This is the first time I have really appreciated the utility of `like'. If this does not work then use the reverse assignment operator outside of COMPLEX_FIG to undo the type loss before applying your features. Paul. -- Paul Johnson UUCP: <world>!mcvax!ukc!gec-mrc!paj --------------------------------!-------------------------|------------------- GEC-Marconi Research is not | Telex: 995016 GECRES G | Tel: +44 245 73331 responsible for my opinions. | Inet: paj@uk.co.gec-mrc | Fax: +44 245 75244