Object properties that are also objects

Apologies if this is something simple that I’m missing, but:

In Inform 7, it’s possible to have an object have a property (I believe that’s the appropriate terminology) that’s also an object. (In the vein of, say “A person has a supporter called the preferredBed”, or whatever)

I’m attempting to set up a system where there are glasses and beverages to put in them. For reasons related to other parts of the game, the beverages are defined as objects that are off-stage and have various properties. I want the player to be able to type, say “get water” to refer to a glass of water if there’s one available. The simplest version of the code I want is as follows:

[rant][code]A beverage is a kind of thing.

NotABeverage is a beverage. Water is a beverage. Milk is a beverage. Orange Juice is a beverage.

A beverageContainer is a kind of thing.

A beverageContainer has a beverage called the containedBeverage. containedBeverage of a beverageContainer is usually NotABeverage.

A glass is a kind of beverageContainer.

Printed name of a glass is usually “[If containedBeverage is NotABeverage]Empty glass[otherwise]Glass of [containedBeverage]”;

Understand the containedBeverage property as describing a beverageContainer.

The Bar is a room.

One glass is in the bar.[/code][/rant]

But the “understand…” line generates an error:

[rant]Problem. You wrote ‘Understand the containedBeverage property as describing a beverageContainer’: but that property is of a kind which I can’t recognise in typed commands, so that it cannot be understand as describing or referring to something. I can understand either/or properties, properties with a limited list of named possible values, numbers, times of day, or units; but certain built-into-Inform kinds of value (like snippet or rulebook, for instance) I can’t use.

See the manual: 17.15 > 17.15. Understanding things by their properties[/rant]

Having read through the recommended section in the documentation and not seeing anything directly related, I can only come to the conclusion that one of the following is true:

  1. Objects can’t be properties of other objects, and in fact are something else that behave like properties under some, but not all, conditions
  2. I’m using the wrong syntax to reference the property I want.
  3. Inform really doesn’t like the idea of using the names of objects to refer to other objects.

Anyone happen to be familiar enough with this sort of thing to give me a hint as to what I might be doing wrong? Thanks in advance.

It sounds like you have a bit of a programming background, so this explanation might make the most sense:
If an object has an object property, you’re storing a pointer to the object. And this is a problem because you can’t Understand a pointer-valued property directly.
If an object has an enum/int/etc property, you’re storing the value directly. This is fine, because Inform can Understand those things.

In this case, you probably want an enum.

Beverage is a kind of value. The beverages are nonliquid, water, and milk. A beverage container has a beverage.

You can also define a new relation connecting the container to the beverage if you really want to use objects.

The liquid containment relation relates a beverage container (called the holder) to a beverage (called the fluid) when the contained beverage of the holder is the fluid. Understand "[something related by liquid containment]" as a beverage container.

But the first is more elegant.

Ah, relations. Haven’t done a whole lot with those, which explains why I didn’t think of that. Thanks much!

(Side note 1: For anyone else reading this future-wise, I needed to tweak the code to Understand “[something related by the liquid containment relation]” to make it compile.)

(Side note 2: The reason I’m using objects instead of values for the beverages is because each of the beverages itself has a number of values applied to it (i.e. Water has a number called acidity, Water has a text called taste, and so on. Maybe there’s a better way to do that, but not one I thought of.)

You can do that with a kind-of-value.

See the “Measured Liquid” extension by Emily Short for an example of exactly this method.