tag:blogger.com,1999:blog-79053668473390881302009-02-20T22:53:47.110-08:00Jazz ProgrammingDynamic Languages, Agile Methodologies, and All That Jazz.gcorriganoreply@blogger.comBlogger35125tag:blogger.com,1999:blog-7905366847339088130.post-40316502757712967652007-11-06T09:07:00.000-08:002008-05-18T12:39:38.146-07:00ECMAScript 4ECMAScript is the standardized form of the language known as JavaScript. In its current incarnation, it is a nice little prototype-based object language that unfortunately is plagued by some warts (peruse this <a href="http://yuiblog.com/blog/2007/04/25/id-rather-switch-than-fight/">blog post</a> to read about some of them) and by DOM implementation riddled with bugs and security problems. This, according to <a href="http://javascript.crockford.com/javascript.html">Douglas Crockford</a>, makes it <em>“the world’s most misunderstood programming language”</em>.<br /><br />The guys at <a href="http://www.ecmascript.org">Ecmascript.org</a> are actively working on a new revision of the standard, and have recently published a new proposal for ECMAScript, edition 4, complete with a reference implementation. This new proposal looks like a 180° turn from the current language, moving to a class-based object orientation paradigm, with multimethods, optional static typing, etc.<br /><br />The proposal has been well-received by programming-languages researchers and aficionados, such as those at <a href="http://lambda-the-ultimate.org/node/2504#comment">Lambda the Ultimate</a>. But many others, such as Dave “Smalltalk” Thomas, have <a href="http://www.jot.fm/issues/issue_2007_11/column3/index.html">voiced</a> their opposition to this new standard:<br /><br /><blockquote><em>Just browsing through the wiki shows a language which has prototypes, classes, multi-methods?, static types, dynamic types, etc, etc. This reminds an old guy like myself of other large design by committee languages such as PL/I, Algol 68 and ADA. These ambitious efforts all had smart people involved in the design and implementation but were unfortunately far too complex and came to the market too late. JS is intended to be a language for the people, not another language that only technical wizards can understand. If you are an Ajax developer or care about dynamic languages I suggest that it is time for you to speak up and help put ECMAScript 4 on a much less ambitious path than is currently being charted. Less is truly more when it comes to languages.</em></blockquote><br /><br />My friend <a href="http://www.riffraff.info/2007/10/25/ecmascript-4-the-fourth-system-syndrome">Riffraff</a> has too a good critique of the proposal:<br /><br /><blockquote><em>The second system syndrome is that evil effect that often happens when redesign a small, working system so that it becomes a huge leviathan built by piling new features over new features.</em></blockquote><br /><br />Today I was reading the overview of ECMASCript 4 from ecmascript.org, and I got this very bad feeling that maybe the fourth version of ES, is suffering of an extremely strong case of this problem.*<br /><br />To make things worse, it looks like there’s some sort of <a href="http://arstechnica.com/news.ars/post/20071102-major-stakeholders-argue-about-the-future-of-web-scripting.html">fracture</a> in the ECMAScript 4 working group, with Adobe and Mozilla on one side, and Microsoft and Yahoo! on the other.<br /><br />In my opiion, all of this doesn’t bode well for the new language. Are we going towards another browser war?<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-4031650275771296765?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-7534687408363658072007-11-06T00:12:00.000-08:002008-05-18T12:21:41.157-07:00HttpView2 1.1-betaYesterday I released a first beta version of <a href="http://wiki.squeak.org/squeak/HttpView2">HttpView2</a>. This is the first development release of HV2 since Goran published version 1.0 in November 2004.<br /><br />HttpView2 (aka HV2) is a little, <em>lean</em> web framework for Squeak. Since <a href="http://goran.krampe.se/">Goran</a>, the original author, has given me complete development freedom, I’m steering HV2 away from being a framework for web applications and towards being one for RESTful web services.<br /><br />Highlights of this new development release include:<br /><ul><li>a new, generic Canvas system</li><br /><li>a new XHTML Canvas system, inspired by Seaside’s one.</li><br /><li>HTTP responses are now accessible from the various View methods</li><br /><li>source code reorganization</li></ul><br />HV2 1.1 is available on <a href="http://map.squeak.org/packagebyname/HttpView2">Squeak Map</a>. If you have any bug reports, or you’re interested in helping, drop me a line in the comments.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-753468740836365807?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-5893076044974059252007-10-31T23:03:00.000-07:002008-05-18T12:20:06.639-07:00RESTful Web Services Example 3.4 - Obtaining a list of bucketsExample 3.4 of the <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRESTful-Web-Services-Leonard-Richardson%2Fdp%2F0596529260%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">RESTful Web Services</a> deals with obtaining a list of <em>buckets</em> (think of them as top-leve directories). This first version of the code will return a collection of strings, each one being the name of a single bucket. This is done by sending <code>#getBuckets</code> to an <code>S3BucketList</code> instance.<br /><br />If you load the latest code (RWS-gc.25) from the <a href="http://www.squeaksource.com/RWS.html">RWS repository</a> you’ll see many new changes. The ones we’re interested into are the <code>S3Authorized</code> class and the <code>S3BucketList</code> class.<br /><br />The former is a class extracted via refactorings from the <code>S3Object</code> class, while the latter allows you to get the list of your buckets.<br /><br />Take a look at <code>S3BucketList>>getBuckets</code>. The method is defined as:<br /><pre>S3BucketList>>getBuckets<br /> | doc |<br /> "Fetch all the buckets this user has defined.<br /><br /> Code taken from RESTful Web Services. Copyright © 2007 O'Reilly Media, Inc.<br /> All rights reserved. Used with permission."<br /><br /> "GET the bucket list URI and build an XML DOM tree from it."<br /> doc := XMLDOMParser <br /> parseDocumentFrom: (self get: Host) contents readStream.<br /> "For every bucket, collect its name"<br /> ^ doc // 'Bucket' / 'Name' collect: [:each | each contentString]</pre><br />As you may see, the Smalltalk code is shorter than the corresponding Ruby code. That’s because we used <a href="http://blogs.corriga.net/giovanni/archives/2007/7/1/installing_pastell_and_the_curlplugin/">Pastell</a>, an XPath-like DSL for navigating XML DOM trees, instead of using a separate XPath library.<br /><br />The first line of code creates a DOM tree from the XML document obtained by sending <code>#get:</code> to itself. <code>#get:</code> is one of the new messages added in the <a href="http://blogs.corriga.net/giovanni/archives/2007/10/29/restful_web_services_a_better/">previous post</a>.<br /><br />In the second line, the DOM tree is sent a <code>#//</code> message. This message selects all the descendant nodes of an XML node whose name matches the argument of the message. In this example, the result of this message send will be a collection of nodes whose tag is <code>'Bucket'</code>. This collection is a special subclass of <code>OrderedCollection</code> that can understand the Pastell messages, called <code>PastellCollection</code><br /><br />The list of nodes is sent another Pastell message, <code>#/</code>. This message selects all the child nodes whose tag matches the argument of the message. In this example, when sent to the PastellCollection instance returned by <code>#//</code>, it returns another PastellCollection whose elements have a <code>'Name'</code> tag. We can retrieve the actual names of this elements by <code>collect:</code>ing their <code>contentString</code>s.<br /><br />In the next two examples, we’ll see how to model a single bucket as a Squeak object, and how to modify <code>S3BucketList>>getBuckets</code> in order to make it return a collection of objects instead of strings.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-589307604497405925?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-85812397352395253522007-10-29T10:04:00.000-07:002008-05-18T12:17:21.087-07:00RESTful Web Services - A Better HTTP interfaceBefore moving to the remaining Amazon S3 examples from Chapter 3 of the <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRESTful-Web-Services-Leonard-Richardson%2Fdp%2F0596529260%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">RESTFul Web Services</a> book, let’s take another look at the code. The previous examples were strongly inspired by the corresponding Ruby examples. This, paired with the use of the libCurl bindings, has led to code which is brittle and hard to modify.<br /><br />As an example, let’s consider the <a href="http://blogs.corriga.net/giovanni/archives/2007/10/22/restful_web_services_example_315/">code</a> for <code>S3Object>>open:method:headers:</code>. This method requires the HTTP method in order to compute the correct signature for the request, but then ignores it by sending <code>request download</code>, which is the message used to send a GET request. A possible solution for this is to use a <code>case</code>-like solution in order to send the right message; the code would then become something like this:<br /><pre>(method asLowercase == 'put')<br /> ifTrue: [request upload]<br /> ifFalse: [request download]</pre><br />Now, this isn’t just ugly, it’s plain bad OO code. This means we have to look for another solution.<br /><br />The solution that I’ve chosen is based on the pattern used for Seaside’s and HV2’s Canvas systems. It involves having an <code>S3Request</code> object that wraps a <code>Curl</code> instance and provides a simple interface. <code>S3Request</code> has different subclasses for the various HTTP methods: <code>S3GetRequest</code>, <code>S3PutRequest</code> etc.<br /><br />The code for <code>S3Request</code> and its subclasses may be found in package RWS-gc.20 from the <a href="http://www.squeaksource.com/RWS.html">RWS repository</a>. <code>S3Request</code> is defined as:<br /><pre>Object subclass: #S3Request<br /> instanceVariableNames: 'headers url request contents'<br /> classVariableNames: ''<br /> poolDictionaries: ''<br /> category: 'RWS-Examples'</pre><br />I won’t provide a detailed explaination for this class, save for the <code>#send</code> message:<br /><pre>S3Request>>send<br /> request := Curl new.<br /> request url: url.<br /> headers keysAndValuesDo:<br /> [:key :value |<br /> request addHeader: key, ': ', value].<br /> request onHttpHeaders.<br /> self perform.<br />^ request</pre><br /><code>#send</code> creates a new Curl object, sets the headers and url for the new request, then sends a <code>#perform</code> message to itself before returning the Curl object. <code>#perform</code> is an abstract message implemented by the various subclasses of <code>S3Request</code>. For example, <code>S3PutRequest>>perform</code> looks like<br /><pre>S3PutRequest>>perform<br /> contents ifNotNil: [request contents: contents].<br /> request upload</pre><br />This is a simple and elegant solution to our problem that, while adding 5 new classes to the system, keeps the overall complexity of the code to a much lower level.<br /><br />In order to use this new API, I’ve added some more messages to the protocols of S3Object. If you browse the latest versions of this class, you’ll find many methods such as <code>#get:headers:</code>, <code>#put:contents:headers:</code> etc. This methods replace the <code>#open:method:headers:</code> message and its variants.<br /><br />In the next post, we’ll see how to interact with the Amazon S3 service. Meanwhile, I suggest you go over Chapter 3 of <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRESTful-Web-Services-Leonard-Richardson%2Fdp%2F0596529260%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">Richardson and Ruby’s book</a> in order to get yourself acquainted with S3’s lingo.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-8581239735239525352?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-38191764826929241322007-10-26T12:17:00.000-07:002008-05-18T12:09:54.323-07:00KomHttpServer 7.0.5In the past days I’ve become one of the mantainers of KomHttpServer, Squeak’s native HTTP server. I’ve just released a new version (available on <a href="http://map.squeak.org/package/0fdb5ffc-cfa1-4d40-96c2-fe325bc8ba5f">Squeak Map</a>) that includes various bug fixes, and HTTP 1.1 compliant status codes (plus some WebDAV ones, too).<br /><br />I’d like to thank Goran, Ron, Philippe and all the others for the work they’ve done on Kom’s source code.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-3819176482692924132?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-23629855665791946022007-10-24T15:32:00.000-07:002008-05-18T12:08:27.134-07:00Vito Di Modugno Organ Quartet plays Haitian Fight SongCharles Mingus’ <em><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FHaitan-Fight-Song%2Fdp%2FB000U8IPEU%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">Haitian Fight Song</a></em> (and its later variant <em><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FII-B-S%2Fdp%2FB000VRLCZO%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">II B.S.</a></em>) is one of my favourite jazz pieces. And the organ, especially the Hammond organ, is one of my favourite musical instruments. So I was very pleased to find on Youtube a version of Haitian Fight Song played by the Vito di Modugno Organ Quartet. Here is it, for your hearing pleasure:<br /><object width="425" height="366"><param name="movie" value="http://www.youtube.com/v/jZiHcTqr-ZM&rel=1&border=0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/jZiHcTqr-ZM&rel=1&border=0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="366"></embed></object><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-2362985566579194602?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-35129427603720022192007-10-23T13:44:00.000-07:002008-05-18T12:06:18.413-07:00Miles Davis - So What 1958 & 1964Looks like I’m not the only one with a blog who’s interested in Jazz and programming. <a href="http://patricklogan.blogspot.com/">Patrick Logan</a> just published a wonderful post about <a href="http://patricklogan.blogspot.com/2007/10/compare-1958-recording-of-so-what-via.html">Miles Davis’ So What</a> So What is a track from the <em><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FKind-Blue-Miles-Davis%2Fdp%2FB000002ADT%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">Kind of Blue</a></em> album, and Patrick compares two different versions of it: the first one from 1958, the second one from 1964. It’s difficult to say which one I prefer.<br /><br />Incidentally, just ten days ago in the <a href="http://netartmagazine.com/2003/IrcVerbamanent">#verbamanent IRC channel</a> we briefly discussed and compared Davis’ <em><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FKind-Blue-Miles-Davis%2Fdp%2FB000002ADT%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">Kind of Blue</a></em>, Coltrane’s <em><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FLove-Supreme-John-Coltrane%2Fdp%2FB0000A118M%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">A Love Supreme</a></em> and Mingus’ <em><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FBlack-Saint-Sinner-Lady%2Fdp%2FB000003N81%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">The Black Saint & The Sinner Lady</a></em>. The comparision is a little inappropriate, since Kind of Blue precedes the other two albums by roughly five years, but it’s interesting nonetheless. I’m going to write more about these three albums in another post.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-3512942760372002219?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-66629067156837025652007-10-22T11:36:00.000-07:002008-05-18T12:03:23.086-07:00RESTful Web Services - Bugfixing CurlPluginBefore moving to today’s example, in which we’re going to start interacting with the Amazon S3 server, I’ll take a diversion to explain why all this lateness. As I wrote in the <a href="http://blogs.corriga.net/giovanni/archives/2007/10/21/restful_web_services_example_316/">previous post</a>, this example is so late because of a bug in CurlPlugin that I introduced myself.<br /><br />The original CurlPlugin didn’t expose at the Smalltalk level the functionalities for setting custom HTTP headers in the request, so I had to add these functionalities to the plugin. When I did that, I overlooked the fact that a Smalltalk string and a C string aren’t implemented in the same way: a Smalltalk string, being a <code>Collection</code> subclass, has an arrayed collection of character elements (either 8-bit or 32-bit wide) and an explicit size attribute, while a C string is a NULL-termined array of <code>char</code>.<br /><br />This means that since you can’t be sure of the fact that, in the internal representation of a Smalltalk string, the value after the last character of the string will be a NULL, you have to explicitly add one. Since I forgot to do so (by sending a simple <code>#asCString</code> message, provided by CurlPlugin), I introduced a tricky bug in the plugin. To make things worse, this bug showed itself only when the string was longer than usual. So, when adding to the request short headers such as <code>Date:</code> or <code>Content-Type:</code> there were no problems, while the <code>Authorization:</code> header always had some spurious trailing characters.<br /><br />In order to detect this bug, I had to install a <a href="http://www.wireshark.org/">packet sniffer</a>, learn how to use it, and look at what libCurl was actually sending to the server. As it often happens, once the problem was identified, fixing it was a matter of minutes.<br /><br />Now that the bug is fixed, you’ll have to download the <a href="http://www.corriga.net/%7Egiovanni/Squeak/CurlPlugin.zip">new version</a> of the CurlPlugin. Extract the archive, overwrite the <code>CurlPlugin</code> file in your image directory, file in the new <code>Curl.st</code> file, and you’ll be ready for the next example.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-6662906715683702565?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com5tag:blogger.com,1999:blog-7905366847339088130.post-78910303029645303122007-10-21T12:49:00.000-07:002008-05-18T12:01:27.705-07:00RESTful Web Services Example 3.16 - Signing the requestAfter little less than a month, let’s resume with the Squeak Smalltalk versions of the examples of the <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRESTful-Web-Services-Leonard-Richardson%2Fdp%2F0596529260%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">RESTful Web Services</a>. This latest installment is so late due to a bug that I introduced in the <a href="http://blogs.corriga.net/giovanni/archives/2007/7/1/installing_pastell_and_the_curlplugin/">CurlPlugin</a> code when adding a new primitive, and it took me a long while to debug it. The new primitive is needed for the next example in this series.<br /><br />We already know <a href="http://blogs.corriga.net/giovanni/archives/2007/9/24/restful_web_services_example_318/">how to build a canonical string</a>, and <a href="http://blogs.corriga.net/giovanni/archives/2007/9/22/restful_web_services_examples_319/">how to actually sign it</a>. In today’s example, we’ll see how the request signature is created from the URI, the HTTP method, and the headers.<br />This is the task of the <code>#signatureFor:method:headers:expires:</code> method and its ilk.<br /><br />The source for <code>S3Object>>signatureFor:method:headers:expires:</code> is the following:<br /><pre>S3Object>>#signatureFor: aStringOrUri method: method headers: headers expires: expires<br /> | uri path |<br /> "Builds the cryptographic signature for an HTTP request. This is<br /> the signature (signed with your private key) of a 'canonical<br /> string' containing all interesting information about the request.<br /><br /> Code taken from RESTful Web Services. Copyright © 2007 O'Reilly Media, Inc.<br /> All rights reserved. Used with permission."<br /><br /> "Accept the URI either as a Squeak URI object, or as a string"<br /> uri := aStringOrUri asURI.<br /> path := uri query ifNil: [uri path] ifNotNil: [uri path, uri query].<br /><br /> "Build the canonical string, then sign it"<br /> ^ self signString: (self canonicalStringFor: method path: path headers: headers expires: expires)</pre><br />The method is very simple, but there are a couple of observations that may be done.<br /><br />The first observation is about the <code>uri</code> temporary variable: since the <code>aStringOrUri</code> parameter, as the name says, may be either a string or an URI, we send the <code>#asURI</code> message in order to be sure that <code>uri</code> holds an <code>URI</code> object (this way of ensuring that an object is of the appropriate class is a common pattern in Smalltalk).<br />Once we are sure we have an URI object, we extract the path from the URI, plus the optional query string (the part of the URI after the <code>?</code> character).<br /><br />Finally, we build the canonical string, sign it and return the signature.<br /><br />The source code for this method is included in the RWS-gc.14 package in the <a href="http://www.squeaksource.com/RWS.html">RWS repository</a>. In the same package you will find other variations of the same method:<br /><br /><pre>`S3Object>>#signatureFor:method:headers:`<br />`S3Object>>#signatureFor:method:`<br />`S3Object>>#signatureFor:headers:`<br />`S3Object>>#signatureFor:`<br /></pre><br /><br />If you browse the source code for these methods, you’ll observe that all these methods send the <code>#signatureFor:method:headers:expires:</code> message with the appropriate default parameters. This is a very common pattern in Smalltalk, but it has one serious flaw, as the sheer number of possible combinations makes this solution unpractical on a large scale. For example, a message with four parameters may have other 14 possible variants, while one with five parameters has 30 possible variants.<br /><br />This <a href="http://en.wikipedia.org/wiki/Combinatorial_explosion">combinatorial explosion</a> is somewhat mitigated by the fact that usually there’s only a restricted subset of sensible and useful variants of a message, but in many cases this is not enough. This is one of the reason why <a href="http:/www.seaside.st/">Seaside</a> moved from a builder system to a canvas one for (X)HTML generation.<br /><br />In the next post in this series, we’ll see how to send a signed request to the Amazon S3 service.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-7891030302964530312?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-14807909109184196212007-09-24T12:14:00.000-07:002008-05-18T11:58:53.824-07:00RESTful Web Services Example 3.18 - Building the canonical stringToday’s <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRESTful-Web-Services-Leonard-Richardson%2Fdp%2F0596529260%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">RESTful Web Services</a> example is another utility method named <code>#canonicalStringFor:path:headers:expires:</code>. This method builds the string that will be used to sign the HTTP request.<br /><br />According to the <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=123&categoryID=48">Amazon S3 Developer Guide</a>, the <em>canonical string</em> is composed with the HTTP request method, the request path and some of the headers of the request. I refer you to either the S3 docs or to the RWS book for more information on how the string is built.<br /><br />The code for <code>#canonicalStringFor:path:headers:expires:</code> is the following:<br /><pre>S3Object>>canonicalStringFor: method path: path headers: headers expires: expires<br /> | signHeaders canonical param |<br /> "Turns the elements of an HTTP request into a string that can be<br /> signed to prove a request comes from your web service account.<br /> Code taken from RESTful Web Services. Copyright © 2007 O'Reilly Media, Inc.<br /> All rights reserved. Used with permission."<br /><br /> "Start out with default values for all the interesting headers."<br /> signHeaders := Dictionary new.<br /> InterestingHeaders do: [:header | signHeaders at: header put: String new].<br /><br /> "Copy in any actual values, including values for custom S3 headers."<br /> headers keysAndValuesDo:<br /> [:header :value |<br /> header isString ifTrue:<br /> [header := header asLowercase.<br /> "If it's a custom header, or one Amazon thinks is interesting..."<br /> ((InterestingHeaders includes: header) or:<br /> [header beginsWith: AmazonHeaderPrefix]) ifTrue:<br /> [signHeaders at: header put: value asString]]].<br /><br /> "This library eliminates the need for the x-amz-date header that Amazon defines,<br /> but someone might set it anyway. If they do, we'll do without HTTP's standard Date header."<br /> (signHeaders includesKey: 'x-amz-date') ifTrue: [signHeaders at: 'date 'put: String new].<br /><br /> "If an expiration time was provided, it overrides any Date header.<br /> This signature will be valid until the expiration time,<br /> not only during the single second designated by the Date header."<br /> expires ifNotNil: [signHeaders at: 'date' put: expires].<br /><br /> "Now we start building the canonical string for this request. We start with the HTTP method."<br /> canonical := WriteStream on: String new.<br /> canonical<br /> nextPutAll: method asUppercase;<br /> nextPutAll: String cr.<br /><br /> "Sort the headers by name, and append them (or just their values) to the string to be signed."<br /> signHeaders associations sort do:<br /> [:assoc | | header value |<br /> header := assoc key.<br /> value := assoc value.<br /> (header beginsWith: AmazonHeaderPrefix) ifTrue:<br /> [canonical<br /> nextPutAll: header;<br /> nextPutAll: ':'].<br /> canonical<br /> nextPutAll: value;<br /> nextPutAll: String cr].<br /><br /> "The final part of the string to be signed is the URI path.<br /> We strip off the query string, and (if neccessary) tack one of the<br /> special S3 query parameters back on: 'acl', 'torrent', or 'logging'."<br /> canonical nextPutAll: (path copyUpTo: $?).<br /><br /> param := #('acl' 'torrent' 'logging')<br /> detect: [:each | path includesSubString: '?', each]<br /> ifNone: [nil].<br /> param ifNotNil:<br /> [canonical<br /> nextPutAll: '?';<br /> nextPutAll: param].<br /><br /> ^ canonical contents<br /></pre><br />This is quite a long method according to Smalltalk’s standards, but it is a straightforward mapping of the Ruby one explained in the RWS book. Were I to built a real S3 library, I’d probably create something similar to Seaside’s and HV2’s Canvas systems.<br /><br />The most glaring difference between this Smalltalk code and the Ruby one is how the path is handled. S3 requires you to strip the query string (that is, the part after the question mark) and to attach back one of the S3 query parameters (<code>acl</code>, <code>torrent</code>, and <code>logging</code>) in case it’s part of the query string. Richardson and Ruby use a regular expression to identify these parameters. I chose a simpler method on the account that, according to the S3 documentation, each request may have only one of the three special S3 parameters. So I just look for a string such as <code>?acl</code> and, if found, I attach it to the canonical string.<br /><br />Another difference is in how headers are handled. Ruby’s <code>Dictionary</code> class has a <code>#sort_by</code> message that returns a sorted collection over which we can iterate. Smalltalk’s dictionaries don’t have this feature, so I have to send an <code>#associations</code> message to obtain a sequential collections of associations. I iterate over this collection with an unary block that takes a single association as the argument of its <code>#value:</code> message. In this example I split the association into its key and value and put them into two block temporary variables. This is done only for sake of clarity.<br /><br />In the next example in this series, we’ll see the other two messages understood by <code>S3Object</code>: the one we’ll use for signing the request and the one we’ll use for sending the HTTP request.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-1480790910918419621?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com2tag:blogger.com,1999:blog-7905366847339088130.post-43934277933986003022007-09-22T13:06:00.000-07:002008-05-18T11:53:22.838-07:00RESTful Web Services Example 3.19 - SHA1 SigningThe Amazon S3 examples explained in Chapter 3 of the <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRESTful-Web-Services-Leonard-Richardson%2Fdp%2F0596529260%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">RESTful Web Services book</a> have a top-down order: the first examples explain the high-level workings of the system, while the final ones explain details such as request signing etc.<br />Since in this conversion notes I assume you are familiar with Richardson & Ruby’s book, I will start from the bottom and climb my way up to the most high-level examples.<br /><br />For these reason I’ll start with a helper method that is used to sign the HTTP requests: <code>#signString:</code>.<br /><br />If you load the package RWS-gc.10 from the <a href="http://www.squeaksource.com/RWS">RWS repository</a>, you’ll see a new class called <code>S3Object</code>:<br /><pre>Object subclass: #S3Object<br /> instanceVariableNames: 'publicKey privateKey'<br /> classVariableNames: 'AmazonHeaderPrefix InterestingHeaders'<br /> poolDictionaries: ''<br /> category: 'RWS-Examples'<br /></pre><br />This class plays the same role as the Ruby <code>S3::Authorized</code> module. All the Squeak classes in the examples will be subclasses of <code>S3Object</code>.<br /><br /><code>S3Object</code> has two instance variables to hold the public and private keys that Amazon has assigned to you when you signed up for its Amazon Web Services program.<br />It also has two class variables that hold useful constants. These class variables are initialized in the <code>S3Object class>>initialize</code> method:<br /><pre>S3Object class>>initialize<br /> InterestingHeaders := #('content-type' 'content-md5' 'date').<br /> AmazonHeaderPrefix := 'x-amz-'<br /></pre><br />The example I’ll show here is the <code>#signString:</code> method. This method computes a base64 encoding of the HMAC-SHA1 digest of its argument.<br /><pre>signString: aString<br /> | hmac digest |<br /> "Signs a string with the client's secret access key, and encodes the<br /> resulting binary string into plain ASCII with base64.<br /> Code taken from RESTful Web Services. Copyright © 2007 O'Reilly Media, Inc.<br /> All rights reserved. Used with permission."<br /> hmac := SHA1 new hmac.<br /> hmac key: privateKey asByteArray.<br /> digest := hmac digestMessage: aString asByteArray.<br /> ^ Base64MimeConverter mimeEncode: (ReadStream on: digest)<br /></pre><br />The Smalltalk code is similar to the Ruby source, but with a couple of lesser differences.<br />The first is that Squeak’s HMAC class requires instances of the <code>ByteArray</code> class instead of plain strings, due to the multilingual support built into the latest version of Squeak. The second difference is that Squeak’s base64 requires a stream instead of a String or a ByteArray, as per the standard Smalltalk idiom.<br /><br />In the next post, I’ll show another helper method, <code>canonicalStringFor:path:headers:expires:</code>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-4393427793398600302?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-64022762838030337122007-09-21T23:15:00.000-07:002008-06-08T04:25:27.878-07:00#squeak is getting crowdedI usually hang out on <a href="http://wiki.squeak.org/squeak/5888">Squeak’s IRC channel</a> on the Freenode network, to chat with other Squeak developers and to occasionally help the newcomers.<br /><br />Lately, with the <a href="http://news.squeak.org/2007/04/16/google-summer-of-code-squeakn-style/">Summer of Code</a> and the <a href="http://news.squeak.org/2007/09/14/squeak-by-example-now-published/">new Squeak book</a>, there’s been a constant influx of new people in the channel.<br /><br />So today, a little time before dinner, I suddenly realized that there were more than 60 people on the channel:<br /><br /><img src="http://s3.amazonaws.com/blog.corriga.net/IRC.png" alt="#squeak IRC channel"><br /><br />I believe it’s a new record ;-)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-6402276283803033712?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com1tag:blogger.com,1999:blog-7905366847339088130.post-40114387799870671382007-09-21T22:45:00.000-07:002008-05-18T11:48:41.260-07:00RESTful Web Services - Preparing for Chapter 3In a couple of days we’ll move to the examples in Chapter 3 of <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRESTful-Web-Services-Leonard-Richardson%2Fdp%2F0596529260%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">Richardson and Ruby’s book</a>.<br />Before that, we need to add a couple of package to our image. These packages are the Cryptography Team Package and Steve Waring’s HTTP Client, both available on the <a href="http://map.squeak.org/">Squeak Map</a>.<br />We’ll also need either a working account for <a href="http://aws.amazon.com/s3">Amazon’s S3 service</a>, or a working <a href="http://code.whytheluckystiff.net/parkplace">Park Place</a> server.<br /><br /><strong>The Cryptography Team Package</strong><br /><br />The <a href="http://map.squeak.org/package/79e97c64-9254-4115-82e8-c59036c7d661">Cryptography Team Package</a> is one of the three crypto packages available on Squeak Map. It is the product of the work of Squeak’s Cryptography team, headed by Ron Teitelbaum.<br /><br />In order to install it, just open the Squeak Map Package Loader tool, select the package and then select <em>Install</em> from the menu.<br /><br /><strong>Steve Waring’s HTTP Client</strong><br /><br />The other package we’ll need is an HTTP 1.1 Client originally created by Steve Waring’s for Dolphin Smalltalk and ported to Squeak by Brent Vukmer and others. We’ll use it for Chapter 3’s example instead of the CurlPlugin, since the latter doesn’t expose some libCurl APIs that we need.<br /><br />To install this package, use the Squeak Map Package Loader as for the previous package. The name of this package is <em><a href="http://map.squeak.org/package/15f42ec1-e93e-4bcf-ab2b-6746ae9d413f">HTTP Client</a></em>.<br /><br /><strong><em>Edit 10/Oct/2007</em></strong><em>: Unfortunately, this HTTP Client does not support all the features needed for the Squeak versions of the Chapter 3 examples, so it won’t be used at all; CurlPlugin will be used instead. See <a href="http://blogs.corriga.net/giovanni/archives/2007/10/21/restful_web_services_example_316/">this post</a> for more information.</em><br /><br />Once we have installed these packages, we’re ready for Chapter 3’s first example: an Amazon S3 client.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-4011438779987067138?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-59907768941435909042007-09-20T16:25:00.000-07:002008-05-18T11:44:47.968-07:00The Paolo Fresu Angel Quartet - MetamorfosiUno degli ultimi ingressi nella mia collezione è un CD del 1998: <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FMetamorfosi-Paolo-Fresu-Angel-Quartet%2Fdp%2FB000028E6W&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">Metamorfosi</a> del Paolo Fresu Angel Quartet.<br /><br /><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FMetamorfosi-Paolo-Fresu-Angel-Quartet%2Fdp%2FB000028E6W&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325"><img src="http://ec1.images-amazon.com/images/I/41MDXVKYC5L._AA240_.jpg" alt="The Paolo Fresu Angel Quartet - Metamorfosi"></a><br /><br />Al quartetto base, composto dal leader <a href="http://www.paolofresu.it/">Paolo Fresu</a>, dal chitarrista <a href="http://www.nguyen-le.com/">Nguyên Lê</a>, dal contrabassista <a href="http://www.furiodicastri.com/">Furio di Castri</a> e dal batterista <a href="http://www.robertogatto.com/">Roberto Gatto</a>, si unisce per alcune tracce il suono della fisarmonica di <a href="http://www.antonellosalis.com/">Antonello Salis</a>.<br /><br />Il quartetto si è sciolto da tempo, sostituito dal più recente Devil Quartet, ma si è riunito di nuovo quest’estate in occasione della XX edizione del festival <a href="http://www.timeinjazz.it/programma_calendario.php?l=2&id=9&id_cal=74">Time in Jazz</a> di Berchidda, dove ho avuto modo di apprezzarlo.<br /><br />Il disco ha confermato le mie impressioni positive. In particolare mi sono piaciute le tracce <em>The Open Trio</em>, <em>Pong</em> e <em>Don’t Ask</em>, rispettivamente a firma di Fresu, Lê e Gatto.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-5990776894143590904?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-4471799750003035342007-09-19T13:19:00.000-07:002008-05-18T11:40:58.137-07:00Of Trucks and NumbersWhile chatting with some acquaintances today, I found out that not many people are familiar with the concept of <em>truck number</em>.<br /><br />The <strong>truck number</strong> of a software developement project may be informally defined as <em>“the number of team members of your project that have to be run over by a truck in order to have your project going to the dogs”</em>.<br /><br />Obviously, “being run over by a truck” is just a cheeky figure of speech; in reality it may be a developer resigning with no advance notice, or with sudden, serious health problems, etc. So the Truck Number is really one of the measures of risk associated with your project’s personnel.<br /><br />As Cockburn and Williams <a href="http://alistair.cockburn.us/index.php/Costs_and_benefits_of_pair_programming">notice</a>, the worst truck number your project can have is “one”: if, for example, you have only one person with deep knowlegde of a vital subsystem, or only one who knows the in-and-outs of your architecture, your project is in serious trouble if you suddenly lose this person.<br /><br />So, as a measure of risk mitigation, you should strive to have the highest truck number possible. Cockburn and Williams propose Pair Programming as a solution to this problem, but other solutions may be equally valid: daily meetings, better documentation, etc.<br /><br /><strong>Update</strong>: the first definition I wrote wasn’t so clear, so I re-wrote it.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-447179975000303534?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com2tag:blogger.com,1999:blog-7905366847339088130.post-77750789512003878042007-09-17T15:37:00.000-07:002008-05-18T11:37:09.297-07:00Michael Brecker - PilgrimageNei mesi estivi ho comprato un certo numero di CD. Tra questi, uno di quelli che mi ha colpito di più è stato <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FPilgrimage-Michael-Brecker%2Fdp%2FB000OHZJA0&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">Pilgrimage</a>, l’album postumo di <a href="http://www.michaelbrecker.com/">Michael Brecker</a>.<br /><br /><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FPilgrimage-Michael-Brecker%2Fdp%2FB000OHZJA0&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325"><img src="http://ec1.images-amazon.com/images/I/51E0G0kkmAL._AA240_.jpg" alt="Pilgrimage by Michael Brecker"></a><br /><br />Conoscevo questo sassofonista solo di nome, ma dopo aver letto un articolo commemorativo su <a href="http://www.jazzit.it">Jazzit</a> mi sono incuriosito e ho acquistato questo suo ultimo CD, uscito postumo. Sono rimasto molto colpito sia dal sax di Brecker, che dalla bellezza e vitalità delle sue composizioni, eseguite dall’ottimo ensemble riunito da Brecker apposta per questo album.<br /><br />Per una recensione di questo album fatta da qualcuno che se ne intende sul serio di queste cose, vi rimando a <a href="http://www.allaboutjazz.com/php/article.php?id=25722">questo articolo</a> su allaboutjazz.com.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-7775078951200387804?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-48120438613429538412007-09-16T14:51:00.000-07:002008-05-09T02:55:40.984-07:00Why Jazz Programming?Maybe some of my 7 readers (source: Google Analytics) are wondering why this new name. The reason is simple: the old name was fun and cheeky, but it didn’t really describe what I’d like this blog to be. So I chose the new name basing it on what my two main interests currently are.<br /><br />Furthermore, I think there are some analogies between Jazz and Software Engineering, especially Agile Methodologies. The first that come to my mind are:<br /><ul><li>both a jazz player and an agile programmer can do well in solo, but give thier best in a group/team.</li><br /><li>both a jazz player and an agile programmer look at each session as a chance for improvement.</li><br /><li>both a jazz player and an agile programmer strive continuosly for improvement.</li></ul><br />If any of you has other analogies, why not leave them in a comment?<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-4812043861342953841?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com2tag:blogger.com,1999:blog-7905366847339088130.post-39513637127040277992007-08-01T14:34:00.000-07:002008-06-08T04:21:28.091-07:00An HttpView2 Canvas sampleHere's a quick example on how to use the new Canvas system of HV2.<br /><br />First of all, create an new <code>TestView</code> class as a subclass of <code>HVTransientView</code>:<br /><pre>HVTransientView subclass: #TestView<br /> instanceVariableNames: ''<br /> classVariableNames: ''<br /> poolDictionaries: ''<br /> category: 'Test'</pre><br />Then, create a <code>default</code> method as follows:<br /><pre>default<br /> | canvas |<br /> canvas := self canvas.<br /> canvas html:<br /> [canvas head: [canvas title text: 'Test!'].<br /> canvas body:<br /> [canvas h1 text: 'A test of HV2''s new Canvas system'.<br /> canvas p text: 'This is a simple test of the latest HV2 version']].<br /> ^ canvas</pre><br />To start the engine, type the following on a Workspace then DoIt:<br /><pre>TestView startOn: 8080.</pre><br />As soon as the HV2 engine has started, you can point your browser to <code>http://localhost:8080/</code>. Here's a screenshot of what you'll see:<img src="http://s3.amazonaws.com/blog.corriga.net/HV2.png" alt="HV2's new canvas system">.<br /><br />You should also note that you can omit the <code>^ canvas</code> expression in the <code>default</code> method. If you do so, HV2 will retrieve the response from the TestView instance itself.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-3951363712704027799?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-19152328465828960342007-08-01T14:03:00.000-07:002008-05-08T15:57:13.436-07:00HttpView2 status reportIn the past days, I've continued working on <a href="http://wiki.squeak.org/squeak/HttpView2">HttpView2</a>.<br /><br />I've completed support for XHTML 1.1 in class <code>HVXHTMLCanvas</code> . I've also extracted from <code>HVXHTMLCanvas</code> an <code>HVCanvas</code> class that provides support for generic XML documents.<br /><br />On the other hand, I've decided to scrap the current HVPainter system and punt the new one to the next release of HV2.<br /><br />The other big change from HV2's current stable release is related to the HTTP response. In the <a href="http://map.squeak.org/package/a6fcadd6-d2e5-4e74-b17a-520ecb481713">stable release</a> (1.0x), the HTTP response is automatically created from the builder and the user has no control over it. In the current development release, the <code>HttpResponse</code> object has been exposed in the <code>HVTransientView</code> class. The various URL methods may access it, modify the status code, the content type and the contents itself.<br /><br />With these modifications, HV2 may be used (albeit awkwardly) as a simple engine for RESTful web services.<br /><br />As soon as Goran, HV2's mantainer, gets back from his vacations we'll publish the new development version on the <a href="http://map.squeak.org">SqueakMap</a>. Meanwhile, you may find the code on the <a href="http://squeak.krampe.se/httpview/">Monticello repository</a> as version <a href="http://squeak.krampe.se/httpview/HV-gc.132.mcz">HV-gc.132</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-1915232846582896034?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-68502433549504720302007-07-22T16:00:00.000-07:002008-05-08T15:52:32.369-07:00HttpView2's Canvas/Painter systemMost of my work on HV2 involves the creation of a new Canvas/Painter system. This is heavily inspired by Seaside's Canvas system, but has a couple of key differences.<br /><br />Seaside's Canvas system is based around three classes.<br />The first, <code>WACanvas</code>, has the basic infrastructure for producing HTML tags.<br />The second, <code>WAHtmlCanvas</code>, is a <code>WACanvas</code> subclass that adds support for "static" HTML tags (such as <code><p></code>, <code><div></code>, etc.).<br />The last class is the main one you're going to use in Seaside: <code>WARenderCanvas</code>. This is a subclass of <code>WAHtmlCanvas</code> that adds support for the "dynamic" tags of HTML: forms, input fields etc, and is the most integrated with the other parts of Seaside.<br /><br />I've pondered whether to reuse Seaside's Canvas system or not, and in the end I've decided against it: adapting it to HV2 would entail more work than creating a new system from scratch. Also, having another implementation of a Canvas system allows exploring other possible solutions to the problem of creating HTML from Smalltalk code.<br /><br />HV2's Canvas/Painter system is similar to Seaside's Canvas one. There's a <em>canvas</em> class, currently named <code>HVXHTMLCanvas</code>, whose purpose is to produce HTML tags on a stream.<br /><br />The user should use <code>HVXHTMLCanvas</code> directly, but should instead use an <code>HVPainter</code> instance. This <em>painter</em> class delegates most of the work to the canvas, but adds some high-level behavior like autonaming of form fields and automated retrieval of the values of the fields of a POST request.<br />Here's a snippet from a test application I'm building to test HV2's Canvas/Painter system:<br /><pre>painter form withFieldset: <br /> [summary := painter textField<br /> label: 'Summary';<br /> value: model summary.<br /> location := painter painter textField<br /> label: 'Location';<br /> value: model location.<br /> "..."<br /> description := painter painter textField<br /> label: 'Description';<br /> value: model description.<br /> button := painter submitButton value: 'Save'].<br />"..."<br />button ifPressed:<br /> [model summary: summary value.<br /> model location: location value.<br /> model description: description value.<br /> "..."<br /> self redirectToDefault].</pre><br />A nice change from HV2's old Builder system is that the form-autonaming feature of the new Canvas/Painter system may be easily overridden by the user: in the previous system, I could have used<br /><pre>painter textField<br /> label: 'Summary';<br /> name: 'summary';<br /> value: model summary.</pre><br />to create a text input field whose name would have been <code>'summary'</code> instead of the name computed by HV2's Painter.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-6850243354950472030?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-14105356419385377572007-07-22T15:37:00.000-07:002008-05-07T16:22:17.088-07:00Working on HttpView2As you may have noticed, in the past two weeks I've been silent. The reason for this is that I've been working on a couple of Smalltalk projects that have monopolized my attention.<br /><br />One of these projects is <a href="http://wiki.squeak.org/squeak/HttpView2">HttpView2</a>, also known as HV2. HV2 is the web framework behind <a href="http://map.squeak.org">SqueakMap</a>. It's a nice little framework, and is a good complement to <a href="http://www.seaside.st">Seaside</a>.<br /><br />I'm actively involved in the development of the next version of HV2. In particular, I'm building a new Canvas/Painter system to replace HV2's current Builder system. I'll write another post with more details on the new canvas system.<br /><br />I've also been exploring how to restructure HV2 to ease the creation of RESTful web services. I've a couple of ideas in mind: an easier access to the HTTP Response, more specialized View objects for single items and collections, and a few more that I still have to ponder.<br /><br />The new HV2 version hasn't been released yet; you can grab my latest version of it from <a href="http://squeak.krampe.se/httpview/">this (readonly) Monticello repository</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-1410535641938537757?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-68814558721267470362007-07-08T11:28:00.000-07:002008-05-08T15:36:40.513-07:00BirrasIeri con un paio di amici siamo andati a <a href="http://www.birras.tk/">Birras</a>, la prima festa delle birre artigianali sarde.<br /><br /><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/2/22/Il_pozzo_Sartori_-_Miniera_di_Montevecchio.JPG/800px-Il_pozzo_Sartori_-_Miniera_di_Montevecchio.JPG" alt="Pozzo Sartori" /><br /><br />La festa si è svolta in alcuni dei locali del <a href="http://it.wikipedia.org/wiki/Immagine:Il_pozzo_Sartori_-_Miniera_di_Montevecchio.JPG">Pozzo Sartori</a> della miniera di Montevecchio.<br /><br />Erano presenti degli stand per degustare le birre dei sei produttori artigianali al momento presenti in Sardegna. In particolare ho apprezzato la Montevecchio chiara (nota un tempo anche come birra Dolomiti), la <a href="http://www.birradolmen.it/">Dolmen</a> chiara, la <a href="http://www.janasbeer.com/">Janas Beer</a> rossa e la Toccadibò della <a href="http://www.barley.it/">Barley</a>. Non mi ha invece entusiasmato la chiara della Orteip’s Bir, che ho trovato troppo dolce.<br /><br />Purtroppo al mio arrivo la degustazione guidata era già in corso, e non abbiamo voluto trattenerci fino all’inizio della degustazione successiva. In compenso siamo riusciti a seguire la dimostrazione pratica di <em>homebrewing</em> offerta dagli <a href="http://www.hbsardi.it/">HomeBrewers Sardi</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-6881455872126747036?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-9090432993454336922007-07-05T09:14:00.000-07:002008-05-07T16:16:31.988-07:00Smalltalk & Simple DesignOn the <a href="http://tech.groups.yahoo.com/group/extremeprogramming/">Extreme Programming</a> mailing list, Ron Jeffries and others are explaining and defending why Smalltalk allows simpler designs than other languages.<br /><br />Go read the <a href="http://tech.groups.yahoo.com/group/extremeprogramming/message/132736">whole thread</a>, or start from <a href="http://tech.groups.yahoo.com/group/extremeprogramming/message/132786">this message</a>.<p></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-909043299345433692?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-6698352242442913802007-07-03T14:12:00.000-07:002008-05-08T15:36:05.467-07:00RESTful Web Services Example 2.15 - Yahoo! News Search w/ JSONThe final example from Chapter 2 of the <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRESTful-Web-Services-Leonard-Richardson%2Fdp%2F0596529260%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">RESTful Web Services</a> book that I'll be converting to Squeak is another version of the Yahoo! Web Search, this time using JSON and, to spice things up a little, the news search service instead of the web search one.<br /><br />In order to get this example to work, you'll have to install Squeak's JSON package, available from <a href="http://www.squeaksource.com/JSON.html">SqueakSource</a>.<br /><br />Here's the code for the example:<br /><pre>yahooNewsSearch: aString<br /> | baseURI document term json |<br /> "Code taken from RESTful Web Services. Copyright © 2007 O'Reilly Media, Inc.<br /> All rights reserved. Used with permission."<br /> baseURI := 'http://api.search.yahoo.com/NewsSearchService/V1/newsSearch'.<br /> term := aString encodeForHTTP.<br /> json := Curl new getContentsUrl: baseURI , '?appid=restbook&output=json&query=' , term.<br /> document := Json readFrom: json readStream.<br /> ((document at: #ResultSet) at: #Result) do:<br /> [:element |<br /> Transcript<br /> show: (element at: #Title) printString;<br /> cr]</pre><br />There isn't much to say about this example that hasn't been said for <a href="http://blogs.corriga.net/giovanni/archives/2007/6/28/restful_web_services_example_21/">Example 2.1</a>: the document returned from the <code>#getContentsUrl:</code> send is a <a href="http://json.org/">JSON</a> script that is fed to Squeak's JSON parser. The parser returns a nested structure of Dictionaries and Arrays that can be accessed with the standard <code>at:</code> message. The results are then printed to the Transcript, as usual.<br /><br />The code for this method may be found in package RWS-gc.8 in the <a href="http://www.squeaksource.com/RWS">RWS repository</a>.<br /><br />This post concludes the series of examples from Chapter 3 of the RWS book. In the next posts (coming next week or so) I'll show examples from Chapter 3, including a complete implementation of a Squeak client for the <a href="http://www.amazon.com/S3-AWS-home-page-Money/b/ref=sc_fe_l_2/102-2381689-9948939?node=16427261">Amazon S3 service</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-669835224244291380?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com0tag:blogger.com,1999:blog-7905366847339088130.post-12637402345747980292007-07-02T12:13:00.000-07:002008-05-18T11:37:59.408-07:00The Bad Plus - GiveL’ultima entry nella mia collezione di CD è un album del 2004: <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FGive-Bad-Plus%2Fdp%2FB0001AP0PY%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">Give</a> dei <a href="http://www.thebadplus.com/">Bad Plus</a>.<br /><br /><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FGive-Bad-Plus%2Fdp%2FB0001AP0PY%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325"><img src="http://ec1.images-amazon.com/images/I/51QujP01W0L._AA240_.jpg" alt="The Bad Plus - Give" /></a><br /><br />Mi piacerebbe farne una recensione, ma decisamente mi mancano le competenze per scrivere un articolo ben fatto sull’argomento. Mi limiterò quindi a suggerire alcune recensioni trovate in giro per la rete: la <a href="http://www.bbc.co.uk/music/release/5wn8/">prima</a> viene dal sito della BBC, le <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FGive-Bad-Plus%2Fdp%2FB0001AP0PY%2F&tag=httpwwwcorrig-20&linkCode=ur2&camp=1789&creative=9325">altre</a> sono quelle presenti sulla pagina di Amazon del CD. Aggiungo anche una <a href="http://www.glidemagazine.com/articles100.html">intervista</a> pubblicata subito dopo l’uscita di quest’album ed un <a href="http://www.jazzitalia.net/IoCero/BadPlus_Roma.asp">articolo/resoconto</a> di un loro concerto a Roma nel 2005.<br /><br />Personalmente, posso dire che l’album mi è piaciuto molto, e penso proprio che andrò al loro concerto a <a href="http://www.festivalcalagononejazz.it/">Cala Gonone</a> a fine mese.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7905366847339088130-1263740234574798029?l=blog.corriga.net'/></div>gcorriganoreply@blogger.com1