The Case of the Intransigent Intransitive Verb

Ovid on 2005-11-07T00:10:47

It was a complete mystery. My beautifully implemented Model::World test had the following line of code:

$player->put($box, $ring);

And that dies with the message:

You can't put anything in the player

The intent was, when a player receives a message, it assumes it has a verb, an optional object, and zero or more arguments after that. However, the box, ring, and player classes are all subclasses of the Thing class. This was bad. Everytime I add a possible "Verb" to the box class, player should not automatically inherit it. Instead, the player should always be able to inspect a thing and figure out what it can do. I can override put in the player class, but every time I add a verb for the box class, I have to remember to override it in the player class. This is wrong.

Instead, I need to create an "abstract thing" class which provides only the tiniest amount of code. Then the player can inherit from the abstract thing class and a "item" (bad name) or other class can also inherit from that and the box and ring inherit from the item class. Thus I avoid bad inheritance.

The comes a real problem: what can a player do? A player can "do" any verb the player defines. These are often intransitive verbs, verbs which do not take a direct object. For example, "Johns jumps" has an intransitive verb. A player can also "do" any verb a thing allows. If a Box class supplies a "break" method (and verb), then "John breaks the box" is allowed and this calls the "box->break" method.

The problem comes in when a verb can be used either transitively or intrasitively. A player can just "look around" and we have an intransitive verb. What if a player looks at another player? Now it's not an intransitive verb. I can't just "player2->look". So now when actions are performed, I'll have to consider whether the invocant is the subject or the object of the action. I'm sure there is a simple way of doing this, but I'm going to have to mull over this for a while.


Don't throw away information...

pdcawley on 2005-11-07T06:55:42

sub look {
    my($self, $object) = @_;
    if ($self == $object) { ... }
    else { $object->look($object) }
}


Easy.
   

Two actions

VSarkiss on 2005-11-07T14:51:13

It sounds like you have two different methods, look_around and look_at. The former doesn't take an object, the latter does.

OT: Agents

Theory on 2005-11-07T16:09:11

Are the agents of verbs (the subjects) always players? Could they be other things (bots, monsters, etc.)? Perhaps the class should be Agent rather than Player.

—Theory