[Pyobjc-dev] Bridging of Strings
Brought to you by:
ronaldoussoren
From: <bb...@ma...> - 2002-12-23 16:27:57
|
On Sunday, Dec 22, 2002, at 18:20 US/Eastern, David Eppstein wrote: > Shouldn't this work? > > NSString.localizedCaseInsensitiveCompare_('foo','bar') > > When I try it I get a complaint that the argument should be an > NSString instead of a Python string. I guess this means there is a > signature missing somewhere? I don't understand signatures well > enough to correct it. > > > Really it would be better to be able to call > 'foo'.localizedCaseInsensitiveCompare_('bar') > but I can see why that's unlikely to work... That is exactly what you *should* be able to call but for another problem. Actually, either form should work in the Python sense. This is sort of a bug in the bridge and a feature. Bug: This.... NSString.localizedCaseInsensitiveCompare_('foo', 'bar') ... should really work, but complains about "First argument must be an objective-C object, got 'foo'". I'm somewhat surprised that the bridge doesn't convert 'foo' to an NSString as it hits the bridge because it is a feature of the bridge to transparently convert Strings to their native ObjC/Python type as they pass across the bridge. 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]! --- So-- given that we can't call the methods on NSString via the class object, we really need to be able to pass an NSString across the bridge such that it remains an NSString on the Python side. There are a number of reasons for this-- not duplicating data and having access to the localization methods being the primary reasons. A workaround (for David and others, not a recommendation for a possible solution in the bridge): Create an NSBundle that contains a category or class that wraps the methods on NSString that you need access to. I.e.... @implementation NSString (BridgedMethods) + (NSComparisonResult)string: (NSString *) aString localizedCaseInsensitiveCompare:(NSString *)bString; { return [aString localizedCaseInsensitiveCompare: bString]; } @end ... to be invoked [after loading] as ... NSString.string_localizedCaseInsensitiveCompare_('foo', 'bar') ... not as elegant as an instance method and not directly compatible with the various sorting methods on Array and the like. b.bum |