30/09/2008

SUnit loves my instances

I have been trying to find out how to get rid of dead instances, because I seem to have collected a few. I first noticed this when I ran
Fspace allInstances size
and discovered 7 instances floating around. After some digging around, I was pointed to this entry on clearing up junk.
The entry introduced me to the idea of a PointerFinder, and that helped me identify where the instances were being referenced. However, that just lead to more confusion, because they seemed to be being held by the TestRunner, even though the window was closed.
A search of the squeak wiki brought up this article, which was interesting but didn't really solve the problem because I was already following its advice - at least I thought I was!
In the end, I started a new image, filed in my code, and changed the SUnit tests to include tearDown code as well as setUp code. This seems to have solved the problem. However, the documentation suggests that this isn't necessary, so perhaps I am doing something wrong.

Redirecting on session expiry

I am collecting up little code snippets, because I am bound to need them at some stage. I am tempted to start my own wiki, however, I think it would be better if there is somewhere I can store this on the smalltalk wiki - that way everyone can benefit from them.

This snippet controls the redirection of the user when their session expires.


You should overwrite the expire method on your session and redirect to the
desired url,
i.e:
MySession>> expire
super expire.
self redirectTo: 'http://seaside.st'

29/09/2008

Cincom's Seaside Tutorials

I have now had the chance to go through the tutorials, and they really are very good indeed. If you are interested in learning Seaside, this is a great place to start.

It seems as though James is in the middle of rerecording them, because the earlier ones are now using full-motion screen capture, whereas the later ones use Wink and are more 'static'. It was interesting to compare my reaction to the two styles. There is something about seeing the mouse move, in real time, and even seeing James type, that made the newly recorded ones much easier to follow. I think that cutting and pasting code into the text boxes is slightly jarring to ones learning process. Something for me to bear in mind when I make video demos.

Using Flex directly with Squeak

Thierry Thelliez has been doing some experiments, trying to integrate Flex with Seaside. I am interested in this too. He has now worked out how to pass data to a Flex component, embedded in a Seaside page.



I found the solution:

The FLEX HTTPService is encoding the request URL and that's not
playing well with Seaside style.

I found another way to do it with a FLEX URLLoader (code sample
below). So far so good. The FLEX widget can talk back to Seaside to a
dynamic URL, get back some XML data and draw whatever FLEX can offer
(datagrid, charts,...). Cool. (Next step for me: https support?)

Thanks again.
Thierry


On the MXML side:

private var myLoader:URLLoader = new URLLoader();
...
private function initApp():void {
...
var request:URLRequest = new URLRequest(aSeasideURL);
myLoader.addEventListener(Event.COMPLETE, onLoaded);
myLoader.load(request);

private function onLoaded(event:Event):void {
sourceXML = XML(myLoader.data);
}
...
private function onLoaded(event:Event):void {
sourceXML = XML(myLoader.data);
}
...

...


Glare UI, combining Flex and Smalltalk

Glare is a new, experimental, Flex remoting interface for Smalltalk - currently Visualworks. James Robertson made a brief video of the system at ESUG 2008, and you can see it here

I think this looks really interesting. Combining a Smalltalk back-end with the near universal availability of the Flash player, could provide some very exciting capabilities.

Squeak Map and Package Universe - the fog clears

At little while ago, I asked the question - on the beginners' list - about whether Package Universe had now replaced Squeak Map as the place to look for software. I didn't get a response, at the time, which surprised me because the experts on the list are usually excellent at answering newbies' queries. Anyway, today Ralph Johnson answered a similar question, and I can see now that the situation is more complex that I had imagined. I am including his explanation for future reference.

> What I observed is that it is very hard to find the latest (working)
> packages within the tools provided (SqueakMap, Universe browser).

What you call "Universe Browser", I will call "Package Universe", or
PU. SqueakMap is SM.

SM and PU are comparable. SM is a lot older, and is nice because,
until a year or so ago, it had a pointer to pretty much everything
being distributed. Montecello (MC) is different. It is aimed at
development, not at distribution. For a long time people used MC for
development and SM for distribution. SM basically would point to a MC
repository with the version of the software you wanted. I think it
was called "SqueakMap" because it would be a map to everything in
Squeak.

The problem with SM was that it had no dependency information. It
would not try to load dependent packages, or even warn you that you
needed to load them. You could read the comments of a package and see
if it advertised that it was built on another package, but it was a
pain to build a large system with SM.

PU was an attempt to solve this, but it went a long way beyond
dependency information. Lex Spoon wanted a package universe to have
only packages that were known to work together. Thus, there would be
many package universes. Each one would be self consistent, but
packges from one universe might not work with those from another. In
contrast, there was only one SM.

PU has been around for several years, but it didn't get popular until
it got used for 3.10. its popularity had the obvious-in-hindsight
consequence of people putting their packages in it but NOT putting
them in SM. So, SM no longer has the latest and greatest of
everything. Moreover, PU tends to have lots of versions of each
package, which is entirely against the original purpose of PU, since
not all versions will work with every other. In retrospect, PU should
have used SM to find the latest version of a package. That would have
forced people to keep putting info in SM.

I am surprised that nobody has yet upgraded SM to do everything that
PU does. That would be one solution to the problem. Keith Hodges has
built something called Sake/Packages that lets you write scripts that
does everything that PU does, but that can do this upon SM, and has
proposed using this and SM instead of PU. One of the reasons that PU
got off the ground was the Lex Spoon built a few universes, and then
he got some people to maintain them. Perhaps someone needs to write
the Sake packages to get things started.

If you are using a fairly standard image, you should try using the
universe for the package and then complain to package authors when the
version of the package in it is out of date. If you use SM, complain
to package authors when the latest version is not in SM. The tools
are there, but people have to use them. Certainly they can (and
should) be better. But until they are better, we ought to use them as
best we can.

-Ralph Johnson

28/09/2008

Sometimes I 'get it' and sometimes I don't!

Today I was trying to free up some objects, so that they would garbage collect. What I tried to do was:

Fspace allInstancesDo:
[:each |
each := nil.
Transcript show: (each value); cr.
Smalltalk garbageCollect]

What I expected it to do was to set each of the instances to nil. Of course, as Randal kindly pointed out, it would do no such thing. What it actually does is set the value of the :each temporary variable, to nil.

I was thinking about why I had made that mistake and the conclusion I came to was that I was becoming so used to sending messages to objects, that I thought I was somehow communicating with the instance, rather than with the temporary variable.

Ah well, onwards and upwards :-)

Keeping the development image up to date

I noticed, today, that I seem to be running an older version of Seaside (2.8). I am tempted to upgrade, but I am still not clear how the upgrade process works, and whether it would overwrite any changes I had made. I suspect not, but I am reluctant to try - just at the moment.

As luck would have it, there was an interesting comment in the beginners list today. I am noting this for future use.




In the dev image, from the world menu, select "open...", then "Universe
Browser (enhanced)" (or basic if you prefer). Make sure up update the list
from the network.
Now others will have to chime in, because you can also select "open..." and
then "Squeak Map Package Loader." Much of the same material is in both
places, but they ARE different somehow. I've never been quite clear how.

However, if you take a standard dev image, and execute (in a workspace):


(HTTPSocket httpGet: 'installer.pbwiki.com/f/LPF.st') readStream fileIn.
"Bootstrap"

and then

Installer install: 'Packages'.

You will get a pretty nice stable image with nearly every dev image release,
at which point you can also load packages by doing things like:

Installer sake addPackage: 'FreeTypePlus'; install.
Installer sake addPackage: 'MemoryUsage'; install.
MemoryUsage new openInWorld.

(These are just two packages I like to load). Anyway, the nice thing about
using the Universe Browser or the Sake package loader is that they take care
of the dependencies for you...

I have NO IDEA how it all works--I've just finally figured out how to use
it.

Also, with a fresh dev image, try, in the Universe Browser, updating the
list, then "select upgrades." Click the "all" button, and scroll through
the list. It will show you what packages it selected. You can than update
if you want...

27/09/2008

Web Velocity - very clever stuff

I had heard about Web Velocity, but knew nothing about it. So, I was very pleased to find this video. Well worth watching, if you are interested in using Smalltalk for web apps.

26/09/2008

Fantastic Seaside tutorial from Cincom

James Robertson of Cincom Systems was kind enough to point me to a Seaside tutorial that he built. You can access the tutorial here. Although the link to the tutorial is included as a comment to my previous entry, I wanted to bring it up to the top level in case anyone else is subscribed to these entries, and may miss it if they aren't subscribed to comments.


The interesting thing about James' comment is the timing. I have just started listening to his podcast, and, as a result of that, I downloaded the Cincom smalltalk this morning!


I have a couple of outstanding questions that I need to get answered, in due course:

  1. How do I get it to run on a Mac! Yes, I am sure it is an RTFM, it is just that I am a bit short of time, at the moment. The installer said something about setting a path variable, and, sadly, my knowledge of OS X is rather limited, so I have to check the instructions
  2. How much does it cost to use Cincom in an application? Normally, this isn't a difficult question to answer, but with the Cincom smalltalk, it seems as though everything is negotiable. I think the pricing is what put me off trying it in the past. However, now that I am becoming so interested in the language, I really should find someone who can explain the pricing model. My ideal is that it would be a bit like the Gemstone approach, i.e. free for small applications, then you pay for bigger ones. Who knows. However, when I find out, I will note it down here :-)

Seaside learning resources

This presentation by Lukas looks very useful. It provides an overview of Seaside, whilst ,at the same time, showing some code examples. I think I will come back to it in a little bit.

21/09/2008

Icons in OmniBrowser

So, it turns out that what I had been referring to as OmniBrowser isn't really OmniBrowser. OB is actually a framework for building browsers of all kinds. Various people have built new browsers and the version that ships in the latest Dev build is called OmniBrowser Enhancements (except when people just call it OmniBrowser!).

Anyway, there is some good documentation - including an explanation of what the icons mean, here

Turns out I was doing my unit testing all wrong!

I thought - based upon a couple of examples that I had read - that SUnit worked like this:

self should: [some condition].
self shouldnt: [some condition].


Turns out that the should and shouldnt messages are for checking whether errors have been raised or not. I need to learn a bit more about them. However, I now know that the right messages to send are assert: and deny:

You can read a bit more about using SUint, in a practical way, here

18/09/2008

Huh, Test Driven Development, not such a crazy idea after all ;-)

Well, my new image is beginning to pay off. I started writing my first semi-serious webapp today. And, given everything I have been reading, plus my experience from my first attempt, I decided to try to apply TDD. So far, so good. The system actually caught some bugs within the first few minutes of using it.

I haven't got to the stage of writing my tests before I write the code, but I think I will do that next, because I can really see the value.

What do all these little symbols mean?

Many of the methods in the SystemBrowser (my current default), have symbols next to them. As far as I can tell, they relate to whether a method is inherited, overridden, or something else! The rules seem to be:


  • Nothing: new method in this chain, i.e. the method could exist in other classes but not in this particular chain of inheritance.

  • Upward orange triangle: method is inherited and overridden in this class

  • Downward orange triangle: method is overridden in a subclass

  • Two orange triangles (up and down): overrides and is overridden in a subclass

  • Green up arrow: calls the same method in its super class

  • Blue triangle: Self should not implement or subClassResponsibility

  • Green plus: don't know, can't work this one out

  • Red flag: has a halt message in the code

  • Spanner: shows that the code needs to be returned to, i.e. under construction



Need to check this stuff on the beginners' list

Hmm, OmniBrowser!

The new Squeak Dev image is great. Much less clutter, nicer fonts, altogether a good experience. However, it has also introduced me to a whole new set of tools. The main one being, OmniBrowser. I am now feeling a bit lost.

OmniBrowser looks like the old system browser, but it behaves in different ways. Not hugely different, but enough to make me feel uncomfortable. So, today I went in search of documentation that would explain how to use the new tool. Not surprisingly, the documentation exists, and also unsurprisingly, it is scattered all over the place. The best I have been able to find so far is here. I am going to read through the PDF and see if it helps.

 Update: 

Looks like this article is a better place to start if you want to understand how to use the browser.

And another update. The article - although very helpful - seems to be slightly out of step with the current Squeak Dev image I downloaded. In particular, there is no ' SmartGroup' Browser in the World menu. However, the SmartGroup feature seems to be built into the main browser, and if you use that - and follow the instructions in the article - it seems to work in the same way.


I am beginning to think I should rewrite this whole post instead of adding updates!

Anyway, I have found some useful help text. It doesn't really explain how to use the browser, but it does tell me a bit about switching between browsers and what the various versions do. I think the SmartGroup browser must have been removed from this dev image. Also, it seems as though the SqueakSource package idea is gradually becoming an organising principle for Squeak - it is now being built into the tools more directly.

17/09/2008

Getting the development image - I should have done this from the start!

I was reading through Ramon Leon's blog and I came across a reference to the Squeak Developer image. I had read about this before, but obviously not followed it up. There again, perhaps I did and it just got lost in the sea of images I have downloaded over time!

Anyway, if you are starting to develop in Squeak, get the developer image - you know it makes sense!

14/09/2008

Subscribing to teh Squeaksource rss feed

I noticed, browsing around squeaksource today, that it has an RSS feed. Out of curiosity I subscribed, not expecting many changes. Boy, was I surprised. If the feed is correct, i.e. it isn't reporting old changes, then there is a real blizzard of activity. I haven't worked out whether any of it is useful yet, but it is interesting to see what people are working on.

Getting dangerously ambitious!

The other night I worked out how to rotate a matrix. Well, to be more precise, what I actually did was take an Array of OrderedCollections - that held the result of the CSV parsing - and collect up the columns, and write them into a new Array of OrderedCollections.

The code, which is a little messy because it is coming straight from my workspace, looks like this:

newArray1 := Array new: ((oldArray1 collect: [:each| each size]) max)
(1 to: newArray1 size)do: [:count| newArray1 at: count put: OrderedCollection new]
oldArray1 do: [:each| (1 to: each size) do: [:count|| oc2| oc2:= (newArray1 at:count) . oc2 add: (each at:count) ]]


Looking at the code now makes me realise the importance of giving my variables 'intention revealing' names. I must pay closer attention to how the rest of the squeak code is written.

Anyway, having got this code to work, I now want a way to package into something reusable. There are various options, I could add it to Array, I could add it to CSVparser, I could try to add it to either Matrix or Array2D. However, I don't 'own' any of those classes, so although I could subclass them, I really don't know if that is a good way to do it. So, instead, I am going to try to write a CSV Browser. Yes, I am going to delve into Morphic, or Seaside, or perhaps both.

12/09/2008

New day, new problem ;-)

So, after having learned about the CVSParser, I am now becoming more interested in the various squeak repositories. I say, 'various', because there do seem to be a lot of them. And, I don't really understand how the various package management tools in Squeak work.

Monticello, as far as I can tell, is a version management system, and I suspect that I would use it to manage my own code, as well as pull down other people's. The Monticello browser allows me to access numerous repositories. However, there is also a Package Universe browser. This lets me download packages (which seem to be Monticello files) from various sources. It doesn't seem to offer any upload capability, and therefore seems to be a 'consumer' tool. The problem is that this leaves me with several unanswered questions.
  1. Which respositories is the package universe browser accessing?
  2. How is that list kept up to date, and can I/should I add new repositories to the list?
  3. Is this now the preferred way of getting code (a bit like app-get on Linux)?
  4. What about the squeakmap browser, that I stumbled across as well?
  5. Finally, is there any kind of quality control in the packages that package universe lists? I don't mean it in a formal sense, after all no one is really 'in charge' of squeak, but rather is there any kind of rating system, because it seems as though squeaksource and squeakmap contain more items than are listed in the package universe.
Answers must be found!

11/09/2008

Maybe I am beginning to understand this stuff ;-)

This should probably be filed under the heading of "famous last words". However, I have actually succeed in doing something useful with Squeak. I think this is quite an important milestone. Up to this point I have been scratching my head and trying to understand individual methods, whilst all the while feeling that things weren't quite making sense. This evening, however, was different.

After I loaded Avi Bryant's CSV parser, I was able to create a stream from a file, figure out to how process the contents and ended up with an array of OrderedCollections. I wanted to pull the first item from each collection (basically, I was rotating a matrix), and display it in the Transcript. So... I typed in:

(CSVParser on: (FileStream readOnlyFileNamed: 'ifadqs.csv')) rows do: [:each| Transcript show: each first; cr].

And it worked :-)

Starting to use Monticello

Loading Avi's CSV parser, nudged me into using the Monticello browser. I had played with it before, but this time I had to work out how to 'hit' a different server - turns out you just click the +Repository button.

One strange thing about the browser is that I can't work out how to remove repositories from the list. Probably not important at the moment, but curious none the less

Characters != String

I am sure it makes perfect sense but...

The fact that:
$a = 'a'
returns false is a bit unhelpful. Still, worth noting for the future. Also

$a = ('a' at:1)
returns true.

Parsing CSV files and thinking in objects

I have a google spreadsheet that contains the answers to a questionnaire. I wanted to do some simple processing on the responses, so I thought it would be a good idea to use Squeak to munge the data around. However, that raised the question of how to get the data into the system. CSV to the rescue!

Google can export the file as CSV, so I thought it should be reasonably easy to convert it to some sort of OrderedCollection. The question was how to do it? I played around with some methods for a while, and then decided to ask on the beginners' list. The reason I wanted help was that I had the feeling that I was still thinking in far too procedural manner.

Zulq was kind enough to offer this solution
I ususally do something like this:

(((FileStream readOnlyFileNamed: 'file.csv')
contentsOfEntireFile " read and close "
findTokens: String crlf) " split into lines "
reject: [:e | e isEmpty]) " lose empty lines "
collect: [:e | e findTokens: $,] " split into fields "

Regards,
Zulq.


Squeak is so powerful, it is just amazing. It also highlights that I am still nowhere near getting the OO thinking right. Ah well, time enough. However, when I dug into the CSV a bit more I realised that the solution wasn't complete.

The CSV spec covers the situations where:
  1. data fields don't contain embedded commas
  2. where they do
  3. where they contain double quotes
This is important because - basically - if a field contains a comma then that field must be enclosed in double quotes e.g.
this is data,"so, is this"
So the findToken solution wouldn't be quite correct because it would split the line at every comma.

I was pondering this for a while, largely thinking how to solve this in the most elegant way, when it dawned on me that probably I should find the point in the existing solution that would produce the new solution, and create the least disruption - maybe a new heuristic? It seemed to me that if I could subclass (or perhaps replace) the findToken routine, then I would have changed the least amount of code, and still solved the problem. I am not really using the Test Driven Development approach yet - don't understand how to do it at a practical level - but that should be my next move.

Time to write some code