Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

D6 and Spray Web Services Toolkit

5 views
Skip to first unread message

Pax

unread,
Apr 23, 2006, 7:40:38 AM4/23/06
to
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

John

unread,
Apr 23, 2006, 5:14:27 PM4/23/06
to
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

Steve Alan Waring

unread,
Apr 23, 2006, 10:49:59 PM4/23/06
to
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

John

unread,
Apr 24, 2006, 2:07:08 AM4/24/06
to
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

Chris Uppal

unread,
Apr 24, 2006, 5:08:36 AM4/24/06
to
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


Steve Alan Waring

unread,
Apr 25, 2006, 12:43:28 AM4/25/06
to
> > 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

Chris Uppal

unread,
Apr 25, 2006, 4:41:24 AM4/25/06
to
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


Pax

unread,
Apr 25, 2006, 9:46:56 AM4/25/06
to
Excellent!

Thanks for the information guys. Time to setup a D6 image and start
moving pacs from D5 to D6.

Regards,

Pax

John

unread,
Apr 25, 2006, 10:03:43 PM4/25/06
to
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

Chris Uppal

unread,
Apr 26, 2006, 8:25:12 AM4/26/06
to
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


Steve Alan Waring

unread,
Apr 26, 2006, 6:25:26 PM4/26/06
to
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

John

unread,
Apr 27, 2006, 2:56:24 AM4/27/06
to
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

Chris Uppal

unread,
Apr 27, 2006, 8:18:16 AM4/27/06
to
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.)

Chris Uppal

unread,
Apr 27, 2006, 8:18:38 AM4/27/06
to
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

Steve Alan Waring

unread,
Apr 30, 2006, 7:53:41 PM4/30/06
to
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

Chris Uppal

unread,
May 2, 2006, 11:42:48 AM5/2/06
to
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

Steve Alan Waring

unread,
May 2, 2006, 9:25:06 PM5/2/06
to
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

0 new messages