Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Perl] Implementing Objects?

3 views
Skip to first unread message

Ricardo Dague

unread,
Jun 3, 1999, 3:00:00 AM6/3/99
to
Any ideas out there on the best way to implement Inform-like
objects in Perl? The obvious way to do it is with hash
references. Here's an example of two rooms, each with an
exit to the other one:

$room2 = {};
$room1->{"e_to"} = $room2;
$room2->{"w_to"} = $room1;

The first line "prototypes" the object $room2, which you
have to do since otherwise $room2 is undefined in the second
line. This seems awkward to me; I don't like it. It'd be
frustrating to code a few objects and have to scan them to
see which need prototyping. Then if I changed the order of
the objects, I'd have to re-prototype.

Another way would be to automatically prototype with a
function:

sub obj { return $_[0] if defined($_[0]); return ($_[0] =
{}); }
$room1->{"e_to"} = obj $room2;
$room2->{"w_to"} = obj $room1;

Better, but it's more typing, and it'd be a pain if you
forgot to use the function.

The method I'm leaning toward is to have one big hash which
associates the name of the object and the name of the
property to a value:

%member{"room1 e_to"} = "room2";
%member{"room2 w_to"} = "room1";

Each object isn't a variable, it's identified by a string.
This is the messiest notation (IMO) of the three, but you
don't have to worry about prototyping at all.

Actually, these are more like TADS objects, aren't they?

Questions? Comments? Anyone want a mint?

-- Ricardo
"You believe in GOD? I wanna know 'cause I'm a RETARD."

David Glasser

unread,
Jun 3, 1999, 3:00:00 AM6/3/99
to
Ricardo Dague <tri...@hotmail.com> wrote:

> Any ideas out there on the best way to implement Inform-like
> objects in Perl? The obvious way to do it is with hash
> references. Here's an example of two rooms, each with an
> exit to the other one:

You could write an "object-oriented"-style module and use "real" Perl
"objects", which would be blessed hash refs. You'd still need to
initialize them with a new command, but you do that in Inform too,
right?

Try perldoc perlobj

--
David Glasser: gla...@iname.com | http://www.uscom.com/~glasser/
DGlasser@ifMUD:orange.res.cmu.edu 4001 | raif FAQ http://come.to/raiffaq
"Maybe Glulxification will cause people to start using Scheme for IF. Or
maybe not. Anyhow, I just like saying 'Glulxification'." -andyf on ifMUD

Adam J. Thornton

unread,
Jun 3, 1999, 3:00:00 AM6/3/99
to
In article <374FBF59...@hotmail.com>,

Ricardo Dague <tri...@hotmail.com> wrote:
>Any ideas out there on the best way to implement Inform-like
>objects in Perl?

>Questions? Comments? Anyone want a mint?

I like a cork nut.

But that's another language entirely.

Adam

PS That's what *she* sed.
--
ad...@princeton.edu
"My eyes say their prayers to her / Sailors ring her bell / Like a moth
mistakes a light bulb / For the moon and goes to hell." -- Tom Waits

David Given

unread,
Jun 4, 1999, 3:00:00 AM6/4/99
to
In article <374FBF59...@hotmail.com>,
Ricardo Dague <tri...@hotmail.com> writes:
[...]

> The first line "prototypes" the object $room2, which you
> have to do since otherwise $room2 is undefined in the second
> line. This seems awkward to me; I don't like it. It'd be
> frustrating to code a few objects and have to scan them to
> see which need prototyping. Then if I changed the order of
> the objects, I'd have to re-prototype.
[...]

List all your objects at the beginning of the file.

$room1 = {}
$room2 = {}
$room3 = {}

..

$room1->{"e_to"} = $room2
$room2->{"w_to"} = $room1

$room2->{"e_to"} = $room3
$room3->{"w_to"} = $room2

It's probably good practice, anyway, because then you can comment what
room does what.

--
+- David Given ---------------McQ-+ "...it's not that well-designed GUI's are
| Work: d...@tao-group.com | rare, it's just that the three-armed users
| Play: dgi...@iname.com | GUI's are designed for are rare." --- Mike
+- http://wired.st-and.ac.uk/~dg -+ Uhl on a.f.c

Ricardo Dague

unread,
Jun 5, 1999, 3:00:00 AM6/5/99
to
David Glasser wrote:
>
> Ricardo Dague <tri...@hotmail.com> wrote:
>
> > Any ideas out there on the best way to implement Inform-like
> > objects in Perl? The obvious way to do it is with hash
> > references. Here's an example of two rooms, each with an
> > exit to the other one:
>
> You could write an "object-oriented"-style module and use "real" Perl
> "objects", which would be blessed hash refs. You'd still need to
> initialize them with a new command, but you do that in Inform too,
> right?

Check. I hadn't studied Perl objects, since I assumed they'd
be too hard to use. That's what I feel about C++ objects.

So here's a little implementation of Inform-like objects,
though it's incomplete. Note that a method would, in
general, change the value of a property if called with
arguments.

Without args, it would process the value somehow. For
example, "$ball->name()" (the parentheses aren't necessary)
would check the input line to see if the ball was named.
"$ball->before()" would print the a string or run code
depending on which action was in effect, i.e.
"$ball->{BEFORE}->{$action}".

Also, the "pr" function would remove any newlines from its
input and change the ~ and ^ to double-quotes and newlines.

#!/usr/bin/perl
package Room;
#method definitions here...

package Thing;
#method definitions here...

package Scenery;
@ISA = qw(Thing);
#method definitions here...

package Actor;
@ISA = qw(Thing);
#method definitions here...

package main;

$gymnasium = Room->new("Gymnasium");
$clock = Scenery->new("large clock",$gymnasium); #name and
initial
#location
$flag = Scenery->new("flag",$gymnasium);
#also bleachers, basketball court, backboards etc objects

$ball = Thing->new("orange ball",$player);
$jackson = Actor->new("Mr. Jackson",""); #not anywhere
initially

$gymnasium->description("This is a huge area with bleachers
on either
side of a basketball court. A large clock is up on one wall,
under an
American flag.");
$gymnasium->light(1);

$clock->name("large","clock"); #$clock->{NAME} =
['large','clock']
$clock->description("It's about twenty feet off the floor
with ~Mt.
Vernon Middle School~ written in garish green around it.");
#$clock->{DESCRIPTION} =
"It's..."

$flag->name("american","flag");
$flag->description("A rectangular cloth with red and white
stripes, and
stars on a blue background in one corner, right?");

$ball->name("orange","ball");
$ball->before(
BOUNCE=>"Boing! Boing!",
THROWAT=>sub {
return unless $second eq $clock;
$self->parent(""); #like remove
self
$jackson->parent($location); #move jackson
to location
$clock->general(1); #give clock
general
pr "You hurl it at the clock ... CRACK!!
Perfect!
Right in the center!^^Mr. Jackson runs up, befuddledly
looking from his
wristwatch to the now stopped clock. ~What the heck are you
doing??!~ he
demands.^";
return 1;
}); #$ball->{BEFORE} = {BOUNCE=> ...}

$jackson->name("mr","jackson","teacher","man");
$jackson->proper(1);
$jackson->life(
TELL=>sub {
pr "He's not interested.^",return 1
unless $noun eq $clock;
pr("~I didn't do it,~ you reply, trying
to look
innocent.^"),
return 1
if $clock->general;
pr "You know nothing interesting about it
(yet).^";
return 1;
});

David Glasser

unread,
Jun 5, 1999, 3:00:00 AM6/5/99
to
Ricardo Dague <tri...@hotmail.com> wrote:

> Check. I hadn't studied Perl objects, since I assumed they'd
> be too hard to use. That's what I feel about C++ objects.
>
> So here's a little implementation of Inform-like objects,
> though it's incomplete. Note that a method would, in
> general, change the value of a property if called with
> arguments.
>
> Without args, it would process the value somehow. For
> example, "$ball->name()" (the parentheses aren't necessary)
> would check the input line to see if the ball was named.
> "$ball->before()" would print the a string or run code
> depending on which action was in effect, i.e.
> "$ball->{BEFORE}->{$action}".

Cool. One more suggestion that could make initializing objects a bit
simpler, in addition to the way you have it, would be to have a
"properties" function or something:

$joe->properties( {
name => "joe",
description => "funny-looking",
});

my %joesProps;

%joesProps = joe->properties(); # this just returns them, not makes
# %joesProps an alias or something,
# though I guess you could

You could put it in an Object package or something that all other
pacakges inherit from.

sub properties {
my ($self) = shift;
my $el;
die "properties list has odd number of entries" if
if ($#_ %2) == 1;
if (@_) {
while (@_) {
$el = shift;
$self{$el} = shift;
}
else {
# returning hash is an exercise for the reader
}
}

Or something like that (this code is untested, and the $self{$el} =
shift; line is almost certainly wrong).

--
David Glasser: gla...@iname.com | raif FAQ: http://come.to/raiffaq/
"It's good to explore the G.U.E. caves / It's good to explore the G.U.E.
caves / You can count all the leaves / You can KILL TROLL WITH SWORD /
You'll get stuck but you won't be bored"-Joe.Mason, rec.arts.int-fiction

Joe Mason

unread,
Jun 6, 1999, 3:00:00 AM6/6/99
to
David Glasser <gla...@iname.com> wrote:
>$joe->properties( {
> name => "joe",
> description => "funny-looking",
>});

Hey!

Joe
--
"Think hard and long about what your favorite book is. Once identified, read
it a paragraph at a time. Then after having read the paragraph, read each
sentence. See the way the sentences interrelate. Then, read the words..."
-- Mike Berlyn, on learning to write

0 new messages