MantisBT - I6 Library
View Issue Details
0002052I6 LibraryGeneralpublic2018-02-17 21:172018-04-16 01:31
turthalion 
DavidG 
normalseriousalways
resolvedfixed 
x86Windows7
6/11 
 
0002052: Inform library calls "after" rule when a container is inserted in an unopened container
Given the following code snippet:
Object -> plain_bag "plain shopping bag"
with name 'plain' 'shopping' 'bag',
description "A plain shopping bag that can hold 2 things.",
      capacity 2,
      has ~open openable container;

Object -> jar "jar"
with name 'jar',
description "A jar.",
      capacity 2,
      after [;
        Open: print "You twist off the lid of the jar";
          if (children(self) == 0)
            ". The jar is empty.";
          print ", revealing ";
          WriteListFrom(child(self), ENGLISH_BIT);
          print_ret ".";
      ],
      has ~open openable container;

Object -> -> jam "jam"
with name 'jam',
      article "some",
description "Some jam.",
  has edible;

... the following output is produced:
Kitchen
This is a large country-style kitchen.

You can see a plain shopping bag (which is closed) and a jar (which is closed) here.

>open jar
You twist off the lid of the jar, revealing some jam.

>close jar
You close the jar.

>put jar in bag
(first taking the jar)
(first opening the plain shopping bag)
You twist off the lid of the jar, revealing some jam.
You put the jar into the plain shopping bag.

>x jar
A jar.

>l

Kitchen
This is a large country-style kitchen.

You can see a plain shopping bag (in which is a jar (which is closed)) here.

>


When the jar was put in the shopping bag, the shopping bag needed to be opened, but the after rule for the jar was printed. As seen by looking afterwards, the jar did NOT open, but its after rule was run.
No tags attached.
Issue History
2018-02-17 21:17turthalionNew Issue
2018-03-30 20:04jpavelNote Added: 0004765
2018-03-30 20:10jpavelIssue Monitored: jpavel
2018-03-30 20:14jpavelNote Added: 0004766
2018-04-02 06:41DavidGAssigned To => DavidG
2018-04-02 06:41DavidGStatusnew => assigned
2018-04-02 06:42DavidGNote Added: 0004767
2018-04-02 06:42DavidGNote Added: 0004768
2018-04-02 06:43DavidGStatusassigned => resolved
2018-04-02 06:43DavidGResolutionopen => fixed
2018-04-16 01:31jpavelIssue End Monitor: jpavel

Notes
(0004765)
jpavel   
2018-03-30 20:04   
Looking at this message trace

> put jar in bag
[Moving jar to yourself]
(first taking the jar)
[ "country style kitchen".before() ]
[ "jar".before() ]
[ "plain shopping bag".before() ]
[ "country style kitchen".before() ]
[ "plain shopping bag".before() ]
[Giving plain shopping bag open]
(first opening the plain shopping bag)
[ "country style kitchen".after() ]
[ "jar".after() ]
You twist off the lid of the jar, revealing some jam.
[Moving jar to plain shopping bag]
[ "country style kitchen".after() ]
[ "jar".after() ]
[ "plain shopping bag".after() ]
You put the jar into the plain shopping bag.

We see that ImplicitOpen is calling after() on the wrong object (jar rather than bag).

ImplicitOpen calls AfterRoutines() after performing the <Open ...> action, but we see in AfterRoutines

   if (inp1 > 1 && RunRoutines(inp1, after)) rtrue;

that it checks inp1, which in this case is the jar, and runs its after routine.

I've only just begun looking at the library, so how to fix this safely, I don't know.

~Jesse
(0004766)
jpavel   
2018-03-30 20:14   
I've tried replacing ImplicitOpen so that it sets inp1 to obj before calling AfterRoutines(), and it *seems* to work...

(see code below)

Jesse
--------------
Replace ImplicitOpen; ! Before Include "VerbLib"

! ==========================
! and later on in your story

[ ImplicitOpen obj
    res temp temp2;
    if (obj has open) rfalse;
    res = CheckImplicitAction(##Open, obj);
    ! 0 = Open object, Tell the user (normal default)
    ! 1 = Open object, don't Tell
    ! 2 = don't Take object continue (default with no_implicit_actions)
    ! 3 = don't Take object, don't continue
    if (res >= 2) rtrue;
    if (obj has locked) rtrue;
    temp = keep_silent; keep_silent = 2; <Open obj, actor>; keep_silent = temp;
    if (obj hasnt open) rtrue;
    if (res == 0 && ~~keep_silent) L__M(##Open, 6, obj);
    temp = action; action = ##Open;
    temp2 = inp1; inp1 = obj;
    AfterRoutines();
    inp1 = temp2;
    action = temp;
    rfalse;
];
(0004767)
DavidG   
2018-04-02 06:42   
Also reported at https://github.com/DavidGriffith/inform6lib/issues/52 [^]
(0004768)
DavidG   
2018-04-02 06:42   
Fix applied in https://github.com/DavidGriffith/inform6lib/pull/53 [^]