27/10/2008

Developing your applications through the debugger

Yesterday, while I was listening to an episode of FLOSS Weekly, Randal said something that caught my attention. He talked about writing unit tests and then running them before you had actually written the code - that much I had heard about before - but he then went on to talk about how you would then fix each of the tests by writing the code in the debugger, and clicking proceed.
This struck me as a really interesting way of coding. It's almost like having your office applications built into your to-do list. The to do item becomes the item you are trying to do.
I think I am going to experiment with this approach - I still need to understand a bit more about the debugger's capabilities. But what really appeals to me is that one could write almost pseudo code (although I think it is more of a declarative description) of what you want the object to do, and work away - a piece at a time - until it does it.
In a way, one could think of this style of programming as gradually removing all the bugs until the code does what you want.

Security 'watch outs' in Seaside

There was an interesting question raised on the Seaside list, today. I have pasted the thread below. Basically, if you share a URL with someone, they can potentially take over your seaside session. There are ways around the problem, but it is important to note for the future.

>
> hey, guys..
>
> one quick question after watching the seaside movie last night..
>
> pretend i have an application like ebay written in seaside..
>
> so, i log into my account..
>
> check my bids..
>
> then, i do a search for something..
>
> during that search, i find something my friend would really like..
>
> so i send the link to my friend..
>
> now.. suppose he immediately clicks it (i sent it over IM..)
>
> does he now have full access to my session, including my account
> information?

Unless you take action to prevent it, yes. This problem isn't unique
to Seaside, of course; any system with session keys in URLs will be
have the same problem. You can, of course, configure the session key
to be stored in cookies, which eliminates the problem. Or you can use
a WASessionProtector to prevent the IP address of the user from
changing.

Note that in either case, you would need to make sure to include
enough information in the URL via #updateUrl: that a new session could
be built pointing to the right item.

24/10/2008

I have no idea what this means, but I hope, in time, it will make sense

I am noting it here for future reference.

> is there a way to clean up the callback registry, or to unregister some
> callbacks?

With the model of Seaside, it is hard to tell what callbacks are still
used when doing AJAX. Therefore I suggest to do a full refresh from
time to time.

Note that you can easily do a full refresh through AJAX. Just trigger
an AJAX request to a normal callback, extract the string between
body and /body and place it into the DOM tree. This recreates all
the callbacks in the page and ensures that old ones eventually expire.
To the outside this "full request" feels like a normal AJAX action,
just that it is maybe a bit slower than the other ones.

Actually I planned to write a blog entry about this technique, just
didn't find the time yet.

23/10/2008

So that's what decorators do!

I have been reading about decorators in various tutorials, but not really got my head around them - largely because I am still trying to understand more basic information. However, this post in the Seaside list really helps me understand the concept.



You may also want to take a look at WADecoration, which can help you
to decouple the header/footer from the main page:

WADecoration:
I am an abstract decoration around instances of WAComponent. I can be
added to aComponent by calling #addDecoration: and I change the basic
behaviour or look of a component. There are several methods that can
be overriden to archive this:

- #renderContentOn: to emit xhtml around the decorated component. Call
#renderOwnerOn: to let the owner emit its output.
- #processChildCallbacks: to intercept the callback processing of the
owner.
- #handleAnswer: to intercept the answer processing.



I am sure I will find all the methods useful, eventually, but it is the first one that struck me as particularly interesting. It's almost as if it allows you to add 'decoration' to a component. Hmmm, intention revealing method names, not such a bad idea after all ;-)

Switching between https and http sessions

Establishing SSL connections is going to be important in a lot of my apps, so this code snippet from Ramon is well worth noting

14/10/2008

It won't work, if you don't use the right objects

I had a very interesting problem yesterday. I am slowly moving forward on building the threaded discussion system. I have worked out how to render the basic HTML, as a series of components, and I was at the stage of wanting to render the discussion items. My question was how to represent them?

In an earlier post I had looked at how one might identify the objects in a system, and in particular which ones should be written from scratch. The basic idea was that if one were storing information that already 'fitted' into a class, there was no reason to create something new. The class could be a simple one, such as Array, or something more complex such as Person. In either case, the basic principle was - don't reinvent the wheel. However, as we will see sometimes reinventing the wheel is the right thing to do!

I decided to represent the conversation as an array of nested arrays, e.g.,

discussion := #(topic1 topic2 (sub-topic2.1 sub-topic2.2) topic3).

Initially, the structure seemed to work well. It was simple, easy to traverse and didn't involve the creation of any new classes. I was quite pleased with myself for following the design principles. Unfortunately, I soon discovered that rendering the subarrays was a pain. Basically, I want Seaside to create an Ordered List and add the entries as List Items. When it comes across a subarray, it should start another ol tag and add the elements.

I played with this problem for a little while, but everything I did seemed ugly, and not very smalltalk. In the end, I asked on the beginners' list and received two interesting replies:

  1. Randal suggested using the Visitor Pattern

  2. Ramon suggested creating two new objects and using recursion (see below)


I had never heard of the visitor pattern, but fortunately Wikipedia came to the rescue. AIUI this would involve adding a method to both the array, and the strings/arrays it contains, so that they know how to render themselves. Ramon's code, more directly challenged the way I was storing the discussion threads. He suggested something like this:

renderPost: aPost on: html
html render: aPost.
aPost comments do:
[ :each | self renderComment: each on: html ]

renderComment: aComment on: html
html html: aComment body.
aComment comments do:
[ :each | self renderComment: each on: html ]

For the time being, I am going to try Ramon's approach, purely because I have a better understanding of how to do it. However, I am now intrigued by the visitor pattern, so I will go back to that, once I understand a bit more about OO design. However, for me, the most interesting aspect of this whole problem was the question of why couldn't I see the answer? I think the explanation is that once I had decided to go with an Array, my thinking was limited to that set of methods etc. And, the choice of the Array was driven by the fact that the data could be made to fit into it. So, I now need to develop a more sophisticated design heuristic when thinking about object modelling. Basically, just because something could fit, doesn't mean it should. Now, obviously, design is an iterative process, and all programmers run around refactoring, sooner or later. What I am trying to understand is how I might think about the problem in a more flexible manner.

13/10/2008

Creating a framework on top of Seaside

Now that I am starting to understand Seaside (and Squeak), I am beginning to realise that I will probably need to customise a bit. Not because of shortcomings, but rather because there will be various good practices that one will almost always want to build into a project. My previous post about Ramon Leon's initialisation tricks is a good case in point.

Randal's comment on that post - I have included his version in this post - came at the exact moment I happened to be reading another of his entries, which addressed configuring the startup/shutdown issue. So, my default application settings will now contain something like this:


MyClass class >> initialize
self registerAsApplication: #foo.
Smalltalk addToStartUpList: self.
Smalltalk addToShutDownList: self.
self startUp.

MyClass class >> #registerAsApplication: name
^(super registerAsApplication: name)
libraries add: SULibrary;
preferenceAt: #sessionClass put: FooSession;
yourself.

MyClass class >> startUp
self start. "in case I want more things here"

MyClass class >> start

WAKom default.
... other stuff if I want it...
HttpService startOn: 9090 named: 'httpd'.

MyClass class >> shutDown

self stop.

MyClass class >> stop

HttpService allInstancesDo: [:each | each stop. each unregister].

Tips and tricks for making seaside applications easy to manage

One of my current web applications is built on top of Lotus Domino. I have used Domino & Notes for years, and I have a deep respect for it. This particular application was only meant to have a short shelf life, but it has turned into the application that wouldn't die. Normally, I would be happy with that, it is always nice to know that your work is appreciated. However, in this case, because it was put together in a hurry, we didn't build a web based admin console for it. Unfortunately, for us, this means that every time someone want's to use the app, we have to scurry around with a copy of Lotus Notes, messing about with environment variables by hand.
Granted, our 'suffering' is trivial in comparison with people who deal 'real' jobs. After all, as many of my friends have pointed out, all we do is sit around, drinking tea and chatting with people, followed by messing around with computers - hard to argue with that assessment. Anyway, as we move applications over to Seaside, I am really keen that we should do everything possible to simplify the admin. And, that is why I found this section of Ramon Leon's Terse Guide to Seaside, so interesting. He wrote:

FooComponent class>>initialize
"self initialize"
| app |
app := self registerAsApplication: #foo.
app libraries add: SULibrary.
app preferenceAt: #sessionClass put: FooSession

This sets up a dispatcher at /seaside/foo with the Scriptaculous library (SULibrary) and a custom session class that might contain things like the current user or current database session. You can then highlight the comment “self initialize” and run it to create your site. This has the additional advantage of automatically setting up your site in any new image when you load your package into it and also allowing you to programatically recreate your site on demand. This comes in very handy when upgrading to newer versions of Seaside which sometimes require recreating your sites.


I think this is going to be very useful for the future

12/10/2008

Oh, so when you say 'literal' you really do mean 'literal'!

This comes from the 'hard of thinking' category.

I was trying to create my 'children' method - necessary when you are rendering subcomponents in seaside. I knew it need to return a collection, and when I looked at an example, it showed:

 ^#()


In other words, return an empty array. Obviously, it was using the array literal syntax. This, of course, it where my thinking went horribly wrong. I created my method with the following code:

 ^#(pageHeader pageFooter).


Seaside stopped working :-( It complained about a decorator method not being understood by ByteSymbol. If you are new to seaside, and you don't already know the answer, see if you can work out what I was doing wrong.

Give up? OK, the array literal syntax creates an array of literals. I know, who would have thought it! My array contained the symbols #pageHeader and #pageFooter, NOT the value of those two instance variables. Totally obvious now, but I share it in case you are ever tempted into similar thinking. And, just for your information, the correct code is:

 Array with: pageHeader with: pageFooter.


## Update: Randal has just pointed out that there is also 'curly brace' runtime Array constructor that was limited to Squeak, but is now available in Gemstone and possibly VW. The syntax is:

 {pageHeader. pageFooter}


This makes much more sense, and is a very slick way of creating arrays. Thanks Randal

11/10/2008

As Homer would say "Mmmm Smalltalk, is there nothing it can't do?"

No sooner had I posted my vague 'pipe dream' about automatically creating methods, than Randal posted a comment, showing exactly how to do it. In case you aren't subscribed to the comments feed, this is what he wrote:

#(one two three four five) do: [:each | YourClass compile: (each asString , ' self flag: #toBeWritten') ].


Actually, he finished his code with a :-) . Out of curiosity, and powered by my new found belief that Smalltalk really can do anything, I opened a method finder to check whether :-) is a method. Sadly, and not surprisingly, it is invalid syntax. However, if I ever do find a way of implementing it, I shall get it to return an Anchor tag to this video.

Misusing the 'create accessors' menu option

I spent some of last night sketching out the UML for my test project. I wanted to turn the sketches into code, but it was late and I couldn't be bothered to type out all the method names etc. Then I had an idea. If I created instance variables for each of the methods, I could use the Accessor menu item to automatically build the stubs. Then, delete the superflous variables, and my structure is ready to fill in.

Now, clearly this is an ugly hack. However, it did save me some time, and it made me curious about how the accessor code generator works. At some point in the future, I will see if I can find the appropriate methods and create a new version. Ideally, I would like to have a new item in class definition, something like stubMethods: that would allow me to generate the methods and mark each one with a self flag: #toBeWritten. call.

Starting to use the refactoring tools in OB

Up to now, the only OmniBrowser tool I have used is the 'accessors' option, which automatically generates instance variable access methods. All my other actions, e.g. moving methods, creating subclasses etc., have been done manually, largely because my mind was fully occupied just trying to work out what I was meant to be doing!

Last night, I decided to bite the bullet and explore a bit further. And finally, I am beginning to understand why experienced Smalltalkers describe the system as being more than just a language. There are some really clever tools that can save you from, not just wasting time, but also the chance of messing things up, badly!

For example, I needed to rename a variable in a method, and therefore also rename its accessor. When I used the rename menu option, it went off, did the rename and then updated all the methods which accessed that method - brilliant!

Now, clearly this sort of global search and replace isn't rocket science, but the fact that the tools are so beautifully integrated means that coding, and refactoring, become a 'relative' pleasure.

Smalltalk and Etoile

Some time ago I stumbled across an open source project called Etoile

The project is attempting to create a new, configurable, interface for computers, based upon the GNUStep library. My interest lay in the potential to build workspaces that might support creative problem solving. Anyway, recently, they announced that they were planning to build Smalltalk into the system, and that has now happened.

The class library is a little unusual, because it builds on top of the GNUStep library, but the basic language will be familar to anyone who has used Smalltalk. I really like the idea of being able to program the whole OS via Smalltalk.

10/10/2008

A terse guide to seaside

Ramon Leon has put together a very good, and - as the name suggests - brief guide to Seaside. You can read it here.

What I find so interesting about the guide is that a few months ago the contents would have been largely unintelligible to me, and now, they seem to make perfect sense. I am sure people have the same experience when learning any new skill, but it does reinforce the idea that it is worth going back over tutorials, several times, because you can get a lot of new information that you may have missed the first time through

06/10/2008

Class side variables, an alternative to Global variables

I have built my small experiment, using Globals, and it actually works quite well. However, over the weekend, I was thinking about whether I should use a Class instead of the Globals. Mark Volkmann was thinking similar thoughts, but with a different objective. He added this to the beginners' list


create a class that represents the enumerated type
add a class variable for each enumerated value (must start uppercase)
add a class-side initialize method that creates an instance of the
class for each enumerated value using basicNew and assigns it the
corresponding class variable
prevent creation of additional instances by overiding the class method
new with "self error: 'new instances cannot be created'"
add class-side getter method for each enumerated value that simply
returns it
Here's an example ColorEnum class.

Object subclass: #ColorEnum
instanceVariableNames: ''
classVariableNames: 'Blue Green Red'
poolDictionaries: ''
category: 'SomeCategory'

initialize
Red := self basicNew.
Green := self basicNew.
Blue := self basicNew

new
self error: 'new instances cannot be created'

red
^Red

green
^Green

blue
^Blue

---
Mark Volkmann

03/10/2008

Timing execution speed

Premature optimisation is Evil. However, I think Evil has an unfair reputation. And, because of that, this particular code fragment is well worth remembering

Time millisecondsToRun: [].

Update: Turns out you can actually send

timeToRun to any block. Much easier.

Creating some sort of data bus

How might I get the various Seaside components to know about their underlying models?

I am trying to build a simple application - sort of a discussion forum. There could be several fora, plus a collection of users - each of whom needs to authenticate. What I am trying to get straight is the easiest/best/most reuseable etc., way of linking the presentation with the data.

Clearly, when I instantiate components, I could pass them the address of the model - or just the subpart of the model they will be interested in, but somehow that feels clunky to me.

As I was sitting here, thinking about it, it suddenly occurred to me that I could identify the shared objects, e.g., user directory etc, and declare them as Global variables in the Smalltalk SystemDictionary. That way, they would be naturally accessible to all components. But, is this a good idea? Aren't Global variables evil?

I don't know, but it does seem to be a neat solution, that builds on top of Smalltalk's 'natural' behaviour, and means that the objects can initialize themselves.

I am going to have a play with the design and see how it pans out.

Building a login system for Seaside

I need to build a website that has individual user authentication. I was confused about how to do this, but fortunately, this article seems to cover it very well. I shall go and experiment.

Clever ways to build strings

Mark Volkmann asked a question, on the beginners' list, about the best way to build a concatenated string. He wonder whether there was a benefit in doing one of the following:

Approach #1

s := ''.
s := s, 'foo'.
s := s, 'bar'

Approach #2

stream := WriteStream on: ''.
stream nextPutAll: 'foo'.
stream nextPutAll: 'bar'.
s := stream contents


Randal responded with this suggestion:


s := String streamContents: [:stream |
stream
nextPutAll: 'foo';
nextPutAll: 'bar'.
].

Then you don't even have to name the stream, because it has that
temporary name inside the block.


It has taken me a little while to understand how this works. Up to now, I have been thinking about blocks with arguments as having their argument passed in from the 'thing' they are associated with. E.g.

(1 to: 10) do: [:index| Transcript show: index]


In this case, the argument is created within the called method:

streamContents: blockWithArg
| stream |
stream := WriteStream on: (self new: 100).
blockWithArg value: stream.
^stream contents


This gives me a new way of thinking about arguments and blocks.