Archive for the tag 'Seaside'

9 July 2007 Upgrading Seaside

Here’s some very valuable info posted by Philippe Marschall (core Seaside developer) in the mailing list…

This is a short list of things to do when migrating for an older to a newer version of Seaside in the wiki at:
http://www.squeaksource.com/Seaside.html

2.6 to 2.7 must:

  • every component that uses the old default WAHtmlBuilder must do so explicity by returning it in #rendererClass
  • evaluate WADispatcher resetAll
  • use WATagBrush >> #title: instead of WATagBrush >> #tooltip:
  • move to new image map api, check all senders of #imageMap, see WAImageMapTag for details

2.6 to 2.7 should:

  • move to new header api, modify implementors of #updateRoot:
  • remove the implemtors of #rendererClass that return WARenderCanvas
  • migrate to WARenderCanvas
  • migrate from WAScriptLibrary and WAStyleLibrary to WAFileLibrary
  • use WAAnchorTag >> #with: instead of WAAnchorTag >> #text:
  • check for deprecated message sends
  • replace users of WAChangePassword, WAEditDialog, WAEmailConfirmation, WAGridDialog, WALoginDialog, WANoteDialog

2.7 to 2.8 must:

  • migrate to WARenderCanvas
  • backtrack state by implementing #states (check all senders of #registerObjectForBacktracking: and #registerForBacktracking)
  • move to new header api, modify #updateRoot:. #linkToStyle becomes #stylesheet #url, #linkToScript becomes #javascript #url:, check all implementors of #updateRoot:
  • use WAAnchorTag >> #with: instead of WAAnchorTag >> #text:
  • replace users of WAChangePassword, WAEditDialog, WAEmailConfirmation, WAGridDialog, WALoginDialog, WANoteDialog
  • every component that implements #initialize must send this message also to super (use SLint)
  • if you use Squeak 3.7 load SeasideSqueak37 after Seaside
  • if you use Squeak do not load into an image that has an earlier version of Seaside already loaded

2.7 to 2.8 should:

  • check for deprecated message sends
  • migrate from WAScriptLibrary and WAStyleLibrary to WAFileLibrary
  • remove the implementors of #rendererClass that return WAHtmlCanvas

I’m sure this list is not complete and I forgot stuff. So if you spot something that is missing send a message to me or the list or fix it directly. This is not on the Seaside homepage so anyone can edit it.
It will probably be moved to the homepage at a future point.

Cheers, Philippe

On the Smalltalk Browser

Some of the comments in a the Barrier To Entry post bring up the point that maybe the Smalltalk IDE itself is one of those barriers.

It’s an interesting thing, the Smalltalk browser. Unlike most IDEs, it’s optimized for reading code rather than writing code. Other IDEs allow you to see any number of methods all at once, cutting and pasting text giant chunks at a time, they sure make you feel like you’re working. They don’t however, allow you to navigate the semantic structure of the code very well nor do they encourage the writing of well organized code.

Modern IDEs are getting better at this, but they’re doing it by copying Smalltalk. Smalltalk’s various code browsers (hierarchy, method, inheritance, senders, implementors, protocol, category, package, refactoring) let you explore the structure and relationships between existing code and its tools (transcript, workspace, method finder, message names) make finding and using existing code, or understanding existing APIs vastly easier than any other language I know of. Seeing the structure of code is always but a context menu or hotkey away.

Smalltalk’s browser is rather opinionated, luckily, thanks to Rails, opinionated software seems to be having somewhat of a revival. When it comes to writing code, the browser forces you into a certain mindset, one that other languages don’t force you into. When I create a method in Java/C#/Ruby, I have to choose little more than what file and class it belongs in. I *can* organize the code well, but there’s little incentive to do so and my unit of work is rather undefined, I could be slicing and dicing methods, classes, namespaces, etc., usually with the full screen devoted to code across various files or even god forbid in one giant file. This encourages a code now and organize later approach. Sadly, later often never comes, and the code is left functional but messy.

Smalltalk on the other hand, defines my unit of work as *the method* and by doing so forces me at every turn, to continually organize my code in semantically meaningful ways. When I create a method, I have to choose a class category, a class, and a method category to put the method in. If I don’t, Smalltalk kindly categorizes the method for me in a protocol called “as yet unclassified”. It’s almost an insult, but it’s also a not so subtle reminder than I’m writing code sloppily, faster than I’m thinking. It reminds me to slow down, think for a second, where does this thing belong.

It only takes a second to pick a meaningful category name, and these names are idiomatic, I see them all the time when I’m looking for code. Aha, we’ve linked writing code to reading code. By taking the time to properly categorize my methods I also learn where to look for code later, when I’m in reading mode. It’s a feedback loop, the more I read the better I write and the better I write the more I learn to read with accuracy, looking only where necessary. It’s as if the code itself *is* a concise form of documentation hyperlinked by semantic meaning using things that Smalltalkers call browsers. Browsers and hyperlinks, bah, that’ll never work!

And RDoc, what the fuck is that, looks curiously like a Smalltalk browser to me, but why should class comments be anywhere except on the class itself? Oh that’s right, Ruby doesn’t have a Smalltalk browser, they code in files, how quaint.

As for editing the method itself, I work on and view only one method at a time, and only the lower half of the browser is for editing code which punishes me if I write long methods that can’t fit into that tiny pane. Smalltalk at every turn encourages me to read more code than I write, reuse more code than I otherwise might, and write smaller simpler methods than I likely would in a text editor.

Writing smaller methods forces me to give them meaningful names. Giving them meaningful names and putting them in meaningful places makes the code easier to read and easier to find. Code that is easier to read and easier to find, is easier to reuse, easier to understand, and easier to compose into new solutions. It’s called bottom up programming, the foundation of which is small composeable methods.

I keep using the word small, maybe that’s a mistake on my part, what I really mean is concise. Methods with a single purpose that is clearly summed up by their name. These kinds of methods happen to be short in general, but that’s a side effect of their being focused on a single task. The Smalltalk browser encourages these kinds of methods by making writing long methods or paying attention to too many methods painful. Text editors are general purpose editor aimed at text, that could be anything from a blog post to a novel. Surely an editor intended only for code, and only for a particular style of code, can be made much more *domain specific*.

The Smalltalk browser is such an editor, its domain is highly factored heavily structured bottom up style object oriented code. If that’s the style of code you like to write, you’ll find the Smalltalk browser wonderful, if not, you’ll find it painfully opinionated and rude.

Take a peek at decompiled .Net framework sources, or Ruby sources and what you’ll find, are average line per method counts in the 50+ to even 100+ ranges. In Smalltalk, around 10 or so. To me, this is a clear indication that text editors are the wrong interface for writing clean simple well factored reusable code. Sure, I just pulled these numbers out of my ass, but they reflect my experiences and even then, I’m being polite, 1000 line methods are not at all uncommon in .Net.

Maybe adjusting to the Smalltalk browser is similar to adjusting to Lisp’s parenthesis. It’s something you desperately want to fix as a newbie and make it work like other languages. In Lisp’s case, trying to design an infix Lisp while in Smalltalk it’s a text and file based editor. In both cases, once you stop fighting the language and realize the difference is actually a great strength of the language rather than something that needs fixed. You realize it’s you that needs to change, you open your mind, accept that sometimes different is good, and take advantage of the new power these tools give you.

Experienced Lispers love their parenthesis and experienced Smalltalkers love their browsers. Rather than seeing the Smalltalk browser as a barrier, maybe, just maybe, you’d be better off seeing it as a new toy to play with. Something new to learn.

UPDATE: Here’s a few admitidly cramped screenshots of the various browsers. They do of course look much better maximized on your monitor.

browser8.jpg

browser7.jpg

browser6.jpg

browser5.jpg

browser4.jpg

browser3.jpg

browser2.jpg

browser1

What are the Barriers to Entry for Smalltalk and Seaside?

It’s been two or three years since I began using Smalltalk and Seaside and I’m so comfortable in the environment I think I’ve forgotten how difficult it was to get going. By the time I started this blog, I was already quite comfortable using both Smalltalk and Seaside that I think a bunch of the little things I could have written about have been overlooked.

I’ve been so busy with work lately that I haven’t felt much like writing but I think it’s about time I give the blog a little more love. So those of you looking to get into Smalltalk, or Seaside, where’s your pain? What things are tripping you up that you can’t find answers to? What things are getting in your way that keep you from getting into the flow and really doing something in Seaside?

I’m just looking for some ideas for some bite sized yet useful articles covering topics I haven’t already covered that’ll help ease someone’s pain just a bit and get me back into the writing mood.

Maintaining Loose Coupling in Seaside Components

There is an interesting question that often comes up often when writing components. How do my components communicate with each other in a way that doesn’t bind them together explicitly. How does a child component call a method on a parent component without explicitly knowing who the parent is.

Knowing who the parent is prevents the component from being re-used in other contexts with different parents. There is a general solution to this whole class of problems and it was solved quite elegantly by Vassili Bykov with his Announcements framework.

The basic idea is to setup an announcer somewhere global, in the session for example.

MySession>>announcer
    ^ announcer ifNil: [announcer := Announcer new]

Then subclass Announcement for any interesting thing that might happen like removing a child.

Announcement subclass: #RemoveChild
    instanceVariableNames: 'child'

RemoveChild class>>child: aChild
    ^self new
        child: aChild;
        yourself

RemoveChild>>child: anChild
    child := anChild

RemoveChild>>child
    ^child

Any component interested in this announcement registers its interest when it initializes.

Parent>>initialize
    super initialize.
    self session announcer on: RemoveChild do:[:it | self removeChild: it child]

Parent>>removeChild: aChild
    self children remove: aChild

And any component who wants to fire this event simply announces it by sending in an instance of that custom announcement object.

Child>>removeMe
    self session announcer announce: (RemoveChild child: self)

Works great, and depending on where you place the announcer, you could even have different sessions sending events to each other, or different applications.

Here’s a file out of a commented working demo that has a child remove itself from the parent via an announcement.

UPDATE: I use the port of Announcements from Lukas Renggli’s public repository. The one on SqueakSource is a different port.

« Previous PageNext Page »