Hi,
just wondering if D6 is compatible with the Spray web services toolkit from Steve Waring... I haven't attempted to load up packages (yet) but plan to do so in the near future. Anyone able to load the Spray D5 pacs into D6? TIA, Pax |
PAX,
I was able to use it in D6 (Thanks Steve!). If I recall correctly, the only thing that had to be fixed was a few places in the code where there is an assignment to a block parameter which is not allowed in D6. If I knew how to do a comparison to the original package I would be able to tell you where the changes are. Steve could probably figure it out in 30 seconds flat though... Admittedly I've mostly been using Splash to access the NWS WS however I did use Spray initially and it worked as well. Also, most examples don't work but this is not due to the code. Alot of the web services have changed or no longer exist out there. Take care, John |
Hi John and Pax,
John: thanks for the info. I have not got around to installing that code in D6 as yet ... it is towards the bottom of the todo list. Someone emailed me about a month ago asking if it was OK if they worked on a cleaned up D6 port. I have not heard back, so I am not sure what progress has been made. I would be more than happy to host or link to any D6 version someone else does. > a few places in the code where there is > an assignment to a block parameter Yes, I had a bad habit of writing code like "#(1 2 3) inject: 0 into: [ :sum :each | sum := sum + each]." The best way to find and fix these errors is after you have installed the packages, go to the SmalltalkSystemShell and click on the "Browse/Method Category/Compilation Failures". Steve |
I have a bad habit of when I load a package and get it working to just
save the package and forget about it. I'll have to try to discipline myself to at least make note of the changes somewhere. Might I ask why it is that the "asssignment to block parameter" is a bad thing? Just wondering. Is it agaist spec or does it have some deeper ramifications. Take care, John |
John,
> I have a bad habit of when I load a package and get it working to just > save the package and forget about it. > I'll have to try to discipline myself to at least make note of the > changes somewhere. I add: #CUmodified. or: #CUadded. to each method I change or add to system or third-party packages (and, if I remember in time, save a copy of the original method under a new name). Since you can browse for references to either symbol, it makes finding changes I've made rather simple. I use the same technique for "todo" notes too, with #CUtodo. I think it's generally considered to be good practise, if you publish code which extends system classes, to mark your additions in some similar way. (In point of fact, I go further and define virtual method categories to identify such methods, but that might be overkill for your purposes ;-) > Might I ask why it is that the "asssignment to block parameter" is a bad > thing? Just wondering. Is it agaist spec or does it have some deeper > ramifications. I think it was always /intended/ to be illegal (not allowed in Smalltalk anymore than assigning to method parameters is). However the implementation, pre-D6, did allow it anyway. Indeed it was sometimes necessary to assign to block parameters in order not to capture long lived references to objects which would otherwise be eligible for GC. -- chris |
> > I'll have to try to discipline myself to at least make note of the
> > changes somewhere. Versioning the packages with STS would also allow you to find any changes. > I add: #CUmodified. or: #CUadded. A good idea, but I don't tend to do this for my own (non-public) packages anymore as I always move the changed methods to one of my own packages. Looking through loose methods, combined with STS's method "Browse Editions" is a good way for me to track what I have changed, and see what it was that I changed. > made rather simple. I use the same technique for "todo" notes too, with > #CUtodo .... and define virtual method categories to I make heavy use of my own todo symbol and having a virtual method category for it is very handy! Thanks, Steve |
Steve,
[me:] > > made rather simple. I use the same technique for "todo" notes too, with > > #CUtodo .... and define virtual method categories to > > I make heavy use of my own todo symbol and having a virtual method > category for it is very handy! Ah, so there /is/ someone besides myself who uses them! Nobody else ever seems to mention that rather wonderful feature... Another simple one that I find very useful is a 'loose methods' category. -- chris |
Excellent!
Thanks for the information guys. Time to setup a D6 image and start moving pacs from D5 to D6. Regards, Pax |
In reply to this post by Chris Uppal-3
Chris Uppal wrote:
> John, > >> I have a bad habit of when I load a package and get it working to just >> save the package and forget about it. >> I'll have to try to discipline myself to at least make note of the >> changes somewhere. > > I add: > #CUmodified. > or: > #CUadded. > to each method I change or add to system or third-party packages (and, if I > remember in time, save a copy of the original method under a new name). Since > you can browse for references to either symbol, it makes finding changes I've > made rather simple. I use the same technique for "todo" notes too, with > #CUtodo. > > I think it's generally considered to be good practise, if you publish code > which extends system classes, to mark your additions in some similar way. > > (In point of fact, I go further and define virtual method categories to > identify such methods, but that might be overkill for your purposes ;-) > Thanks. That makes sense. Kinda like // TODO: in Jav...err...never mind ;) I realize now I've seen these before in package from others that I've loaded. The grey cells (what's left of them) just didn't make the connection. <snip> > Indeed it was sometimes necessary to assign to > block parameters in order not to capture long lived references to objects which > would otherwise be eligible for GC. > Will you expand on this further? Thanks, John |
John,
[me:] > > Indeed it was sometimes necessary to assign to > > block parameters in order not to capture long lived references to > > objects which would otherwise be eligible for GC. > > > > Will you expand on this further? I can try. If you have a D5 installation, try the following in a workspace. Start with: Base64Codec allInstances size for me that answers 0. There's nothing special about Base64Codec, I just wanted a class which happens to have no instances. Now evaluate: block := [:x | Transcript display: x; cr]. to create a long-lived block. Use that block: block value: Base64Codec new. and the value of x will appear on the Transcript. However, the implementation of Blocks is such that the last object passed to the block is saved internally: Base64Codec allInstances size. now answers 1. You can inspect the block to see this, the block holds a ref to the Codec somewhere in it's "outer". If we now evaluate block value: 'Hello'. then a new object is trapped, and the old Codec is allowed to die gracefully. If instead you use a block which nils-out its parameter. block := [:x | Transcript display: x; cr. x := nil]. Then the effect does not occur. If you try this with D6 then the object is never trapped, and the D6 compiler won't let you use the second form of the block. BTW, the same thing applies (in D5, not in D6) to local variables in blocks. Actually, this example is a little misleading since blocks in workspaces are not implemented in quite the same way as blocks in method bodies, but you can still get the same trapping effect. It's not usually something you have to worry about, even in D5, since most blocks don't live long. But if you are creating a long-lived block, /and/ if that block is likely to have lifetime-sensitive objects passed to it (such ones that keep a large object network alive), then the set-to-nil technique is available. -- chris |
In reply to this post by Chris Uppal-3
Hi Chris,
> Another simple one that I find very useful is a 'loose methods' category. Thanks! ... that will be handy. I implemented it by evaluating the expression below. Is it what you use? PluggableVirtualMethodCategory addPseud: (PluggableVirtualMethodCategory newNamed: PluggableVirtualMethodCategory pseudPrefix , 'loose methods' withFilter: [:cm | cm isLoose]) Any other gems? Steve |
In reply to this post by Chris Uppal-3
Chris,
Thanks for the great explaination! Just out of curiosity, was there a reason for the reference to hang around? I'm just wondering as I tried the same code in Squeak (using an arbitrary RuleDate class instead) and it seens to do the same thing. Though in Squeak, even after the "block value: 'Hello'." the reference seens to still be there. However I'm not sure if the reference is hard or if the GC is just being lazy about cleaning it up. Not sure how to find references in Squeak. Thanks again, John |
In reply to this post by Steve Alan Waring
Steve,
> I implemented it by evaluating the expression below. Is it what you > use? Pretty similar. Actually, I use a custom subclass of VirtualMethodCategory. I've had this stuff for a long time and PluggableVirtualMethodCategory only appeared in D6 (in fact I hadn't realised it existed; it's a very good idea -- thanks for the heads-up!). > Any other gems? I use quite a lot of custom categories, I'm not sure which would interest you ;-) The most useful to me ("not referred to", "with undefined sends", and "overridden"[*]) depend on an in-image cross-reference database I maintain. It takes up about a megabyte or so of space (and can slow down some bulk operations too) so it's rather a heavyweight feature. If anyone's interested (either in using them or just seeing how they work) then it's on my website (package 'CU Browser Database' under "Experiments"). Only tested with D5 so far. One much simpler one which I find quite handy, is a 'contains halt' category. I presume that would be trivial to implement as a pluggable category. cat := PluggableVirtualMethodCategory newNamed: (PluggableVirtualMethodCategory pseudPrefix , 'has #halt') withFilter: [:it | it messages includes: #halt]. MethodCategory addPseud:cat. appears to work for me. My actual implementation is different (I have more than one #halt-like method in my image, for a start), but the general idea's the same. -- chris ([*] Actually, the 'overriden' category isn't as important as it used to be, since I now use a trivial CHB subclass which displays is-override and is-overriden icons for methods.) |
In reply to this post by John Rubier
John,
> Just out of curiosity, was there a reason for the reference to hang > around? I'm very hazy on the details, but I presume it's an artefact of the way that blocks were traditionally implemented as not-quite-full-closures. Search the archives for Blair's posts mentioning full closures for more and better information. > I'm just wondering as I tried the same code in Squeak (using an > arbitrary RuleDate class instead) and it seens to do the same thing. I wouldn't be surprised. As far as I know, Squeak and Dolphin (pre D6) use similar implementations of blocks. -- chris |
In reply to this post by Chris Uppal-3
Hi Chris,
You have given me some great ideas ... thanks! > in-image cross-reference database Interesting! Over the past couple of years I have tried a couple of ways to display this kind of information in the browsers, but I had not considered maintaining my own tables of it. Currently I replace the tooltip in MethodBrowser with a tooltip that shows the number of definitions/references and references in the TestCase hierarchy of the method's selector. Even with a tooltip, it can cause 2-3 second pauses when hovering over methods like #do:. I had this better optimized in D5, but had to rework it for D6. > is a 'contains halt' category I use IDE extensions in the browser's workspaces to insert things like my todo symbol, comment templates etc. I also have it setup to insert "self halt. #deprecated". A bit of a hack, but it does mean that I won't forget about that halt. A category for this would be a nicer approach. Steve |
Steve,
> > in-image cross-reference database > > Interesting! Over the past couple of years I have tried a couple of > ways to display this kind of information in the browsers, but I had not > considered maintaining my own tables of it. I was forced into it because I wanted an inspector for methods which would allow me to "drill down" into the implementation, structured as a normal tree. I.e. the node representing a method has children representing each method it calls (or rather, representing each selector it uses, and their children represent implantations of the selector). The performance of that was terrible, and the performance of the opposite tree (where children represent references /to/ a method) was even worse. It's turned out to be useful for other things since, but that was the initial spur. > I also have it setup to insert > "self halt. #deprecated". A bit of a hack, but it does mean that I > won't forget about that halt. A category for this would be a nicer > approach. But the category wouldn't give you such a strong visible indication. I like the idea of "borrowing" #deprecated just for it's effect on the visible status. Very cunning ! I keep wondering if it'd be possible for MethodCategories to affect the visible representation of methods directly, but haven't come up with anything worth a damn yet. The big problems are how do applicable categories negotiate between themselves who is most "important", and how to combine the effects of categories of comparable importance. -- chris |
Hi Chris,
> the node representing a method has children representing > each method it calls (or rather, representing each selector > it uses, and their children represent implantations of the > selector). That would provide a very interesting way to understand something. > I keep wondering if it'd be possible for MethodCategories > to affect the visible representation of methods directly I agree, I find myself regularly writing new tools, which on reflection, really only highlight methods already in a category (or possible virtual category). As you say, the two main issues are speed and what to display. I find myself using browsers in a couple of different modes. In each of those modes, I really want to see, or at least have highlighted, different things. It would be handy to have "method browser profiles" that could be switched between. The different modes of my use are not clear cut, but in general: When I am writing code I don't look at the public/private icon (I do look for errors and deprecated). At this stage I am not thinking whether a method is private or public. What I am interested in, is seeing if I have left any notes in a method, whether I need to add more tests for the method, whether the method is almost deleted, or whether it contains unimplemented sends. I use a couple of symbols for this; #mytodo, #moretests, #deprecated and also a couple of automated searches, like searching the TestCase hierarchy for references to the method. As far as testing goes, I guess people who are strictly test first don't need this, but I find myself "testing before during and after"! I like writing tests and having more tests, so any visible indication that draws my attention to lack of tests is good. A second mode is when I revisit recently written code. At this point I find the public/private icon useful as I go through all methods making them either private or public and putting them into proper categories. I also use Smalllint/Code Mentor ... especially to find methods with no references. In this mode, I am on the hunt for unnecessary or duplicated code. Personally I find the standard CHB most useful in this mode, as I tend to work my way through the code methodically (public/private, then categories, then Smalllint/Code Mentor ), and therefore don't need things bought to my immediate attention. A third mode is when trying to understand someone else's code, or my own from the past. In this case I ignore public/private, and really just want to see the number of definitions of the method and number of senders. Your "drill down" inspector sounds like a great way of doing what I normally do ... have reams of MethodExplorers open. I guess a fourth mode is when I am using 3rd party code. Here I do pay attention (a bit!) to the public/private icon. Whenever I have started working on something general to try and display all of this, the speed issue soon stops me, and I go back to a specialized tool (or a hack like using tooltips). Everyone has their own personal working styles so a general solution might not be possible. However, I am guessing that if the finding of references and definitions was much faster (and/or Virtual Category membership was cached somehow) and the MethodBrowser list had a dynamic pluggable system to switch what was highlighted based on categories ... icons/custom foreground/custom background/extra columns etc... it would remove the need for a lot of (my) specialized tools. Steve |
Free forum by Nabble | Edit this page |