Problem setting action variables for inserting and giving

This is my first post here. I’m a long time programmer and IF player who’s just starting to learn Inform 7. At times it can be incredibly frustrating compared to other languages and IDEs but it also SO MUCH FUN. I’ve been stuck on this issue for a week. I’ve thrown all my debugging techniques at it but to no avail.

I successfully used action variables with entering and exiting and taking. When I extend the exact same technique for inserting and giving it throws a runtime error that makes no sense to me.

[i]>[3] put rock in bucket

*** Run-time problem P10: Since Rock is not allowed the property “test_variable”, it is against the rules to try to use it.
[/i]

For some reason the setting code doesn’t see that the variable exists. If I create a global variable with the same name, things work. This tells me it’s some kind of scoping problem, like the action variable isn’t getting created in the correct rulebook or something…

Here’s the sample story to demonstrate the problem:

Example Location is a room.

North room is north of example location.

Rock is a thing in Example Location.

Bucket is a enterable container in Example Location.

[THIS DOES WORK]
The exiting action has a container called thing exited.

Setting action variables for exiting:
now thing exited is the holder of the actor.

Report exiting when thing exited is the bucket:
say “you just left [thing exited].”

[THIS DOESN’T WORK]
The inserting into action has some text called test_variable.

Setting action variables for inserting into:
now test_variable is “testing”.

report inserting into when test_variable is “testing”:
say “here”.

Test me with “enter bucket / exit / put rock in bucket”.

I’m never entirely sure when you need this, but what if you change “inserting into” to “inserting it into”? Two noun actions usually have “it” as part of their name to show where the first noun goes. In some contexts but not all, you can just say “inserting,” but I don’t think “inserting into” ever works as desired. Although if my diagnosis is correct I’m not sure why your code compiled.

Hi. The basic idea is correct, but there are some issues with the exact way that the code refers to the “inserting it into” action and defines the associated rules.

The precise name of the action is “inserting it into” rather than “inserting into” (see the action index), and, when writing rule headers, the “it” needs to be replaced with the description of a noun (either a specific one, or a general one such as “something”).

Also, you can use code tags to enclose code that you post in order to preserve the indentation and make it easier for people to cut, paste, and test for themselves.

Example Location is a room. 

North room is north of example location.

Rock is a thing in Example Location.

Bucket is a enterable container in Example Location.

The exiting action has a container called thing exited.

Setting action variables for exiting:
	now thing exited is the holder of the actor.

Report exiting when thing exited is the bucket:
	say "you just left [thing exited]."

The inserting it into action has some text called test_variable.

Setting action variables for inserting something into: 
	now test_variable is "testing".

Report inserting something into when test_variable is "testing":
	say "here".

Test me with "enter bucket / exit / put rock in bucket".

Edit: my comments about using “it” were too broad. “Report inserting it into” is fine, but “Setting action variables for inserting it into” fails to compile, complaining that “inserting it into” doesn’t make sense as a description of an action.

Thank you!!!

I neglected to mention that I tried every variation I could think of: “inserting into”, “inserting it into”, “inserting something into”, “inserting something into something”, etc. etc. But never did I think that the variable declaration and rule definition would have differing ways to refer to the same action!

matt w: Actually “inserting into” is sometimes needed, as you yourself pointed out to me a few weeks ago (though it was “removing from” then).

Rule for deciding whether all includes (something) when inserting into:
     (etc)

Neither “inserting it into” nor “inserting something into” works in this context. (The former should in my opinion.)

Huh, so I did. OK, I think I can definitively say that I’m never entirely sure when you need “it” and when you need “something” and when you need nothing at all.

The “inserting into” form is actually documented in WWI, though rather obscurely: Section 17.19 (Does the player mean…) in the “caveat to the caveat”.

I think that passage in WWI explains a subtle bug (or at least, mis-documentation) in the “clarifying the parser’s choice” activity. This is stated only to apply to the first noun. But for the “inserting it into” action, it actually only work for the second noun. Presumably this is because the parser handles “inserting into” and “removing from” backwards, establishing the second noun first.

In a parenthetical to the caveat to the caveat! The documentation sure does hide elephants in mouseholes sometimes. Well, this is really hiding a mouse in a mousehole.

Ah, the magic of [things inside]…

It seems like half the code in the parser is for dealing with [things inside] and [other things].

And it seems like there should be a more elegant, more I7-esque way to deal with those situations now (like the modified implicit action extensions rather than the parser’s implicit-take) but I can’t really think of one…

I really don’t think there is. AFAICT the whole parser is based on parsing one noun at a time, and there’s just about nothing that lets you parse one thing by its relation to something you’ve already parsed, except the extreme ad-hoccery that is necessary for “[things inside].”

[other things] does seem kind of ridiculous, though. So much work to make sure that you don’t put a box into itself! I guess this can’t be taken care of with a Does The Player Mean rule because that won’t run for multiple object actions–no DTPM rule can exclude anything from “all.” And you can’t use a deciding whether all includes rule, because that would need to look ahead at the second noun. (Which is I guess why you say “Rule for deciding whether all includes when inserting into,” as in the old thread that was linked earlier in this thread–you don’t use a form that refers to the noun or second noun because you don’t get to talk about them.)

The I7-esquiest way I can think of to do this would be to let the action get parsed to refer to everything, and then use a before rule to squash the things that weren’t actually inside. That would lead to spurious announcements from the multiple object list, though. But wait! We have the multiple action processing rules now! Maybe we could use a multiple action processing rule to edit out the things that weren’t actually inside? We’d also need some kind of does the player mean rule to run when a single thing is specified, so TAKE BUST FROM PEDESTAL would take the bust that is on the pedestal rather than the bust that is not on the pedestal, but something needs to be done about cases kind of like that anyway (it breaks when PEDESTAL is ambiguous), so it might not be that much extra work.

LOL he said something about fiddling with the parser “might not be that much extra work.”

The I7-esquiest way would be for DTPM rules, or something like them, to work for multiple object actions.

Sadly this isn’t trivial either.

Well, I tried this:

[code]Lab is a room.

Grabbing it from is an action applying to two things. Understand “grab [things] from [something]” as grabbing it from.

A multiple action processing rule when the action name part of the current action is the grabbing it from action:
let L be the multiple object list;
let F be L;
repeat with item running through L:
unless the holder of the item is the second noun:
remove the item from F;
alter the multiple object list to F;
if the number of entries in F is 0:
if the second noun is not a container and the second noun is not a supporter:
say “That can’t contain things.”;
otherwise:
say “There is nothing like that [if the second noun is a container]in[otherwise]on[end if] [the second noun]!”.

Instead of grabbing something from something:
try removing the noun from the second noun instead.

A desk is in Lab. A rock, a pen, and a feather are on the desk. A small rock is in Lab.

Does the player mean grabbing something from something when the second noun is the holder of the noun: it is very likely.

Does the player mean grabbing something from something when the second noun is not the holder of the noun: it is very unlikely.[/code]

but it falls down on “grab rock and pen from desk,” because the ordinary multiple object parsing turns “rock” into the small rock, and that gets thrown out by the multiple action processing rules–and since DTPM Rules don’t work for multiple object actions, there’s nothing we can do about it without some kind of parser lookahead. (“Take rock and pen from desk” works.)

Goo’night.