diff --git a/documentation/current/method/_images/Catcall_warning.png b/documentation/current/method/_images/Catcall_warning.png new file mode 100644 index 00000000..4dd3ed4d Binary files /dev/null and b/documentation/current/method/_images/Catcall_warning.png differ diff --git a/documentation/current/method/_images/Catcall_warning.png.data b/documentation/current/method/_images/Catcall_warning.png.data new file mode 100644 index 00000000..0d58433f --- /dev/null +++ b/documentation/current/method/_images/Catcall_warning.png.data @@ -0,0 +1,3 @@ +title=Catcall compiler warning +author=halw +path=content/catcall-compiler-warning diff --git a/documentation/current/method/eiffel-tutorial-et/et-inheritance.wiki b/documentation/current/method/eiffel-tutorial-et/et-inheritance.wiki index 49521bee..77807ada 100644 --- a/documentation/current/method/eiffel-tutorial-et/et-inheritance.wiki +++ b/documentation/current/method/eiffel-tutorial-et/et-inheritance.wiki @@ -822,7 +822,63 @@ with the argument anchored to the current object. A final, more application-oriented example of anchoring to Current is the feature merge posited in an earlier example (in [[ET: The Dynamic Structure: Execution Model|"The Dynamic Structure: Execution Model"]] ) with the signature merge (other: ACCOUNT). By using instead merge (other: like Current) we can ensure that in any descendant class -- BUSINESS_ACCOUNT, SAVINGS_ACCOUNT, MINOR_ACCOUNT ... -- an account will only be mergeable with another of a compatible type. -Covariance makes static type checking more delicate; mechanisms of "system validity" and "catcalls" address the problem, discussed in detail in the book [http://eiffel.com/doc/oosc/ Object-Oriented Software Construction] (see the bibliography). +Covariance makes static type checking more delicate; mechanisms of '''system validity''' and '''catcalls''' address the problem, discussed in detail in the book [http://eiffel.com/doc/oosc/ Object-Oriented Software Construction] (see the bibliography). Catcalls are discussed briefly below. + +===Catcalls=== + +The capabilities of polymorphism combined with covariance provide for powerful and flexible modeling. Under certain conditions, though, this flexibility can lead to problems. + +In short, you should be careful to avoid polymorphic '''catcalls'''. The '''call''' part of '''catcall''' means feature call. The '''cat''' part is an acronym for '''C'''hanging '''A'''vailability or '''T'''ype. What is changing here are features of descendant classes through the adaptation of inheritance. So maybe a descendant class has changed the export status of an inherited feature, so that that feature is not available on instances of the descendant class ... this is the case of '''changing availability'''. Or perhaps, through covariant modeling, the type of an argument to a feature in a descendant class has changed ... the case of '''changing type'''. + +Let's look at an example of changing type, due to covariant modeling. Suppose we have a system which uses the classes depicted on the following diagram: + +[[Image:Catcall example class diagram]] + +If in a client class, we declare the following attributes: + + + my_animal: ANIMAL + my_food_stuff: FOOD_STUFF + + +Also, the class ANIMAL contains the feature: + + eat (a_f: FOOD_STUFF) + -- Consume `a_f' + deferred + end + +This routine is implemented in COW as: + + eat (a_f: GRASS) + +and in class LION as: + + eat (a_f: WILDEBEEST_FILET) + + +So, covariant modeling is used to make the type of the argument for eat appropriate for each of ANIMAL's heirs. + +Here's where the problem comes in. It is possible at run-time to attach to my_animal a direct instance of either COW or LION. So, my_animal is a polymorphic attribute. Likewise, it is possible at run-time that my_food_stuff could be attached to a direct instance of either GRASS or WILDEBEEST_FILET. + +So, the feature call: + + my_animal.eat (my_food_stuff) + +is a '''catcall''', because there is a possibility that through the changing type of the argument to eat, we could be causing a COW to engage in the inappropriate practice of eating a WILDEBEEST_FILET. + +Because this possibility exists, developers should exercise caution in using polymorphism and covariant modeling. + +In version 6.2 of EiffelStudio, a capability was added to detect harmful catcalls at runtime. So, in our example, if we used my_animal.eat (my_food_stuff) only to feed grass to cows and wildebeest filets to lions, then all would be well. But if we attempted to use that same call to feed an inappropriate food to an animal, we would see an exception. + +Likewise the compiler in EiffelStudio will produce warnings in cases in which catcalls are possible. Below is an example of the compiler warning issued on the example. + +[[Image:Catcall compiler warning]] + + + + +