Re: Simple (?) fix for _call and _str
Lenard Lindstrom <[email protected]>
| Newsgroups | gmane.comp.lang.prothon.user |
|---|---|
| Message-ID | <Mahogany-0.66.0-4294668477-20040628-190525.00@pop3.norton.antivirus> |
On Sat, 26 Jun 2004 21:12:02 -0700 Paul Prescod <[email protected]> wrote: > We want the simplest possible two-tier system. Two-tiers are good > because there really is a difference between (proto)types and instances. > For instance prototypes should be callable and instances shouldn't. But > two-tiers can be bad because in most languages the tiers are so totally > different in behaviour and metadata that it becomes hard to think of > classes as objects (which is why metaclasses are so mind-bending). > > I propose that in Prothon the only difference between prototypes and > instances be a flag called "isProto_". When you create a new object with > the "object" command you get a new prototype. You can also ask for a new > prototype with the function newProto(). Otherwise, you get instances > (e.g. when you call a prototype or use the newObject function). You can > switch something from being a prototype to being an instance just by > switching the flag. > > Based on the flag, the default call_ and str_ will do different things. > See below: > === > > #!/usr/local/bin/prothon -s > # must run with system security level! > > ########## Framework ############### > def newObject(proto, *args, **kwargs): > rc = proto.copy() > rc.protos_ = [proto] > rc.init_(*args, **kwargs) > rc.isProto_ = False > return rc > > def newProto(proto, *args, **kwargs): > rc = newObject(proto, *args, **kwargs) > rc.isProto_ = True > return rc > > Object.isProto_ = True # default for objects. > > Object.typeName_ = "Object" > > def Object.call_(*args, **kwargs): > # print "self in Object.call_", self > if self.isProto_: > return self.new_(*args, **kwargs) > else: > return self.callInst_(*args, **kwargs) > > def Object.new_(*args, **kwargs): > # print "Self in Object.new_", self, self.protos_ > return newObject(self, *args, **kwargs) > > def Object.callInst_(*args, **kwargs): > # print "Object.callInst_" > raise TypeError # ("No such type") > > def Object.str_(): > if self.isProto_: > return "<Prototype: " + self.typeName_ +">" > else: > return self.strInst_() > > def Object.strInst_(): > return "<" + self.typeName_ + " : " + self.id_ + ">" > > ########## User Code ############## > > object Foo: > typeName_ = "Foo" > > foo = Foo() > > print "Foo", Foo > print "foo", foo > print "Foo.isProto_", Foo.isProto_ > print "foo.isProto_", foo.isProto_ > > try: > foo() > print "Exception was not raised!" > except TypeError: > print "Exception raised properly" > > def Foo.callInst_(): > print "In Foo callInst!" > > def Foo.strInst_(): > return "<Instance of foo>" > > foo() # should print out "In foo callInst" > print foo # should print out "<Instance of foo>" > There is no need to have a special isProto flag to tell str_ what to print. In Python classes have names. The Python class statement passes the class name to the class factory function. If Prothon's object or class statement did the same the name could be saved to a name_ attribute of the prototype object. If str_ finds a name_ attribute in an object's dictionary it displays the object as a prototype, otherwise as an instance. My solution to call_ was to not adopt Python's instancd creation by class call aproach. Use a new() function or method instead. Lenard Lindstrom <[email protected]>