Thread: [Pyobjc-dev] F-script may be worth a look
Brought to you by:
ronaldoussoren
From: Jack J. <Jac...@or...> - 2002-11-22 23:10:40
|
I just had a quick look at F-Script (www.fscript.org). It's a smalltalk lookalike that includes access to all of Cocoa, and it comes with a class browser and such niceties. It comes with source, so there might be some ideas about solutions to problems we have(or have had in the past:-). Although: it may be that you can send messages from fscript to ObjC but not the other way. I haven't looked long enough to be sore. -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |
From: Peter M. <zig...@po...> - 2002-11-25 10:55:02
|
On Saturday, November 23, 2002, at 10:10 AM, Jack Jansen wrote: > I just had a quick look at F-Script (www.fscript.org). It's a > smalltalk lookalike that includes access to all of Cocoa, and it comes > with a class browser and such niceties. Yep. I haven't looked at it since Jaguar came out. There is an F-Script add-on called F-Script Anywhere that lets you load an F-Script interpreter into any running Cocoa application. This is useful for exploring a third party app to see what classes it is using. Anyway, that's kind of OT. > It comes with source, so there might be some ideas about solutions to > problems we have(or have had in the past:-). Although: it may be that > you can send messages from fscript to ObjC but not the other way. I > haven't looked long enough to be sore. It *does* work the other way but AFAIK you can't really create a new class in F-Script or subclass a Cocoa class. It has a mechanism called a block which lets you wrap up a bit of F-Script code in an object. This object (IIRC) responses to the value: selector. For example, you can create a block and set it as the target of an NSButton and set the action to the selector #value. This works but it is nowhere near as elegant or as powerful as what PyObjC can currently do. It may still be interesting to look at because there is a lot of common ground and, as Jack mentioned, it is open source. On another note, has anyone here looked at CamelBones? I'm not really a Perl person but has anyone looked at how it does the Perl-ObjC bridge? Could be interesting. Peter |
From: Ronald O. <ous...@ci...> - 2002-11-25 11:25:52
|
On Monday, Nov 25, 2002, at 11:54 Europe/Amsterdam, Peter Montagner wrote: > > On Saturday, November 23, 2002, at 10:10 AM, Jack Jansen wrote: > >> I just had a quick look at F-Script (www.fscript.org). It's a >> smalltalk lookalike that includes access to all of Cocoa, and it >> comes with a class browser and such niceties. > > Yep. I haven't looked at it since Jaguar came out. There is an > F-Script add-on called F-Script Anywhere that lets you load an > F-Script interpreter into any running Cocoa application. This is > useful for exploring a third party app to see what classes it is > using. Anyway, that's kind of OT. That might be usefull for PyObjC as well. I have something like this on my private wishlist: I'd like to be able to write (system) prefpanes in Python. > > >> It comes with source, so there might be some ideas about solutions to >> problems we have(or have had in the past:-). Although: it may be that >> you can send messages from fscript to ObjC but not the other way. I >> haven't looked long enough to be sore. > [... interesting description of f-script removed) Ronald |
From: Peter M. <zig...@po...> - 2002-11-25 12:03:36
|
On Monday, November 25, 2002, at 10:24 PM, Ronald Oussoren wrote: > > On Monday, Nov 25, 2002, at 11:54 Europe/Amsterdam, Peter Montagner > wrote: > >> >> On Saturday, November 23, 2002, at 10:10 AM, Jack Jansen wrote: >> >>> I just had a quick look at F-Script (www.fscript.org). It's a >>> smalltalk lookalike that includes access to all of Cocoa, and it >>> comes with a class browser and such niceties. >> >> Yep. I haven't looked at it since Jaguar came out. There is an >> F-Script add-on called F-Script Anywhere that lets you load an >> F-Script interpreter into any running Cocoa application. This is >> useful for exploring a third party app to see what classes it is >> using. Anyway, that's kind of OT. > > That might be usefull for PyObjC as well. I have something like this > on my private wishlist: I'd like to be able to write (system) > prefpanes in Python. Interesting. Well, if you want to take a crack at it, F-Script Anywhere uses libPatch to force itself into a running application. libPatch seems to be a very hard to get bit of code. http://www.phasic.com/~arwyn/libPatch-1.2.tgz Note: This may be old and may not work on Jaguar. I haven't looked at it closely. Don't even know if the link still works. There is also Unsanity's Application Enhancer: http://www.unsanity.com/haxies/ape/ Peter |
From: Ronald O. <ous...@ci...> - 2002-11-25 13:03:41
|
On Monday, Nov 25, 2002, at 13:01 Europe/Amsterdam, Peter Montagner wrote: > > On Monday, November 25, 2002, at 10:24 PM, Ronald Oussoren wrote: >> >> That might be usefull for PyObjC as well. I have something like this >> on my private wishlist: I'd like to be able to write (system) >> prefpanes in Python. > > Interesting. Well, if you want to take a crack at it, F-Script > Anywhere uses libPatch to force itself into a running application. > libPatch seems to be a very hard to get bit of code. > http://www.phasic.com/~arwyn/libPatch-1.2.tgz Some time in the future I will probably try to write whatever is needed to get prefpanes to work. That is probably simular to what is needed to write plugins for programs that use Objective-C classes as plugins (e.g. which is basicly what the system preferences application is doing). I probably won't work on forcing this onto unwilling applications. Finding a way to automaticly execute a function when 'our' shared library is loaded will probably the most problematic part of this. That is: Whenever the 'pyobjcextension' shared libary is loaded 'initPyObjCExtension' in that library should run. I haven't looked into this yet and this may well be either trivial or impossible. Ronald |
From: Peter M. <zig...@po...> - 2002-11-25 13:29:22
|
On Tuesday, November 26, 2002, at 12:02 AM, Ronald Oussoren wrote: > On Monday, Nov 25, 2002, at 13:01 Europe/Amsterdam, Peter Montagner > wrote: > >> On Monday, November 25, 2002, at 10:24 PM, Ronald Oussoren wrote: >> >>> That might be usefull for PyObjC as well. I have something like this >>> on my private wishlist: I'd like to be able to write (system) >>> prefpanes in Python. >> >> Interesting. Well, if you want to take a crack at it, F-Script >> Anywhere uses libPatch to force itself into a running application. >> libPatch seems to be a very hard to get bit of code. >> http://www.phasic.com/~arwyn/libPatch-1.2.tgz > > Some time in the future I will probably try to write whatever is > needed to get prefpanes to work. That is probably simular to what is > needed to write plugins for programs that use Objective-C classes as > plugins (e.g. which is basicly what the system preferences application > is doing). I probably won't work on forcing this onto unwilling > applications. > > Finding a way to automaticly execute a function when 'our' shared > library is loaded will probably the most problematic part of this. > That is: Whenever the 'pyobjcextension' shared libary is loaded > 'initPyObjCExtension' in that library should run. I haven't looked > into this yet and this may well be either trivial or impossible. Well, you could override +alloc on the Principal Class and when the plugin is loaded you could do what ever is needed to do the python stuff. I'm not sure how you are going to get a python interpreter into a running third party app (ie, SysPrefs). One solution would be to use Distributed Objects. The bundle loaded could launch a python interpreter and start listening for a DO connection. The python interpreter would then connect to the loaded bundle. When the connection is made, the loaded module would return the DO proxy (from the +alloc method). Returning from +alloc before a connection is made would be pretty pointless. The Principal Class would never really exist as an instance because a remote object would take its place. I haven't exactly thought this through but it seems possible. It is a bit of a kludge but I don't see any other way to do it, especially with Apple's non-embeddable python. It would be fun if someone killed the python interpreter while System Preferences was still open! Also, this method relies on DO working in PyObjC which it currently doesn't seem to. Peter |
From: Peter M. <zig...@po...> - 2002-11-26 03:01:39
|
On Tuesday, November 26, 2002, at 12:28 AM, Peter Montagner wrote: > > On Tuesday, November 26, 2002, at 12:02 AM, Ronald Oussoren wrote: > >> On Monday, Nov 25, 2002, at 13:01 Europe/Amsterdam, Peter Montagner >> wrote: >> >>> On Monday, November 25, 2002, at 10:24 PM, Ronald Oussoren wrote: >>> >>>> That might be usefull for PyObjC as well. I have something like >>>> this on my private wishlist: I'd like to be able to write (system) >>>> prefpanes in Python. >>> >>> Interesting. Well, if you want to take a crack at it, F-Script >>> Anywhere uses libPatch to force itself into a running application. >>> libPatch seems to be a very hard to get bit of code. >>> http://www.phasic.com/~arwyn/libPatch-1.2.tgz >> >> Some time in the future I will probably try to write whatever is >> needed to get prefpanes to work. That is probably simular to what is >> needed to write plugins for programs that use Objective-C classes as >> plugins (e.g. which is basicly what the system preferences >> application is doing). I probably won't work on forcing this onto >> unwilling applications. >> >> Finding a way to automaticly execute a function when 'our' shared >> library is loaded will probably the most problematic part of this. >> That is: Whenever the 'pyobjcextension' shared libary is loaded >> 'initPyObjCExtension' in that library should run. I haven't looked >> into this yet and this may well be either trivial or impossible. > > Well, you could override +alloc on the Principal Class and when the > plugin is loaded you could do what ever is needed to do the python > stuff. I'm not sure how you are going to get a python interpreter into > a running third party app (ie, SysPrefs). One solution would be to use > Distributed Objects. The bundle loaded could launch a python > interpreter and start listening for a DO connection. The python > interpreter would then connect to the loaded bundle. When the > connection is made, the loaded module would return the DO proxy (from > the +alloc method). Returning from +alloc before a connection is made > would be pretty pointless. The Principal Class would never really > exist as an instance because a remote object would take its place. > > I haven't exactly thought this through but it seems possible. It is a > bit of a kludge but I don't see any other way to do it, especially > with Apple's non-embeddable python. It would be fun if someone killed > the python interpreter while System Preferences was still open! Also, > this method relies on DO working in PyObjC which it currently doesn't > seem to. OK, I can answer my own question. This is basically impossible. You can't pass an NSView across an NSConnection and expect it to work in the new application. The reason is very obvious: It will try to do its GUI stuff locally instead of on the other side of the connection. This is entirely reasonable. Ignore the above message. Peter |
From: <bb...@ma...> - 2002-11-25 13:37:54
|
On Monday, November 25, 2002, at 08:02 AM, Ronald Oussoren wrote: > Some time in the future I will probably try to write whatever is > needed to get prefpanes to work. That is probably simular to what is > needed to write plugins for programs that use Objective-C classes as > plugins (e.g. which is basicly what the system preferences application > is doing). I probably won't work on forcing this onto unwilling > applications. I.e. implement an application that implements enough of the various classes in Python that are required to make a loaded preferences panel work in some place other than System Preferences? Or create a plugin type architecture for new apps? In the first case, Outside of it being an excellent test of the bridge, is the goal to provide the user with standalone prefs apps? Neat idea. Key challenge: The classes that are subsequently subclassed by the loaded module must have instance variables that look/feel/act exactly like the iVars in the original parent class.... In the second case, there isn't really anything to do -- it already "just works" (and is analogous to what a couple of my apps are doing when they mixin ObjC code as frameworks within the app wrapper). You will need to create ObjC headers that declare the classes that are defined in Python that will be subclassed in the bundle (mostly for the iVars, but also just to compile a subclass). To compile the bundle will likely require an '-undefined suppress' option.... > Finding a way to automaticly execute a function when 'our' shared > library is loaded will probably the most problematic part of this. > That is: Whenever the 'pyobjcextension' shared libary is loaded > 'initPyObjCExtension' in that library should run. I haven't looked > into this yet and this may well be either trivial or impossible. Assuming that the target application is ObjC, simply creating a +(void)load in a class/category within the dylib should be enough to cause a hunk of code to be executing that can call -initPyObjCExtension. There is also a similar mechanism in the pure C++ world. In any case, embedding Python as an extension to existing applications would require a build of Python other than Apple's. Not really a big deal -- completely different situation than creating a standalone python App (though it would be nice to have an app extension that doesn't require a multi-MB download because it includes a python distribution). b.bum |
From: Ronald O. <ous...@ci...> - 2002-11-25 14:25:35
|
On Monday, Nov 25, 2002, at 14:37 Europe/Amsterdam, bb...@ma... wrote: > On Monday, November 25, 2002, at 08:02 AM, Ronald Oussoren wrote: >> Some time in the future I will probably try to write whatever is >> needed to get prefpanes to work. That is probably simular to what is >> needed to write plugins for programs that use Objective-C classes as >> plugins (e.g. which is basicly what the system preferences >> application is doing). I probably won't work on forcing this onto >> unwilling applications. > > I.e. implement an application that implements enough of the various > classes in Python that are required to make a loaded preferences panel > work in some place other than System Preferences? Or create a plugin > type architecture for new apps? The former, mostly because it would be a neat trick but adding a System Preference is IMHO better than adding lots of small applications when you want to write 'customize-some-unix-tool' applications. > > Key challenge: The classes that are subsequently subclassed by the > loaded module must have instance variables that look/feel/act exactly > like the iVars in the original parent class.... That should be no problem, PyObjC can already to that. For me the key challenge is finding a way to initialize an embedded python interpreter and run a python script when the plugin bundle is loaded (and for bonus points: Initialize exactly 1 interpreter, even when loading more than 1 python-based plugin) > >> Finding a way to automaticly execute a function when 'our' shared >> library is loaded will probably the most problematic part of this. >> That is: Whenever the 'pyobjcextension' shared libary is loaded >> 'initPyObjCExtension' in that library should run. I haven't looked >> into this yet and this may well be either trivial or impossible. > > Assuming that the target application is ObjC, simply creating a > +(void)load in a class/category within the dylib should be enough to > cause a hunk of code to be executing that can call > -initPyObjCExtension. There is also a similar mechanism in the pure > C++ world. I hadn't though of using a (dummy) class to do this. Thanks for the tip. Ronald |
From: Peter M. <zig...@po...> - 2002-11-26 01:57:04
|
On Tuesday, November 26, 2002, at 01:24 AM, Ronald Oussoren wrote: > On Monday, Nov 25, 2002, at 14:37 Europe/Amsterdam, bb...@ma... wrote: > >> Key challenge: The classes that are subsequently subclassed by the >> loaded module must have instance variables that look/feel/act exactly >> like the iVars in the original parent class.... > > That should be no problem, PyObjC can already to that. For me the key > challenge is finding a way to initialize an embedded python > interpreter and run a python script when the plugin bundle is loaded > (and for bonus points: Initialize exactly 1 interpreter, even when > loading more than 1 python-based plugin) Will this work with Apple's python? Or are you planning on shipping a full python distro with the plugin? Otherwise it'd be a nice hack but it wouldn't be distributable. >>> Finding a way to automaticly execute a function when 'our' shared >>> library is loaded will probably the most problematic part of this. >>> That is: Whenever the 'pyobjcextension' shared libary is loaded >>> 'initPyObjCExtension' in that library should run. I haven't looked >>> into this yet and this may well be either trivial or impossible. >> >> Assuming that the target application is ObjC, simply creating a >> +(void)load in a class/category within the dylib should be enough to >> cause a hunk of code to be executing that can call >> -initPyObjCExtension. There is also a similar mechanism in the pure >> C++ world. > > I hadn't though of using a (dummy) class to do this. Thanks for the > tip. There are problems with +(void)load. Namely, you can't guarantee the order of +(void)load methods, so you can't rely on any other classes. Well, certainly not those in the same bundle. This doesn't sound like a problem in this case but it is something to be wary of. Peter |
From: <bb...@ma...> - 2002-11-26 03:16:22
|
On Monday, November 25, 2002, at 08:56 PM, Peter Montagner wrote: > On Tuesday, November 26, 2002, at 01:24 AM, Ronald Oussoren wrote: >> On Monday, Nov 25, 2002, at 14:37 Europe/Amsterdam, bb...@ma... >> wrote: >>> Key challenge: The classes that are subsequently subclassed by the >>> loaded module must have instance variables that look/feel/act >>> exactly like the iVars in the original parent class.... >> That should be no problem, PyObjC can already to that. For me the key >> challenge is finding a way to initialize an embedded python >> interpreter and run a python script when the plugin bundle is loaded >> (and for bonus points: Initialize exactly 1 interpreter, even when >> loading more than 1 python-based plugin) > Will this work with Apple's python? Or are you planning on shipping a > full python distro with the plugin? Otherwise it'd be a nice hack but > it wouldn't be distributable. It would only work with a distribution of python that has an embeddable library.... i.e. not the Apple build. >>>> Finding a way to automaticly execute a function when 'our' shared >>>> library is loaded will probably the most problematic part of this. >>>> That is: Whenever the 'pyobjcextension' shared libary is loaded >>>> 'initPyObjCExtension' in that library should run. I haven't looked >>>> into this yet and this may well be either trivial or impossible. >>> Assuming that the target application is ObjC, simply creating a >>> +(void)load in a class/category within the dylib should be enough to >>> cause a hunk of code to be executing that can call >>> -initPyObjCExtension. There is also a similar mechanism in the >>> pure C++ world. >> I hadn't though of using a (dummy) class to do this. Thanks for the >> tip. > There are problems with +(void)load. Namely, you can't guarantee the > order of +(void)load methods, so you can't rely on any other classes. > Well, certainly not those in the same bundle. This doesn't sound like > a problem in this case but it is something to be wary of. Not really a problem; in any given hunk o' dynamically loadable code, provide a single +load or ensure that your initialization code is only executed once. Alternatively, the code invoked as a part of the static initializer (which +load really is) should *only* initialize the class in question, never touching anything else. If the initialization code *must* be executed at a point in time when the rest of the framework has been loaded/initialized, then one can typically use something like NSNotificationCenter to cause a notif to be sent (exact mechanism varies according to environment). [In all my experience as a developer, I find it surprising the number of times folks have been tripped up by the undefined order of execution inflicted upon really early initialization code... The NS 3.3 and OS 4.2 AppKit's both suffered from really nasty bugs if you touched classes in the wrong order, thereby causing +initialize to b executed in an "unexpected" order, very bad things would happen. I'm surprised at the number of times I have tripped over this and I should *really* know better by now! In any case, unless explicitly defined... don't assume anything prior to main() or at dyna-load time.] b.bum |
From: Ronald O. <ous...@ci...> - 2002-11-26 06:56:57
|
On Tuesday, Nov 26, 2002, at 02:56 Europe/Amsterdam, Peter Montagner wrote: > > On Tuesday, November 26, 2002, at 01:24 AM, Ronald Oussoren wrote: > >> On Monday, Nov 25, 2002, at 14:37 Europe/Amsterdam, bb...@ma... >> wrote: >> >>> Key challenge: The classes that are subsequently subclassed by the >>> loaded module must have instance variables that look/feel/act >>> exactly like the iVars in the original parent class.... >> >> That should be no problem, PyObjC can already to that. For me the key >> challenge is finding a way to initialize an embedded python >> interpreter and run a python script when the plugin bundle is loaded >> (and for bonus points: Initialize exactly 1 interpreter, even when >> loading more than 1 python-based plugin) > > Will this work with Apple's python? Or are you planning on shipping a > full python distro with the plugin? Otherwise it'd be a nice hack but > it wouldn't be distributable. It won't work with Apple's python. You'd therefore be required to either ship a partial python distribution with the plugin or somehow build a Python shared library that is compatible with Apple's python. The latter would be kind of a hack, but probably doable. Ronald |
From: Jack J. <Jac...@cw...> - 2002-11-25 14:39:20
|
On Monday, Nov 25, 2002, at 14:37 Europe/Amsterdam, bb...@ma... wrote: > In any case, embedding Python as an extension to existing applications > would require a build of Python other than Apple's. Bill, this sort of thing is exactly why I still moderately favor a framework Python over a static python. With framework Python, a plugin would be a couple of lines of C code (call Py_Initialize(), call one python function to set the rest up), and it would be linked against Python.framework. The other options (static Python, python-with-a-dylib) are much more cumbersome to get to work. -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |
From: <bb...@ma...> - 2002-11-25 13:41:53
|
On Monday, November 25, 2002, at 07:01 AM, Peter Montagner wrote: > There is also Unsanity's Application Enhancer: > http://www.unsanity.com/haxies/ape/ As much as some of Unsanity's Haxies are very cool, I would avoid using this as a mechanism for embedding the python interpreter. APE has been a constant source-- directly and indirectly-- of system instability, app crashes, and other problems. Mostly, this has been the result of module developers exercising various APIs incorrectly and not the fault of APE directly. The end result is that APE is synonymous with the Extensions mechanism found in Mac OS 9 and prior. They both provide a way to modify the system in just about anyway desired at the cost of stability and consistency of operation. APE is a hell of a technical achievement, but has caused a boatload of problems within the user community. b.bum |
From: <bb...@ma...> - 2002-11-25 15:49:40
|
On Monday, November 25, 2002, at 05:54 AM, Peter Montagner wrote: > On another note, has anyone here looked at CamelBones? I'm not really > a Perl person but has anyone looked at how it does the Perl-ObjC > bridge? Could be interesting. The author of CamelBones and I exchanged a few messages a bit ago. CamelBones doesn't currently do subclassing. It hopefully will in the next version, but that won't be due out for a while. The author sends his thanks-- he has been using the PyObjC module's source to solve some of the issues he has faces. According to... man PerlObjCBridge ... the PerlObjC bridge is bidirectional but does not yet support subclassing(?) ... Objective-C objects from Perl programs, allowing Cocoa objects in Apple Computer's Mac OS X to be directly manip- ulated from Perl. In addition, Perl objects can be mes- saged from Objective-C, making it possible for Perl objects to function as Cocoa delegates and as targets of notifications and other Cocoa call-back messages. Perl programs can take advantage of Cocoa's Distributed Objects mechanism to support messaging between Perl objects and Objective-C objects (or other Perl objects) in different address spaces, possibly on different machines. It also uses the same name mangling as pyobjc. Clearly, the author had some challenges in wrapping the NSProxy class [perfectly understandable] because the man page has a huge section on using the PerlObjC bridge with DO -- something that should "just work" once the bridge is working correctly. This is interesting... When an Objective-C method declares a signed char or signed short argument, if a negative value is passed the actual value received by the method is coerced to an unsigned char or unsigned short, respectively. For exam- ple, if a method declares a signed char argument and -100 is passed the actual value received by the method will be 156. This is due to bug 2545453 in the Foundation frame- work. ... either the bug is fixed or our implementation doesn't suffer from it: >>> from Foundation import NSNumber >>> x = NSNumber.numberWithShort_(-100) >>> x -100 >>> x.intValue() + 2 -98 The PerlObjC bridge does not support all of the various #defines, typedef enums, and C Functions found in the Foundation or AppKit. The author indicates that support is left to the developer. |