Re: [Pyobjc-dev] unbound methods
Brought to you by:
ronaldoussoren
From: Ronald O. <ous...@ci...> - 2003-01-01 09:27:52
|
On Tuesday, Dec 31, 2002, at 17:34 Europe/Amsterdam, bb...@ma... wrote: > On Monday, Dec 23, 2002, at 14:30 US/Eastern, Ronald Oussoren wrote: >>> Rethinking this, the above method call may not work in some >>> situations. In particular, in class clusters it is often the case >>> that you generally interact with some private subclass. For >>> example, NSArray.count(someArray) will not actually do what you want >>> because instances of NSArray are never directly instantiated-- just >>> private subclasses. >>> >>> In [6]: a = NSArray.arrayWithArray_([1,2,3,4,5]) >>> In [7]: a.count() >>> Out[7]: 5 >>> In [8]: NSArray.count(a) >>> --------------------------------------------------------------------- >>> ------ >>> ValueError Traceback (most recent >>> call last) >>> >>> ? >>> >>> ValueError: NSInvalidArgumentException - *** -count only defined for >>> abstract class. Define -[NSCFArray count]! >>> >> >> That's just like in 'normal' python types: If you call NSArray.count >> you get the count method defined by NSArray instead of the one >> defined by the class of your object. That is not very >> Objective-C-like, but this is needed to implement super(cls, >> self).count(). > > Right. However, the ability to use unbound methods is very much a > feature of Python that a lot of people use... > > Is there a way to support this a bit more cleanly/flexibly in light of > ObjC's ability to have a class method and an instance method of the > same name? > > I.e. say a class Foo implements both a +foo and a -foo method and you > have an instance called aFoo. > > You really want to be able to do... > > Foo.foo(aFoo) > > ... and call the instance method. But you also want to be able to > do... > > Foo.foo() That would be nice, but not possible. It might be possible to get 'Foo.foo(Foo)' working if the class method has the same signature as the instance method, but that wouldn't allow overriding the class method in subclasses. But all is not lost, read on ;-) > > ... and call the class method. Or, maybe, you want to do... > > Foo.foo_(aFoo) That would be [aFoo foo:] in Objective-C ;-). More seriously, that wouldn't be usefull because the Python runtime looks for 'Foo.foo' when you do 'aFoo.foo()'. This is what is causing us problems here. > > ... where you are calling the class method and passing an instance as > the argument? > > This isn't terribly clear, but I'm hoping it gets across the general > idea that we should be able to support both class and instance methods > that are named the same.... > > One possibility would be to pass a kv argument that indicates that the > class implementation should be used if there is both a class and an > instance version-- i.e. Foo.foo(aFoo, useClassMethod=1)? > > But that would not allow an unbound version of the method to be > obtained that is explicitly tied to class or instance...? We could mangle names of class methods, either by having a magic class property for accessing class methods or by adding a prefix/postfix to the methodname: * Foo.__clsmeth__.foo() * Foo._cls_foo() * Foo.foo_cls() I'd prefer the middle one given a suitable prefix: short, easily remembered and not likely to ever be used as the prefix of an Objective-C selector. If we go this route we should keep supporting the current behaviour; NSArray.arrayWithArray_ should not be renamed to NSArray._cls_arrayWithArray_, that would just be confusing. I'm not sure wether we should support both naming schemes for class methods that don't conflict with instance methods. Ronald |