Supporter strangeness

Inspired by this thread on raif, I thought I’d have a go at it. I mean, it’s a trivial challenge, right?

Then something odd happened.

The stork is an animal. The aviary is a room. The perch is a supporter in the aviary. The stork is on the perch.

Rule for printing room description details of the perch:
	say " (occupied by a ruddy bird)";
	omit contents in listing.

This is all fine and dandy. However, if we make one tiny change:

The stork is an animal. The aviary is a room. The perch is a supporter in the aviary. The stork is on the perch.

Rule for printing room description details of the perch:
	say " (occupied by a ruddy bird)" instead;
	omit contents in listing.

The output I get from the second example then becomes: “You can see a perch (inhabited by a ruddy bird) (on which is a stork) here.”

What am I missing? I’ve looked through the Standard Rules, but am no wiser. Is this normal behaviour, or could I have made some error when upgrading to 6F95?

Using “instead” in that way is the same as saying “end this rule here” (at the I6 level, it reads as “return true”). So you’re stopping the rule before you get to the “omit contents in listing”.

Basically, never use “say … instead” unless your rule is a one-liner.

–Erik

Right, that does make sense. I’m a bit puzzled at the need to omit contents in listing, though. From looking at the examples, I got the sense that this rule would supersede the regular listing of contents. In a conceptual sense I don’t want to omit the list of contents, after all, but merely alter its wording. Is there a preferred way to do that?

Well, the way you’re using it, “omit contents” does make sense, at least to me–you’re saying: I’ve already listed the contents, please don’t do so automatically.

In any case, that is intended more for changing the way the contents of a supporter are listed. For changing the name of something when it is printed in a content listing, use the “printing the name of” activity:

Rule for printing the name of the stork while listing contents of the perch: say "ruddy bird".

…Now, that code ought to work, but it doesn’t do anything (a bug?). So you’ll have to do something like this instead:

Rule for printing the name of the stork while listing contents: if the holder of the stork is the perch: say "ruddy bird".

–Erik

Oops, I forgot that you were also changing the way that the perch’s contents are described, in addition to changing the description of the stork. The former is properly changed using the room description details, and here is a more robust way to do exactly what you were doing:

[code]Rule for printing room description details of the perch:
if the perch supports something, say " (occupied by [list of things which are supported by the perch])";
omit contents in listing.

Rule for printing the name of the stork while listing contents:
if the holder of the stork is the perch:
say “ruddy bird”.[/code]

–Erik

Not a bug, it turns out, but the intended behavior. It seems that when the contents of a supporter or container are listed in a room description, the activity is acting on the room; otherwise, it will usually be acting on the box. So, if you use this code:

Rule for printing the name of the stork while listing contents of the perch: say "ruddy bird".

…the player will only see “ruddy bird” after typing X BOX. Whereas, if you use this code:

Rule for printing the name of the stork while listing contents of the Aviary: say "ruddy bird".

…the player will only see “ruddy bird” in the room description. To control all of the context in which listing occurs, you need to use:

Rule for printing the name of the stork while listing contents: if the holder of the stork is the perch: say "ruddy bird".

I’ve put in a request on Mantis for the documentation to tackle this explicitly, as it’s pretty counterintuitive.

–Erik

Neat! That explains things for me, and (when the documentation change is done) will probably do the same for others. Thanks for making the time and effort to track down the issue.

Did I miss something, or does this code replace the listing rules with the exact same listing rules?

You’re missing that the wording has been changed from the default to “occupied by…”

–Erik

Just to get myself clearer on how this works:

There are two separate activities involved in printing the name and contents of the supporter/container, right? The first one is “printing room description details of” (or “printing the name of”). If the object is a container or supporter, then by default we carry out the activity “listing contents of” – even if the activity “printing room description details of” has been stopped. But if the rule for “printing room description details of” invokes “omit contents in listing,” then the “listing contents of” activity isn’t carried out.

…I don’t think that’s right, though. So my question is, what activity is stopped by “omit contents in listing”? Does it have a name? If I want to change its behavior, is the best way always to do whatever I want to do in the rules for printing room description details/printing the name and then to omit contents in listing?

Thanks,

Matt

Not quite, and this is what I meant when I said in an earlier post that the way these activities work is counterintuitive. If you EXAMINE the supporter/container, then the “listing the contents” activity controls the listing of contents of the examined object. In the room description, though, it’s the “printing room description details” that controls listing of the supporter’s content (the listing the contents activity is going on at the same time and is the “parent” of the printing room description details activity, but it is running on the room, not on the supporter).

There is actually a good reason for this: if the library called the listing the contents activity for each supporter/container in a room description, you could exceed the number of allowed rulebooks pretty quickly in a situation where you have nested containers, e.g. an open folder in an inbox in a desk in a room. Each of those would need to run an instance of the listing the contents activity within its parent’s instance of the listing the contents of activity. You can see the potential for problems with this kind of nesting…

(The same is true when you examine a supporter/container–it’s only the object examined for which the listing the contents of activity is run. The listing of the contents of any objects in/on the object examined are controlled by the room description details activity.)

It’s not actually an activity that’s stopped by “omit contents in listing.” It’s what we might call the I6 list-writer, which doesn’t have an I7 equivalent. Basically, I believe that all “omit contents in listing” does is, effectively, change the internal list style to “none” for the next item to be called upon in the list-writer; as long as you place “omit…” in the right activity, it should suppress the list-writer’s output for the intended item. To give a bit of a sense of how not I7-ey the list-writer is, here’s the Standard Rules definition of the “omit” phrase:

To omit contents in listing (documented at ph_omit): (- c_style = c_style &~ (RECURSE_BIT+FULLINV_BIT+PARTINV_BIT); -).

You can look at the DM4 to see some of the details of how c_style and the list-writer’s bitwise operations work. I didn’t have the patience to study it myself :wink:

Anyway, yes, the way to intervene in library listing behavior is usually to do what you want in the appropriate activity, and use “omit contents in listing” to cancel the list-writer’s work for the object.

More generally, here’s a way to explore these questions to find out which activity is responsible for changing what you want to change. This example illustrates all of the points I made above about which activity is responsible for which listings:

[code]The Aviary is a room. The perch is a supporter in the Aviary. The stork is an animal on the perch.

A box is an open container on the perch. In the box is a baby.

Before listing contents of an object (called X):
say "–>[italic type](listing contents of [name X])[roman type] ";
continue the activity.

After listing contents of an object:
say “<–”;
continue the activity.

Before printing room description details of an object (called X):
say "->[italic type](details of [name X])[roman type] ";
continue the activity.

After printing room description details of an object:
say “<-”;
continue the activity.

Before printing the name of an object (called X):
say ">[italic type](name of [name X])[roman type] ";
continue the activity.

After printing the name of an object:
say “<”;
continue the activity.

To say name (O - an object): [prints the name of the object w/o using the printing the name of activity, which would create an infinite recursion]
(- print (string) {O}.short_name; -)[/code]

The output is an eyeful, and you can make it a little easier to read by getting rid of the two paragraphs dealing with the printing the name of activity. Note that we need to use “an object” in all of these so that we embrace both rooms and things.

–Erik

Wow, thanks for that very detailed response. The list-writer thing does seem to me like an instance of something people have said occasionally – that the real quirks of I7 are in the things that go on in I6 and that you can’t change without some deep code munging. (I mean, if you’re not going to mess with c_style I don’t think I will be anytime soon.) But in this case it seems not too hard to work around by doing what you want with the contents and then omitting contents in listing.

This is a very useful thread – thanks, everybody!