[I6] Object is both a container and a supporter?

Ahem.

It’s another trivial thing but can an object be both a container AND a supporter?
I don’t think I have seen something about it in the documentation. Maybe there are some plugins dealing with it?

It can. The problem is that the library has trouble with the concept.

In DM4 (Appendices Library attributes):
“Note: an object cannot be both a container and a supporter.”

It would be difficult for the library to manage both. In particular for the handling of open and transparent attributes, LetGo and Receive actions, for what is “in scope” or not, player’s movement on or into objects and many other things.
Maybe Inform 7 does something else.

( David Griffith knows this better than I do, but it’s just to work on my English with DeepL; and if that can help a little!)

See exercise 103 in the DM4 for a hacky solution. It works by making a separate supporter object and attaching it with add_to_scope.

I7 formally abjures the notion by implementing Container and Support as separate classes. (I7 kinds are strictly single inheritance.) You can implement the same separate-object hack, though.

There is a messy work-around by making supporters / containers that are part of a thing, and redirecting actions as appropriate. The following is meant just as a sample, a full implementation would probably have to handle a lot more corner cases.

The cabinet is a thing.
It is in the Example Location.
The description is "A simple cabinet of humble craftsmanship. [description of the cabinet's top] [description of the cabinet's interior]"

There is an enterable container called the cabinet's interior.
It is part of the cabinet.
The description is "Inside the cabinet is [list of things inside the cabinet's interior]."

There is a supporter called the cabinet's top.
It is part of the cabinet.
The description is "On top of the cabinet is [list of things on the cabinet's top]."

There is a thing called the bowling ball.
It is in the Example Location.

Instead of entering the cabinet:
	try entering the cabinet's interior instead.

Instead of inserting something into the cabinet:
	try inserting the noun into the cabinet's interior instead.

Instead of putting something on the cabinet:
	try putting the noun on the cabinet's top.
	
Understand "exit cabinet" as exiting.

Example Location is a room.

test me with "put ball in cabinet / take ball / put ball on cabinet / take ball / enter cabinet / exit cabinet".

While this is definitely the way to go about it, that’s Inform 7 code, not Inform 6. I6 doesn’t have the “part of” tree alongside the object tree, which makes it harder.

Oh! I totally didn’t see the [I6] tag, sorry!

I think I’ll start looking at something like this for 6.13.x of the standard library.

Thank you all for the answers. Gave me lots of ideas.

I’ve read DM4, checked how TADS deals with the issue (ComplexContainer with sub-objects) and decided to make parent-object with supporter and container as its children and ping-pong reactions to different verbs between them (like MultidimensionalStep proposed).

Code
Class Item
	with before [;
		Take:
			if (self in fridge_inside or fridge_top) {
				move self to parent(player);
				<<Take self>>;
			}
	];

Object Room "Room"
	with description [;],
	has light;

Object -> fridge "fridge"
	with name "fridge",
		before [;
			Open: <<Open fridge_inside>>;
			Close: <<Close fridge_inside>>;
			Examine:
				<Search fridge_inside>;
				<<Search fridge_top>>;
			Receive:
				if (action_to_be == ##Insert) <<Insert noun fridge_inside>>;
				if (action_to_be == ##PutOn) <<PutOn noun fridge_top>>;
		],
	has scenery transparent;

Object ->-> fridge_inside "fridge"
	has container openable;

Item ->->-> vegetables "vegetables"
	with name "vegetables",
	has pluralname;

Item ->->-> soy_souce "soy sauce"
	with name "soy" "sauce",
	has;

Object ->-> fridge_top "fridge"
	has supporter;

Item ->->-> metal_plates "metal dishes"
	with name "metal" "dishes",
	has pluralname;
How it looks
> x fridge
You can’t see inside, since the fridge is closed.
On the fridge are some metal dishes.

> open it
You open the fridge, revealing some vegetables and a soy sauce.

> take soy
Taken.

> put it on fridge
You put the soy sauce on the fridge.

> take dishes
Taken.

> put them in the fridge
You put the metal dishes into the fridge.

> x fridge
In the fridge are some metal dishes and some vegetables.
On the fridge is a soy sauce.

[UPDATE] Less verbose solution, as zarf mentioned, is described in DM4 and uses the add_to_scope property:

Code
Object Room "Room"
	with description [;],
	has light;

Object -> fridge "fridge"
	with name "fridge",
		add_to_scope fridge_top,
		before [;
			Examine:
				<Search self>;
				<<Search fridge_top>>;
			Receive:
				if (action_to_be == ##PutOn) <<PutOn noun fridge_top>>;
		],
	has scenery container openable;

Object ->-> vegetables "vegetables"
	with name "vegetables",
	has pluralname;

Object ->-> soy_souce "soy sauce"
	with name "soy" "sauce",
	has;

Object -> fridge_top "fridge"
	has scenery supporter;

Object ->-> metal_plates "metal dishes"
	with name "metal" "dishes",
	has pluralname;

So far, this looks very nice. Could you do a writeup of this at the Inform6lib GItlab page?