Hi. I've made some changes to POO, and I'd like to share them with you. 1. In functions and in ;-commands, you can use $objects. These are internally expanded when the function is compiled or the ;-command is executed. So, ;print $pub becomes ;print getObj('$pub') the code is smart, and should manage to change things only where necessary. ;print """$pub""", "is", $pub # $pub will only alter the unquoted, non-comment $pub. One still cannot use '#ddd' notation in POO code. 2. Certain important @setperm commands are added to bootstrap.txt 3. A new program, pooboot.py, will bootstrap the database without user intervention. 4. bootstrap.txt was changed to use $-notation. To get rid of the $-notation, just run 'python dollar.py < bootstrap.txt > newboot.txt; mv newboot.txt bootstrap.txt'. 5. getCmdDef returns all CmdDefs on an object and its ancestors when verb=="". 6. Several demo objects are included in lib/ 7. 'show()' works with all the arguments that msg.py permits -- in particular, now strings, tuples, and lists can be passed as well as POO Objs. Unfotunately, tuples like [Obj1, Obj2] don't behave quite as expected. 8. Create a guest, prevent him from setting his home or changing his password diff -x *~ -x *.pyc -x CVS -x poo.dat -u --new-file -r poo/bootstrap.txt poo-jepler/bootstrap.txt --- poo/bootstrap.txt Tue Jun 10 19:11:46 1997 +++ poo-jepler/bootstrap.txt Sun Jun 29 07:49:50 1997 @@ -58,14 +58,14 @@ ;#================== Basic Building & Coding ================ ;print "$coder.@newfunc" -;caller.enterFunc( getObj('$coder'), 'newfunc(self,caller,obj,funcname)' ) +;caller.enterFunc( $coder, 'newfunc(self,caller,obj,funcname)' ) caller.enterFunc( obj, funcname ) .x -;getObj("$coder").setCmdDef('@newfunc','@newfunc .', 'newfunc(caller,%1,%2)' ) -;getObj("$coder").setCmdDef('@newfunc','@newfunc ', 'newfunc(caller,caller,%1)' ) -;getObj("$coder").setCmdDef('@newfunc','@newfunc on ', 'newfunc(caller,%2,%1)' ) -;getObj("$coder").newfunc.desc = "create a new function" -;getObj("$coder").getprop('newfunc').owner = None +;$coder.setCmdDef('@newfunc','@newfunc .', 'newfunc(caller,%1,%2)' ) +;$coder.setCmdDef('@newfunc','@newfunc ', 'newfunc(caller,caller,%1)' ) +;$coder.setCmdDef('@newfunc','@newfunc on ', 'newfunc(caller,%2,%1)' ) +;$coder.newfunc.desc = "create a new function" +;$coder.getprop('newfunc').owner = None ;print "$coder.@cmd" @newfunc $coder.at_cmd(self, obj, pattern, funcdef) @@ -73,9 +73,9 @@ obj.setCmdDef(verb, pattern, funcdef) print verb, "command defined on", obj .x -;getObj("$coder").setCmdDef('@cmd','@cmd . calls ', 'at_cmd(%1,%2,%3)' ) -;getObj("$coder").at_cmd.desc = "set a CmdDef" -;getObj("$coder").getprop('at_cmd').owner = None +;$coder.setCmdDef('@cmd','@cmd . calls ', 'at_cmd(%1,%2,%3)' ) +;$coder.at_cmd.desc = "set a CmdDef" +;$coder.getprop('at_cmd').owner = None ;print "$builder.@set" @@ -86,7 +86,7 @@ @cmd $builder.@set . to calls at_set(%1,%2,%3) @cmd $builder.@set .= calls at_set(%1,%2,%3) @set $builder.at_set.desc = "set a property value" -;getObj("$builder").getprop("at_set").owner = None +;$builder.getprop("at_set").owner = None ;print "$wiz.@setown" @@ -141,7 +141,7 @@ "$builder.@create" @newfunc $builder.create(self,parent,newname='') -if parent.isa(getObj('$user')) and not self.wizard: +if parent.isa($user) and not self.wizard: print "Only wizards can create users." return ob = create(self, parent, newname) @@ -150,7 +150,6 @@ @cmd $builder.@create as calls create(%1,%2) @set $builder.create.desc = "make a new POO object" - "$wiz.beam" @newfunc $wiz.beam(self,obj,where) move(obj,where) @@ -179,6 +178,7 @@ self.component = compName return self .x +@setown $thing.findComponent = None ;#======================= Looking & Describing ================= "$base.description" @@ -292,7 +292,6 @@ @cmd $agent.take calls get(%1) @set $agent.get.desc = "get an object" - "$agent.drop" @newfunc $agent.drop(self,dobj) if dobj.location != self: @@ -304,7 +303,6 @@ @cmd $agent.drop calls drop(%1) @set $agent.drop.desc = "drop an object" - "$user.inventory" @newfunc $user.inventory(self) if not self.contents and not self.__credits: @@ -342,7 +340,6 @@ @cmd $agent.@home calls at_home() @set $agent.at_home.desc = "teleport to self.home" - "$agent.@sethome" @newfunc $agent.sethome(self) self.home = self.location @@ -374,7 +371,6 @@ @cmd $builder.@recycle calls recycle(%1) @set $builder.recycle.desc = "destroy a POO object" - "$builder.@setperm" @newfunc $builder.setperm(self,obj,propname,perms) prop = obj.getprop(propname) @@ -391,7 +387,12 @@ @cmd $builder.@setperm . = calls setperm(%1,%2,%3) @set $builder.setperm.desc = "set permissions on a property" @setown $builder.setperm = None - +@setperm $builder.recycle = rc +@setperm $agent.sethome = rc +@setperm $agent.at_home = rc +@setperm $agent.drop = rc +@setperm $agent.get = rc +@setperm $builder.create to rc "$builder.showprops" @newfunc $builder.showprops(self,what,header='',test=None) @@ -467,7 +468,7 @@ @set $exit.invoke.desc = "move caller to .dest" @cmd $exit. calls invoke(caller) @cmd $exit.go calls invoke(caller) - +@setperm $exit.invoke = rc ;#==================== Directories ===================== "$dir.description" @@ -486,15 +487,16 @@ "$dir.enter" @newfunc $dir.enter(self,who) if self.owner == who or who.wizard or self.r: move(who,self) who.do_cmd('look') else: print "You do not have permission to enter that directory." + .x @cmd $dir.enter calls enter(caller) @set $dir.enter.desc = "Enter a directory." - +@setperm $dir.enter = rc "$dir.up" @newfunc $dir.up(self,who) @@ -503,14 +505,14 @@ .x @cmd $dir.up calls up(caller) @set $dir.up.desc = "Go to the object containing this directory." - +@setperm $dir.up = rc ;#================= Initial Geography ================= @create $thing as Void @set #0.void = Void @set Void.desc = "This object contains the main directories and the universe of rooms in the system." @set Void.accept = 1 -;move(getObj('$void'),None) +;move($void,None) @create $place as Universe @set #0.universe = Universe @@ -606,7 +608,7 @@ @cmd $agent.@page = calls page(%1,%2) @cmd $agent.@page = calls page(%1,%2) @set $agent.page.desc = "send a message to a user" - +@setown $agent.page = None ;#------- extra functions on $user ------- @@ -696,11 +698,11 @@ return # create the room; place in same location as this room if type(newroom) != InstanceType: - newroom = create( self, getObj('$place'), newroom ) + newroom = create( self, $place, newroom ) move( newroom, self.location.location ) print newroom.name, "created as object", newroom, \ "and moved to", newroom.location, '(' + newroom.location.name + ')' -exitThere = create( self, getObj('$exit'), names[0] ) +exitThere = create( self, $exit, names[0] ) exitThere.aliases = names[1:] exitThere.dest = newroom exitThere.getprop('dest').owner = self @@ -708,7 +710,7 @@ print "Exit", exitThere.name, "created in", \ self.location.name, "as object", exitThere -exitHere = create( self, getObj('$exit'), revnames[0] ) +exitHere = create( self, $exit, revnames[0] ) exitHere.aliases = revnames[1:] exitHere.dest = self.location exitHere.getprop('dest').owner = self @@ -719,7 +721,7 @@ @cmd $builder.@dig to calls dig(%1,%2) @cmd $builder.@dig to calls dig(%1,%2) @set $builder.dig.desc = "create a room connected to the current one" - +@setperm $builder.dig = rc "$builder.@renprop" @newfunc $builder.renprop(self,obj,oldname,newname ) @@ -818,7 +820,7 @@ print base.name, ob.name, "created as object", str(ob.id)+"." print "Password set to", ob.name try: - setattr(getObj('$usr'), ob.name, ob) + setattr($usr, ob.name, ob) print "$usr." + ob.name, "set to", ob except: print "Couldn't set $usr." + ob.name @@ -875,7 +877,7 @@ @cmd $container.get out of calls getContent(%1,caller) @cmd $container.get in calls getContent(%1,caller) @set $container.getContent.desc = "get object from contents" - +@setperm $container.getContent = rc "$container.put" @newfunc $container.put(self,what,who) @@ -888,7 +890,7 @@ @cmd $container.put into calls put(%1,caller) @cmd $container.put in calls put(%1,caller) @set $container.put.desc = "put object into contents" - +@setperm $container.put = rc "$container.description" @newfunc $container.description(self,looker) @@ -907,3 +909,21 @@ @set $container.description.desc = "list contents after description" @setown $container.description = None +@newuser $sys.usertypes.User as Guest +@set #0.guest = Guest + +"$guest.@password" +@newfunc $guest.passwd(self) +print "Guests can't change password." +.x +@cmd $guest.@password calls passwd() +@cmd $guest.@password calls passwd() +@setown $guest.password = None + +"$guest.@sethome" +@newfunc $guest.sethome(self) +print "Guests can't change their home." +.x +@cmd $guest.@sethome calls sethome() +@cmd $guest.@sethome calls sethome() +@setown $guest.sethome = None diff -x *~ -x *.pyc -x CVS -x poo.dat -u --new-file -r poo/dollar.py poo-jepler/dollar.py --- poo/dollar.py Wed Dec 31 18:00:00 1969 +++ poo-jepler/dollar.py Sun Jun 29 07:49:53 1997 @@ -0,0 +1,87 @@ +import string +import regex + +def myfind(s, sub, start=0): + """ +Like string.find, but returns len(s)+1 when not found, not -1 +""" + x = string.find(s, sub, start) + if x==-1: return len(s) + else: return x + +def myregfind(s, sub, start=0): + """ +Like string.find, but returns len(s)+1 when not found, not -1 +""" + x = regex.match(s[start:], sub) + if x==-1: return len(s) + else: return x+start + +def dollar(str): + """ +Convert each instance of '$foo' to 'getObj("foo")', +correctly avoiding all sorts of quotes and comments +""" + ret="" + while str: + sq, dq, do, ha = tuple(map(lambda x, str=str: myfind(str, x), "'\"$#")) + m=min(sq,dq,do,ha) + #print m, sq, dq, do, ha + if m>=len(str): # Nothing special left + x=m + elif sq==m: + if str[sq:sq+3]=="'''": # Handle triple squote + x=m+1 + while x calls poke(caller) +@cmd pad.poke at calls poke(caller) +@cmd pad.poke on calls poke(caller) +@cmd pad.poke on calls poke(caller,%1) +@cmd pad.poke on calls poke(caller,%1) +poke 1 on pad +poke 3 on pad +stand on pad +@home +;print "Transporter pad done" diff -x *~ -x *.pyc -x CVS -x poo.dat -u --new-file -r poo/lib/replicator.poo poo-jepler/lib/replicator.poo --- poo/lib/replicator.poo Wed Dec 31 18:00:00 1969 +++ poo-jepler/lib/replicator.poo Sun Jun 29 08:00:29 1997 @@ -0,0 +1,25 @@ +say "replicator by Stylus@starship.skyport.net:4000 (jepler@inetnebr.com)" +@newfunc replicator.order(self, what) +x=string.lower(what) +self.orderstr=what +self.Orderstr=string.upper(what[0])+what[1:] +show(self.giveOrderMsg, {1:user, 2:self}) +for f in self.forbidden: + if string.find(x, f) != -1: + show(self.forbiddenMsg, {1:user , 2:self}) + self.orderstr=self.Orderstr=None + return +show(self.completeOrderMsg, {1:user, 2:self}) +self.orderstr=self.Orderstr=None +. +@setperm replicator.order to rc +@cmd replicator.order from calls order(%1) +@set self.replicator=replicator +;self.replicator.forbiddenMsg = "%2D %2:(buzzes) at %1i and says, \"You may not order %2.(orderstr) from this replicator.\"" +@set replicator.giveOrderMsg = "%1D %1:(orders) %2.(orderstr) from %2i." +@set replicator.completeOrderMsg = "%2.(Orderstr) materializes in %2i." +@set replicator.forbidden = beef,ham,meat,chicken,flesh,shit,fish,tuna,salmon,veal,lamb,spam,steak +@set replicator.desc = "The replicator is composed of a computer panel and a small recess in the wall. Order what you like from this replicator, but be aware that it has a restricted menu." +@set replicator.f to 1 +@delprop me.replicator +say "Done with replicator diff -x *~ -x *.pyc -x CVS -x poo.dat -u --new-file -r poo/lib/tribble.poo poo-jepler/lib/tribble.poo --- poo/lib/tribble.poo Wed Dec 31 18:00:00 1969 +++ poo-jepler/lib/tribble.poo Sun Jun 29 08:04:06 1997 @@ -0,0 +1,9 @@ +@newfunc tribble.hear(self, str) +if randint(0, self.den) > self.num: return # Purr num/den of the time +x=filter(lambda x, self=self: x.salient and x is not self, self.location.contents()) +target=x[randint(0, len(x)+1)] +show("%1D %1:(purrs) contentedly at %2n.", {1:self, 2:target}) +.x +@set tribble.den=2 +@set tribble.num=1 +"hi diff -x *~ -x *.pyc -x CVS -x poo.dat -u --new-file -r poo/poo.py poo-jepler/poo.py --- poo/poo.py Wed Jun 11 10:14:01 1997 +++ poo-jepler/poo.py Sun Jun 29 07:59:20 1997 @@ -16,6 +16,7 @@ import marksub import msg from pooparse import HandleCommand, CmdDef +from dollar import dollar gObjlist = {} # global dictionary of POO objects gHighID = 0 # highest ID used @@ -142,7 +143,7 @@ paramdef = self.name[pos+1:-1] fullsource = 'def f(' + paramdef + '):\n ' \ + self.__dict__['presource'] + '\n ' \ - + string.join(self.source,'\n ') + '\n' + + dollar(string.join(self.source,'\n ')) + '\n' if gUnpickling: try: self.__dict__['code'] = compile(fullsource,'<'+self.name[:pos]+'>','exec') except: return @@ -924,7 +925,7 @@ try: if not self.programmer: raise "PermError", "requires programmer privs" - exec(cmd[1:]) in gSafeGlobals, locals + exec(dollar(cmd[1:])) in gSafeGlobals, locals except: self.handleErr(sys.exc_type, sys.exc_value, sys.exc_traceback) else: @@ -1001,7 +1002,11 @@ out = () if gCmdDefs.has_key(self): defs = gCmdDefs[self] - if defs.has_key(verb): + if not verb: + for i in defs.values(): + for j in i: + out = out + (j,) + elif defs.has_key(verb): out = defs[verb] # then, add commands from parents @@ -1751,6 +1756,8 @@ # tell each one for i in range(0,len(values)): +# Maybe we shouldn't give up so easay on [objspec,...] + if type(values[i]) is not InstanceType: continue values[i].tell(outputs[0][i]) # and finally, broadcast the general message if possible diff -x *~ -x *.pyc -x CVS -x poo.dat -u --new-file -r poo/pooboot.py poo-jepler/pooboot.py --- poo/pooboot.py Wed Dec 31 18:00:00 1969 +++ poo-jepler/pooboot.py Sun Jun 29 07:59:20 1997 @@ -0,0 +1,65 @@ +#!/usr/bin/env python +#---------------------------------------------------------------------- +# pooboot.py JBE 3/01/97 +# +# This module takes the cut'n'paste out of bootstrapping, +# and connects the engine directly to a specified file. +# Borrowed heavily from JJS' poodirect.py, and should probably +# be a part of it rather than separate. +#---------------------------------------------------------------------- +#---------------------------------------------------------------------- + +import poo +import sys +term = sys.stdout + +def AskYesNo(prompt, default='Y'): + while 1: + ans = raw_input(prompt + ' [' + default + '] ') + if len(ans) > 1: ans = ans[0] + if ans == '': ans = default + if ans == 'y' or ans == 'Y': return 1 + if ans == 'n' or ans == 'N': return 0 + print ("Please enter Y or N.") + +def bootstrap(): + # check for poo.dat + try: + file = open('poo.dat', 'r') + file.close() + print "poo.dat must not exist when bootstrapping." + return 0 + except: + print "poo.dat doesn't exist." + poo.initialize(1) + + bootstrapfile=open("bootstrap.txt") + + matches = filter(lambda x: x.__isuser , poo.gObjlist.values()) + if not matches: + print "User not found." + return + + user = matches[0] + user.Login(term) + + done = 0 + while not done: + sys.stdout = term + cmd = bootstrapfile.readline() + if cmd == "": cmd = "quit" + while cmd and cmd[-1] in '\r\n': cmd=cmd[:-1] + print cmd + if cmd == "quit" or cmd == "@quit": done = 1 + elif cmd == "savedb": poo.gSave() + else: + user.handleMsg(cmd) + for i in range(10): poo.gUpdate() +# poo.gUpdate() + + try: user.Logout() + except: print "Problem calling user.Logout()" + sys.stdout = term + poo.gSave() + +bootstrap() diff -x *~ -x *.pyc -x CVS -x poo.dat -u --new-file -r poo/poodirect.py poo-jepler/poodirect.py --- poo/poodirect.py Sun Mar 2 13:02:31 1997 +++ poo-jepler/poodirect.py Sun Jun 29 07:59:21 1997 @@ -1,3 +1,4 @@ +#!/usr/bin/env python #---------------------------------------------------------------------- # poodirect.py JJS 3/01/97 # diff -x *~ -x *.pyc -x CVS -x poo.dat -u --new-file -r poo/poosock.py poo-jepler/poosock.py --- poo/poosock.py Wed Apr 16 21:32:20 1997 +++ poo-jepler/poosock.py Sun Jun 29 09:29:51 1997 @@ -1,3 +1,4 @@ +#!/usr/bin/env python #---------------------------------------------------------------------- # poosock.py JJS 4/16/97 # @@ -181,9 +183,11 @@ sys.stdout = stdout if useSelect: filenums = map(lambda x:x.fileno(), connsToCheck) - fnswinput = select(filenums, [], [], 0)[0] + fnswinput = select(filenums, [], [], 0.33)[0] connsToCheck = filter(lambda x,y=fnswinput:x.fileno() in y, connsToCheck) + else: + sleep(0.33) for u in connsToCheck: try: data = u.conn.recv(1024) @@ -312,7 +316,6 @@ StartServer() # start the server while running > -2: - sleep(0.33) NetUpdate() # loop until done poo.gUpdate()