procedure Look(Actor : in Occupant); -- Option 1. procedure Look(Actor : access Occupant); -- Option 2.
For option 1, you're passing the Occupant to Look; in option 2, you're passing an access-to-Occupant value. Both will dispatch, both can be overridden, and you can use both approaches in the same program (it's no big deal to convert between them). Personally, I find that option 2 closer to the way I think about the problem, so I've used it throughout program Small where appropriate. Why do I find it more natural? Well, I think of Things lying out there in the simulated world, and that these subprogram simply pass around references to them. You'll find that different people have different preferences depending on the circumstance.
If you do not need to dispatch on an operation, you can define operations as:
procedure X(Actor : in Occupant'Class); -- Option 3. procedure X(Actor : access Occupant'Class); -- Option 4. procedure X(Actor : in Occupant_Access); -- Option 5.
Option 3 basically says we can accept any type at all as long as that type is a member of the class Occupant. Option 4 says we can take any access value at all, as long as it accesses a type that's a member of Occupant'Class. Option 5 uses an access type defined elsewhere, and if that type (Occupant_Access) is defined as access Occupant'Class it's quite similar to option 4 except in one very important way - option 5 permits a null value to be passed in.
Thus, if we're passing around access values and we want to permit a null value, we should use "Occupant_Access" as the parameter type. Otherwise, if we don't need to pass a null value, we can use option 4 (so that it uses access values as well).
Generally, if you use option 1 you'll use option 3, and if you use option 2 you'll use options 4 and 5 (depending on whether or not you want to permit a null value). Which you choose depends mainly on how you think about your problem - are you thinking in terms of passing around specific objects, or are you thinking in terms of passing access (reference) values to those objects? Your answer suggests which you should use.
So what do we do about the function "Me" we mentioned earlier? Conceivably a future version might permit a Player to command a Monster or Item, so let's make function "Me" return an Occupant_Access.
At this point we have the basic idea on how to implement Look, Quit, Get, Drop, and Inventory.
Could the actual accessed object function "Me" returns be of type Player?
![]() |
![]() |
![]() |
---|
David A. Wheeler (dwheeler@ida.org)
The master copy of this file is at "http://www.adahome.com/Tutorials/Lovelace/s18s5.htm".