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]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.