<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>tulipemoutarde.be - Articles</title>
    <description></description>
    <link>http://tulipemoutarde.be</link>
    
      
      <item>
        <title>Build a modern computer course on Coursera</title>
        <description>&lt;p&gt;I don&#39;t remember where I heard about this course but I don&#39;t regret to have enrolled in &lt;a href=&quot;https://www.coursera.org/learn/build-a-computer&quot;&gt;Build a Modern Computer from First Principles: From Nand to Tetris&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It&#39;s a 6 week course on Coursera where you build a computer from the logical NAND gate to a fully working assembler. If you don&#39;t know what a NAND gate is, don&#39;t worry, the course explains in great lengths what they are and how they work.&lt;/p&gt;

&lt;h2&gt;General Impressions&lt;/h2&gt;

&lt;p&gt;The course does not go into the actual physical implementation of the computer, that would probably need another 6 week course, but goes in the other direction and shows how abstractions are built on top of each other.&lt;/p&gt;

&lt;p&gt;Soon enough you end up with a full assembler that outputs binary instructions that can be executed by your CPU.&lt;/p&gt;

&lt;p&gt;I was a little bit disappointed by the way the ALU was introduced. The teachers basically gave the inner working of the ALU without any hint on how it was designed. They convinced the students that it was a simple and beautiful design but never explained how they ended up with it. Once again, I guess it is simply because the course is quit short and they only want to give an overview of the different parts.&lt;/p&gt;

&lt;p&gt;I hold a master degree in Software Engineering but this course was a joy to follow. I guess I&#39;m biased because I knew the concepts before but it is the first time that I grasp the hardware concepts that well. Diving into hardware was a really good trip and makes me want to know more about modern computer architecture.&lt;/p&gt;

&lt;p&gt;I also made me want to dive into lower level languages (Rust, Assembler or even VHDL/Verilog). I&#39;ve always been attracted by the bare metal but have never jumped into it. Now seems to be a good time.&lt;/p&gt;

&lt;h2&gt;Online training&lt;/h2&gt;

&lt;p&gt;This course is the first that I followed online. Coursera has the notion of &quot;end date&quot; which is good for actually completing the course. I registered without thinking about my activities and obligations for the 6 weeks. That&#39;s how I ended up moving (fortunately there is only 8km between the two houses), going on winter holidays with friends and continuing my Mandarin language class. While having a full time job. In retrospect, I  should have waited a little bit before taking the course.&lt;/p&gt;

&lt;p&gt;I paid the 45€ as soon as I started. Not for the certificate (you can access the course for free if you don&#39;t want/need the certificate) but for the commitment.
//I paid for it so I shouldn&#39;t procrastinate and finish this week&#39;s assignment.// is strong incentive to complete the course. Event if 45€ is not a huge amount of money by western standard, it puts value into the mix.&lt;/p&gt;

&lt;p&gt;One of the drawback of online training is the lack of camaraderie between students. You never see the other participants and the online forums on Coursera are basically empty. I don&#39;t know anyone in my entourage that was following the course. Having someone with who I could talk about the concepts and ideas explained in the course would have been great.&lt;/p&gt;

&lt;p&gt;Overall, it was a great experience and I&#39;ll probably enroll for Andrew Ng&#39;s course on machine learning :)&lt;/p&gt;
</description>
        <pubDate>Wed, 08 Mar 2017 16:00:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2017/03/08/build-a-modern-computer-coursera.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2017/03/08/build-a-modern-computer-coursera.html</guid>
      </item>
      
    
      
      <item>
        <title>Android Things</title>
        <description>&lt;p&gt;Google &lt;a href=&quot;https://developers.googleblog.com/2016/12/announcing-googles-new-internet-of-things-platform-with-weave-and-android-things.html&quot;&gt;announced&lt;/a&gt; the developer preview of &lt;em&gt;Android Things&lt;/em&gt;. You have maybe heard about &lt;a href=&quot;https://www.wired.com/2015/05/google-unveils-brillo-answer-smartifying-home/&quot;&gt;Brillo&lt;/a&gt; last year without knowing what it really was. The promise was so vague and abstract that nobody really cared (at least in my circles). With Android Things the promise is clearer. The big title on the project homepage says:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The ease and power of Android
If you can build an app, you can build a device&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;It means that you can leverage your experience and tools to develop products. If you&#39;ve already built android apps you&#39;ll be at home. You can reuse Android Studio, reuse your existing Java code and deploy this to a device with or without a screen.&lt;/p&gt;

&lt;h2&gt;Good enough&lt;/h2&gt;

&lt;p&gt;But was is the difference with the myriad of other products in the market? It&#39;s very easy to boot a Raspberry Pi, write some Python code and control the GPIOs to drive almost everything. The hobbyists already have all the tools they need to tinker and to build something useful.&lt;/p&gt;

&lt;p&gt;When targeting Android Things, a developer can prototype on a board and easily deploy on another one. It seems that Google has certification process for Android Thing. Switching the underlying hardware and reuse the code is already possible with other OS of course but certified boards/microprocessors could greatly improve the experience.&lt;/p&gt;

&lt;p&gt;Unless an hobbyist is a hardcore android developer there is proably not a lot of reason to pick Android Thing for your next project. Setting up the Android SDK, learning Android Studio and all the associated tools (e.g., &lt;a href=&quot;https://developer.android.com/studio/command-line/adb.html&quot;&gt;adb&lt;/a&gt;, &lt;a href=&quot;https://developer.android.com/studio/command-line/logcat.html&quot;&gt;logcat&lt;/a&gt;) is not straightforward if you are doing it for the first time. It&#39;s probably faster to connect a screen, keyboard and mouse on your Pi and start coding.&lt;/p&gt;

&lt;h2&gt;Updates&lt;/h2&gt;

&lt;p&gt;In an industrial setting the requirements are quite different. Processes are in place and you want to leverage battle tested tools. Products can have a very long lifetime, 10-20 years is common and you might need to mass produce them. If the business is not life critical, a Raspberry Pi and your code on it is probably enough. If the product is connected to the internet, you must be &lt;em&gt;much&lt;/em&gt; more careful about what you do and you should have a transparent update mechanism to upgrade the device remotely. Beware that this update mechanism can also be abused to compromise the deployed devices. This really is a nightmare today.&lt;/p&gt;

&lt;p&gt;In the eve of 2017, automatic and transparent updates are vital. This year, we&#39;ve seen a lot of security issues from companies selling IoT devices in the fire and forget style. Consumers don&#39;t realise that their connected lightbulbs, coffee maker and fridge are actually dangerous items that can be used in huge Denial of Service attack. Manufacturers have no incentives to level up their security and update practices.&lt;/p&gt;

&lt;p&gt;Updating the OS running the devices is critical. Software companies are working hard to make this easier for developers and product manufacturers. For example, Canonical builds &lt;a href=&quot;https://developer.ubuntu.com/en/snappy/&quot;&gt;Ubuntu Core&lt;/a&gt; which provices a foundation on which products can be built. This is also where Android Things can shine. It is still vaporware but Google announced that they will provide the infrastructure to remotely update deployed devices. If done well, this could be a huge win as it would remove the burden that is currently imposed to product manufacturers. It also means that a product now relies on Google&#39;s goodwill. If they shut down the service, you&#39;re screwed.&lt;/p&gt;

&lt;h2&gt;Locked OS&lt;/h2&gt;

&lt;p&gt;With Ubuntu Core, you have complete freedom over the OS. You can start a webserver, tune the processes that are started at startup, if you have some linux administration skills, you&#39;ll be right at home. With Android, this is another story, as a user you have much less flexibility. The OS is made for phones/tablet thus it is quite hard for apps to manipulate the system. On a phone, you don&#39;t want third party app to touch the system. When a developer builds its own system, she wants to tune it exactly to fit her need.&lt;/p&gt;

&lt;p&gt;Of course this is more dangerous but an IoT device does not have an app store. The code is loaded into it and then it should run forever (and get updates if it is connected to a network).&lt;/p&gt;

&lt;h2&gt;Bare metal&lt;/h2&gt;

&lt;p&gt;Now of course, all this only applies if:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The device does not need connectivity to the outside world,&lt;/li&gt;
&lt;li&gt;The device does not need a full blown OS. Linux (or any non-specialized OS) brings a huge overhead: you need a more expensive and more power hungry processor and it&#39;s harder to put the electronics in deep sleep mode. If realtime processing is a requirement, an OS might not be the best choice neither.&lt;/li&gt;
&lt;li&gt;The device is life critical. That the software runs &lt;em&gt;on top&lt;/em&gt; of a huge pile of software layers that the developer does not control. In life critical systems you need &lt;em&gt;strong&lt;/em&gt; guarantees that the system handles failure.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;In those situations a lightweight approach might be better. Something bare metal without an OS at all or with a specialized embedded one (e.g., FreeRTOS) will be more power efficient and cheaper to produce.&lt;/p&gt;

&lt;h2&gt;Conclusions&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Android Things is trying to solve the same problem than Ubuntu Core (or other similar effort)&lt;/li&gt;
&lt;li&gt;The first question when developing a product is whether or not you need full blown OS. Considering the following criteria:

&lt;ul&gt;
&lt;li&gt;Cost&lt;/li&gt;
&lt;li&gt;Network connectivity (and thus security)&lt;/li&gt;
&lt;li&gt;Updates (both the application code and the underlying system)&lt;/li&gt;
&lt;li&gt;Realtime constraints&lt;/li&gt;
&lt;li&gt;Lifetime&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;We will see in the following months which hardware partners Google will have and which guarantees they will give with the update mechanism.&lt;/p&gt;

&lt;p&gt;To me, Android Thing would be the killer OS if it was more moldable. There is not a lot of documentation on how to tune the system for a specific need. I guess this will come with time and experience.&lt;/p&gt;

&lt;p&gt;Exciting times.&lt;/p&gt;
</description>
        <pubDate>Thu, 29 Dec 2016 16:00:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2016/12/29/android-things.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2016/12/29/android-things.html</guid>
      </item>
      
    
      
      <item>
        <title>Android Google Study Jams Brussels Episode 2</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/2015/android-codejam-brussels-3.jpg&quot; alt=&quot;audience at the Study Jam&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We are now at week 6 of the google study jam in Brussels. Things have been smooth so far. We are a core group of attendees with different backgrounds and goals, which is always nice.&lt;/p&gt;

&lt;p&gt;This week&#39;s lesson was about &lt;a href=&quot;https://developer.android.com/guide/topics/providers/content-providers.html&quot;&gt;Content Provider&lt;/a&gt; and the URI concepts. Most of the questions were about the utility of this way of doing and we talked quite a lot about the different strategies to load data into an application.&lt;/p&gt;

&lt;p&gt;Here are the links about the tools and libraries people have mentioned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://greendao-orm.com/&quot;&gt;greenDAO&lt;/a&gt;, an ORM which adds a build step into the build process: you write a java program that runs on your computer and that generates your model classes with all the machinery to let you query them.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/emilsjolander/sprinkles&quot;&gt;Sprinkles&lt;/a&gt;, a lightweight library around SQLite. It provides a mapping with your model object throughout Java annotations. It&#39;s quite simple to setup and does not hide the SQL complexity: you write your query by hand and it provides the object mapping. This is the one I currently use for my projects.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/novoda/sqlite-analyzer&quot;&gt;sqlite-analyzer&lt;/a&gt;, written by Novoda, it can generates Java code from sqlite migration/databases. Pretty handy.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/novoda/sqlite-provider&quot;&gt;sqlite-provider&lt;/a&gt;, simplifies the use of sqlite with ContentProvider.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/BoD/android-contentprovider-generator&quot;&gt;android-content-provider-generator&lt;/a&gt;, mentioned by an attendee (hi &lt;a href=&quot;http://twitter.com/IV3O&quot;&gt;Maxime&lt;/a&gt;!), this library generates a ContentProvider from a JSON file that describes your model.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;All in all, the most important lesson is that people should use what they&#39;re comfortable with. Choosing a persistence strategy is something that you should think about. Using external libraries that are far from &lt;em&gt;the android way&lt;/em&gt; of doing also conveys a certain risk (e.g., library maintenance).&lt;/p&gt;

&lt;p&gt;We also had a question about how to do animations and how to read/manipulate SVG objects. This is also a large topic but here are a few pointers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Romain Guy&#39;s &lt;a href=&quot;http://www.curious-creature.com/2013/12/21/android-recipe-4-path-tracing/&quot;&gt;blog post&lt;/a&gt; about path tracing and SVG. The &lt;a href=&quot;https://github.com/romainguy/road-trip&quot;&gt;companion app&lt;/a&gt; is something that you want to clone.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bitbucket.org/paullebeau/androidsvg/overview&quot;&gt;Android SVG&lt;/a&gt; a library to manipulate SVG&lt;/li&gt;
&lt;li&gt;Some blog post about animating the Toolbar while scrolling: &lt;a href=&quot;http://arnaud-camus.fr/material-design-extended-toolbar-and-scrolling/&quot;&gt;Arnaud Camus&lt;/a&gt; and &lt;a href=&quot;https://mzgreen.github.io/2015/02/15/How-to-hideshow-Toolbar-when-list-is-scroling%28part1%29/&quot;&gt;Michał Z&lt;/a&gt;. Both have Github example projects.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;very&lt;/strong&gt; good &lt;a href=&quot;https://speakerdeck.com/dlew/i-can-animate-and-so-can-you&quot;&gt;presentation by Daniel Lew&lt;/a&gt; about all the different options you have to do animations on android. Some stuff are dated but it&#39;s a good start.&lt;/li&gt;
&lt;li&gt;A &lt;a href=&quot;http://android-developers.blogspot.be/2011/05/introducing-viewpropertyanimator.html&quot;&gt;blog post&lt;/a&gt; on the official Android developer blog about ViewPropertyAnimator.&lt;/li&gt;
&lt;li&gt;There&#39;s an app that aggregates a lot of open source library and most of them have demos. It&#39;s quite nice if you need to find something: &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.desarrollodroide.repos&quot;&gt;Libraries for Developers&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Once again, if you&#39;re interested and want to participate, join the &lt;a href=&quot;http://www.meetup.com/gdg-brussels/&quot;&gt;Google Developer Group Brussels&lt;/a&gt; on Meetup!&lt;/p&gt;
</description>
        <pubDate>Wed, 11 Mar 2015 00:00:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2015/03/11/google-study-jam-week-6.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2015/03/11/google-study-jam-week-6.html</guid>
      </item>
      
    
      
      <item>
        <title>Android Google Study Jams Brussels</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/2015/android-codejam-brussels-1.jpg&quot; alt=&quot;audience at the Study Jam&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://developerstudyjams.com/&quot;&gt;Google Developer Study Jams Android Fundamentals&lt;/a&gt; is a worldwide study group organised by Google and Udacity. The principle is quite simple: people follows an online course on Udacity to become Android developers. Events are locally organized weekly so participants can share their problems, ideas and solutions.&lt;/p&gt;

&lt;p&gt;The official website describes it perfectly:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Study Jams are an opportunity for students to receive free, in-person guidance and tutoring on the Udacity course in a fun classroom environment. Study Jam sessions are designed around the Udacity course structure, with a weekly session following each lesson (6 lessons), plus two additional weeks for completing and sharing course final projects. Students are expected to come to the Study Jam sessions having completed that week’s Udacity lesson online, so that the Study Jam time may be used to review key concepts, address questions, and work on individual projects. The live community atmosphere and tutoring is designed to help students achieve deeper learning around the concepts taught in the course.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.meetup.com/gdg-brussels&quot;&gt;Google Developer Group of Brussels&lt;/a&gt; is organising the local event in Belgium in the beautiful working space &lt;a href=&quot;http://co-station.com/wrkcafe/&quot;&gt;Co.Station&lt;/a&gt;, next to the central station.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.meetup.com/gdg-brussels/members/9160265/&quot;&gt;Friedger Müffke&lt;/a&gt; and I are the two tutors for the Brussels local group. We try to expand the content of the online course with some of our experiences. We also try to give the student a feeling of the Android ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015/android-codejam-brussels-2.jpg&quot; alt=&quot;audience at the Study Jam&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The Android fondamental course does not use any external libraries. Even for HTTP calls. Instead they ask the students to copy/paste a huge gist containing the code doing the call. I thought that it would have been nice to show the students how to include an external library.&lt;/p&gt;

&lt;p&gt;We started to follow that path and we talked quite a lot about libraries that I find useful. Here are some of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://square.github.io/okhttp/&quot;&gt;OkHTTP&lt;/a&gt;, HTTP calls should be easy.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.google.com/p/google-gson/&quot;&gt;GSON&lt;/a&gt;, JSON manipulation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://square.github.io/retrofit/&quot;&gt;Retrofit&lt;/a&gt;, Ideal if you want to interact with a REST+JSON webservice. Beware that it can feel a little bit &lt;em&gt;magic&lt;/em&gt;, it&#39;s hard to know what&#39;s going on. It relies on OkHTTP and GSON to do its job.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/greenrobot/EventBus&quot;&gt;EventBus&lt;/a&gt;, an EventBus for your application. It lets you send event throughout your application.
*&lt;a href=&quot;https://square.github.io/otto/&quot;&gt;Otto&lt;/a&gt;, basically the same as EventBus. Try both and keep the one you prefer.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JakeWharton/timber&quot;&gt;Timber&lt;/a&gt;, small librarie that makes it easier to deal with logs.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You can find all those library in the &lt;a href=&quot;https://bintray.com/bintray/jcenter&quot;&gt;jcenter maven repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Many of those libraries are edited by Square. Check their &lt;a href=&quot;https://square.github.io/&quot;&gt;open source listing&lt;/a&gt; for more goodness.&lt;/p&gt;

&lt;p&gt;Another small tool that we covered (but that I haven&#39;t tested in real life yet) is &lt;a href=&quot;https://github.com/orfjackal/retrolambda&quot;&gt;Retrolambda&lt;/a&gt;. You integrate it into your build chain and it lets you write lambda expressions with java 7. Nobody knows when (or even if) Java 8 will be available on android, so this tool can come handy if you really want to use those lambdas.&lt;/p&gt;

&lt;p&gt;We also mentioned &lt;a href=&quot;https://www.genymotion.com&quot;&gt;Genymotion&lt;/a&gt;, a fast android emulator based on VirtualBox.&lt;/p&gt;

&lt;p&gt;Someone has a question about &lt;code&gt;Context&lt;/code&gt; last week. &lt;a href=&quot;http://possiblemobile.com/2013/06/context/&quot;&gt;This article&lt;/a&gt; is quite good to grasp the differences between the different available contexts.&lt;/p&gt;

&lt;p&gt;Last but not least, we talked about &lt;a href=&quot;http://androidweekly.net/&quot;&gt;Android Weekly&lt;/a&gt;, a very nice newsletter that collects all the news from the Android ecosytem. It is a great way to discover new libraries and tools.&lt;/p&gt;

&lt;p&gt;Thanks a lot to &lt;a href=&quot;https://twitter.com/DianeLanterman&quot;&gt;Anne Collet&lt;/a&gt; from &lt;a href=&quot;http://www.lewagon.org/brussels&quot;&gt;Le Wagon Brussels&lt;/a&gt; to host us in Co.Station.&lt;/p&gt;

&lt;p&gt;If you&#39;re interested and want to participate, join the &lt;a href=&quot;http://www.meetup.com/gdg-brussels/&quot;&gt;Google Developer Group Brussels&lt;/a&gt; on Meetup!&lt;/p&gt;
</description>
        <pubDate>Wed, 25 Feb 2015 12:00:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2015/02/25/google-study-jam-week2-notes.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2015/02/25/google-study-jam-week2-notes.html</guid>
      </item>
      
    
      
      <item>
        <title>Dependency injection with Dagger</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Dependency_injection&quot;&gt;Dependency injection&lt;/a&gt; (or DI) is quite a big topic in object oriented design. It can be quite hard to grasp for junior developers but it is a pattern that should be in your toolbox.&lt;/p&gt;

&lt;p&gt;This small blog post will briefly show you how to use &lt;a href=&quot;https://square.github.io/dagger/&quot;&gt;Dagger&lt;/a&gt;, a common DI framework in the Android world.&lt;/p&gt;

&lt;h2&gt;Android Example&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/JakeWharton/u2020&quot;&gt;Jake Wharton&#39;s u2020&lt;/a&gt; is an Android app showcasing the use of dependency injection using Dagger.&lt;/p&gt;

&lt;p&gt;The app is full of great tips but taken together, they can be a bit overwhelming if you just want to learn the framework. The injection depends on the variant of the app: the &lt;code&gt;debug&lt;/code&gt; version have a completely different layout that includes a debug drawer. It is a great learning app but you probably don&#39;t want to deal with all that complexity when you just want to learn how Dagger works.&lt;/p&gt;

&lt;h2&gt;Our app: Inject an Webview url at runtime&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015/dagger-screen.jpg&quot; alt=&quot;The Webview displaying Bing and Yahoo search&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To illustrate the DI, we will change the url displayed by a webview at runtime. Change &lt;em&gt;url&lt;/em&gt; by &lt;em&gt;endpoint&lt;/em&gt; and &lt;em&gt;webview&lt;/em&gt; by &lt;em&gt;API&lt;/em&gt; and you&#39;ll have a very common scheme in Mobile apps. This can be useful if you want to switch between your testing and staging servers to test that everything is working.&lt;/p&gt;

&lt;p&gt;In this post, we&#39;ll see how we can dynamically change the endpoint our app is talking to. Beware that it could become dangerous in a real application: dynamically changing the endpoint at runtime is not a good idea if you have a session on the server or if you use a local database to synchronise data with the backend. You can easily meangle all your data and send inconsistent requests to the server.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/fstephany/dagger-example&quot;&gt;Our app&lt;/a&gt; will be very simple: a webview and radio buttons. The webview will display &lt;em&gt;Yahoo&lt;/em&gt; or &lt;em&gt;Bing&lt;/em&gt; according to the currently selected radio button.&lt;/p&gt;

&lt;h2&gt;Annotations&lt;/h2&gt;

&lt;p&gt;This app shows three very simple annotations of Dagger: &lt;code&gt;@Inject&lt;/code&gt;, &lt;code&gt;@Provides&lt;/code&gt; and &lt;code&gt;@Module&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;@Inject&lt;/code&gt; (on a field)&lt;/h3&gt;

&lt;p&gt;This annotation shows that you want to inject a value in this field. We will see later when values are injected.&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;@Provides&lt;/code&gt; (on a method)&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;@Provides&lt;/code&gt; shows that the annotated method can provide a value. Provider methods are part of a Module.&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;@Module&lt;/code&gt; (on a class)&lt;/h3&gt;

&lt;p&gt;A module is the entry point of the injection. We will build our object graph with a Set of modules. We then inject objects that have injectable fields into this object graph to get them populated.&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;p&gt;The app has two modules, &lt;code&gt;BingEndPointModule&lt;/code&gt; and &lt;code&gt;YahooEndPointModule&lt;/code&gt;. Those are injected at runtime when you choose Bing and Yahoo in the UI.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@Module(injects = { MainActivity.class })
public class BingEndpointModule {
    @Provides
    Endpoint provideEndpoint() {
      return new Endpoint(&quot;http://bing.com/&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the &lt;code&gt;@Module&lt;/code&gt; annotation, you can notice that you have to provide where this module will be injected. Dagger verify at compile time that you haven&#39;t messed up.&lt;/p&gt;

&lt;p&gt;In the main activity, we wrote a simple method to switch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private void updateModule(Object module) {
    objectGraph = ObjectGraph.create(module);
    objectGraph.inject(this);
    refreshWebview();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt; Which is called when we change the selection of the RadioGroup:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private void selectBing() {
    updateModule(new BingEndpointModule());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you see, there is nothing really fancy in this code. I wouldn&#39;t use Dagger for such a simple case in practice but keeping it small helps to identify the key parts of Dagger.&lt;/p&gt;

&lt;p&gt;You can get the whole source code on the &lt;a href=&quot;https://github.com/fstephany/dagger-example&quot;&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Closing&lt;/h2&gt;

&lt;p&gt;That was short. Once again, you should clone &lt;a href=&quot;https://github.com/JakeWharton/u2020&quot;&gt;u2020&lt;/a&gt; and study its source code. It shows quite a lot in a condensed app.&lt;/p&gt;
</description>
        <pubDate>Tue, 13 Jan 2015 17:48:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2015/01/13/dependency-injection-dagger.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2015/01/13/dependency-injection-dagger.html</guid>
      </item>
      
    
      
      <item>
        <title>Some Seaside Refactoring</title>
        <description>During a code review, I stumbled upon this. It is the callback of a submit button in a Seaside app:

    RegisterComponent&gt;&gt; saveAction
	| errorMessage |
	errorMessage := self getError.
	errorMessage ifNil: [
		(password = confirmPassword)
			ifTrue: [
				user password:  (ASHasher defaultHasher new hashString: password).
				(user email isEmail) ifTrue: [
					(CCUser issetUser: user email)
						ifTrue: [
							self session addErrorFlash: &#39;Email already used&#39; ]
						ifFalse: [
							self user save.
							Log message: &#39;Register new user: #&#39;, user id asString, &#39; - &#39;, user email.
							self createOwnCompany.
							self session user: user.
							self session moveToWithBC: CCRepositoriesComponent new.
							CCMailSender sendRegisterEmailToUser: user ]]
					ifFalse: [ self session addErrorFlash: &#39;Email invalid&#39; ]
			] ifFalse: [
				self session addErrorFlash: &#39;Password and confirm password should be the same.&#39; ]]
	ifNotNil: [ self session addErrorFlash: errorMessage ]

Don&#39;t panic, we&#39;ll gladly clean this.

![Refactor all the things](/images/2014/refactor-all-the-things.jpg)

At first look, this method is typically way to long for a smalltalk method. I tolerate long methods in very specific cases like `WAComponent&gt;renderContentOn:`; HTML is quite verbose once you add classes and nested divs. It&#39;s easy to get fat rendering methods.

Another thing that looks bad is the identation level. When you see such a level of indentation in the middle of your code, you probably have a problem somewhere.

The two previous points were more something that comes more from gut feeling than rational thinking but I trust my gut when it&#39;s telling me something.

Let&#39;s go deeper. The method seems to do way too much: flash messages handling, kind of user validation, aftersave callback (`createOwnCompany`), logging, UI redirection and email sending. Pfoui!

Let&#39;s start by the beginning:

    RegisterComponent&gt;&gt; saveAction
		| errorMessage |
		errorMessage := self getError.
		errorMessage ifNil: [ ... ]
		ifNotNil: [ self session addErrorFlash: errorMessage ]

Mmmm. Does it mean that errors could have popped ud elsewhere? To me, it&#39;s not the callback responsiblity to check this. Or it should do it *explicitly* by calling a well named method. In this case, the reader is left wondering why the hell the behavior is dependent on the previous errors. It means that the state of the component has been modified elsewhere. Anyway, we can always put some makeup in top of this but there&#39;s a sign that we might need a solid refactoring of the whole class.

The line `errorMessage := self getError.` is quite confusing. The variable name `errorMessage` makes us think that we have a string while the `self getError` seems to return a kind of `Error` object.

Without knowing more, I would refactor that bit of code to:

    RegisterComponent&gt;&gt; saveAction
		self getError ifNotNil: [:errorMessage |
        	^self session addErrorFlash: errorMessage]
        ...

It saves us a temporary variable and one indentation level. We can know proceed and go the inner part of the method. This is what it looked like:

    (password = confirmPassword)
			ifTrue: [
				user password:  (ASHasher defaultHasher new hashString: password).
				(user email isEmail) ifTrue: [
					(CCUser issetUser: user email)
						ifTrue: [
							self session addErrorFlash: &#39;Email already used&#39; ]
						ifFalse: [
							self user save.
							Log message: &#39;Register new user: #&#39;, user id asString, &#39; - &#39;, user email.
							self createOwnCompany.
							self session user: user.
							self session moveToWithBC: CCRepositoriesComponent new.
							CCMailSender sendRegisterEmailToUser: user ]]
					ifFalse: [ self session addErrorFlash: &#39;Email invalid&#39; ]
			] ifFalse: [
				self session addErrorFlash: &#39;Password and confirm password should be the same.&#39; ]

We could do the same as the previous point and replace the first condition with the following, saving a big nested block:

    (password = confirmPassword) ifFalse: [
    	^self session addErrorFlash: &#39;Password and confirm password should be the same.&#39;
    ]
    &quot;the remaining code&quot;.

As we return directly from the block, we don&#39;t need an `else` clause. But refactoring this would be using lipstick on a pig. The code needs more profound changes (e.g., why the hell the component should know how to hash a password). The whole logic should not be handled by the component but by the `User` class itself or, even better, something like a `UserRegistrationService`. One of the benefit of doing this is to have an isolated entity that you can test without involving the UI. It will also be useful if you want to develop an API.

This is how I would refactor the code. Note that this is still not perfect but it&#39;s already a lot better. The snippet exhibits some architectural choices that we could discuss but it&#39;s a topic for another post (e.g., sending an error when validation fails):

    registration := (UserRegistration on: user)
		password: password
        passwordConfirmation: passwordConfirmation.

    [user := registration register] on: ValidationError do: [:error |
        	^self session addErrorFlash: error printString]
    self session user: user.
	self session moveToWithBC: CCRepositoriesComponent new.

So now, the `UserRegistration` class is responsible for:

* Validating that the password and password confirmation match.
* The user email is not already taken by another user (by the way the method `issetUser:` is terrible; it&#39;s not camelCased and does not convey what it is testing)
* Hashing the user password. By the way, the current method is missing salt. This need to be changed.
* Saving the user in database
* Logging the user creation
* Creating a default company for this user
* Send the registration email

Overall, we have the following:

        RegisterComponent&gt;&gt; saveAction
			self getError ifNotNil: [:errorMessage |
        		^self session addErrorFlash: errorMessage].

	        registration := (UserRegistration on: user)
				password: password
	        	passwordConfirmation: passwordConfirmation.

			[user := registration register] on: ValidationError do: [:error |
        		^self session addErrorFlash: error printString].

			self session user: user.
			self session moveToWithBC: CCRepositoriesComponent new.

As we said, there&#39;s more to do but it would involve a bigger refactoring of the class. The important thing is to start, this small cleaning is the first step of the process.

In real life, when seeing a piece of source code like this, I don&#39;t necessarily refactor from top to bottom. I have a more organic workflow where my gut feeling tells me what to do.

I don&#39;t know if code style is something that you learn in school, if it&#39;s innate or if it comes with (a lot of) practice but as a programmer, you need to care about the code you&#39;re producing.

Feedback is welcome, [ping me](http://twitter.com/fstephany) on Twitter if the subject interests you.
</description>
        <pubDate>Wed, 02 Jul 2014 21:56:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2014/07/02/refactoring-seaside.mdown</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2014/07/02/refactoring-seaside.mdown</guid>
      </item>
      
    
      
      <item>
        <title>Pharo packages to know</title>
        <description>&lt;p&gt;Starting to work with Pharo Smalltalk these days is quite a non trivial process. Non-smalltalkers are already lost with the language and the environment. On top of that, they must learn tools and library names that are quite specific to Smalltalk or Pharo.&lt;/p&gt;

&lt;p&gt;Here&#39;s my short list of project name to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Morphic&lt;/strong&gt;: The GUI layer of Pharo. It is not really&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://spec.st/&quot;&gt;Spec&lt;/a&gt;&lt;/strong&gt;: A framework to describe user interfaces. It powers quite a few tools in the Pharo environment. At the moment, it uses Morphic as the backend but it should eventually be backend-agnostic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nautilus&lt;/strong&gt;: The code browser. It&#39;s the primary tool to interact with your code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://zn.stfx.eu/zn/index.html&quot;&gt;Zinc&lt;/a&gt;&lt;/strong&gt;: an HTTP client and server library integrated into Pharo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monticello&lt;/strong&gt;: A source control (think Git but specialized for Smalltalk packages) dedicated to Smalltalk. It outputs &lt;code&gt;.mcz&lt;/code&gt; packages that contain the whole source code for a given version.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gofer&lt;/strong&gt;: A tool helping you to grab Monticello packages. It can be used to script the loading of Monticello Package&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metacello&lt;/strong&gt;: A tool to express the dependencies for your project. Think Bundler, Maven or Pip for Smalltalk. You usually grab the MetacelloConfiguration of a package with Gofer and then ask the configuration to load the project.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versionner&lt;/strong&gt;: A Graphical tool to help you create your Metacello configurations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Athens&lt;/strong&gt;: A new vectorial backend for Pharo. It will eventually replace the current rendering engine. It is based on Cairo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NativeBoost&lt;/strong&gt;: A library to call C libraries from Pharo. Other projects exist (e.g., FFI, Mars) but NativeBoost (NB) is probably the way to go for new projects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Filetree&lt;/strong&gt;: Filetree lets you write Monticello packages into the regular filesystem. If you want to use git, this is the way to go. There are efforts to use git natively with the tools available in the image (e.g., gitfiletree).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;There a many more but those are probably the core packages that a newcomer will hear about when (s)he starts to play with Pharo.&lt;/p&gt;

&lt;p&gt;I&#39;ve linked some of the projects to their homepage but all the others should be covered by &lt;a href=&quot;https://ci.inria.fr/pharo-contribution/job/DeepIntoPharo/lastSuccessfulBuild/artifact/tmp/&quot;&gt;Deep into Pharo&lt;/a&gt; and &lt;a href=&quot;https://ci.inria.fr/pharo-contribution/job/PharoForTheEnterprise/lastSuccessfulBuild/artifact/&quot;&gt;Pharo For the Entreprise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ping me on &lt;a href=&quot;http://twitter.com/fstephany&quot;&gt;Twitter&lt;/a&gt; if I forgot an important package that does not have a meaningful name.&lt;/p&gt;
</description>
        <pubDate>Mon, 02 Jun 2014 02:08:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2014/06/02/pharo-package-to-know.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2014/06/02/pharo-package-to-know.html</guid>
      </item>
      
    
      
      <item>
        <title>iOS legacy code</title>
        <description>&lt;p&gt;Confession: I &lt;strong&gt;love&lt;/strong&gt; dealing with legacy code. I love to curse when reading source code. I love to refactor all those defects that make my eyes bleed.&lt;/p&gt;

&lt;p&gt;In this post, I describe some smells that I often see when taking over or assessing iOS apps.&lt;/p&gt;

&lt;h2&gt;Conclusions&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Code duplication&lt;/strong&gt;. Copy/Pasting a snippet of code from time to time is OK. Copying the same 60 lines in almost all your &lt;code&gt;ViewController&lt;/code&gt; is definitely bad.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Naming convention&lt;/strong&gt;. The use of singular and plural should not be incidental. It brings clarity to your code. Do not start methods name with a capital letter. Use meaningful variable names. Objective-C is verbose &lt;em&gt;because&lt;/em&gt; people express everything in the naming. Don&#39;t break that.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Indentation and whitespace&lt;/strong&gt;. This is at a microscopic level but you should have a consistent coding style. Always pout your opening brackets at the same place, separate your methods definition by one empty line, etc. Those are simple rules but helps to read your source code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Magic constants&lt;/strong&gt;. The return codes are obscure. If you really want to identify errors with error codes, at least create constants so the reader knows what you mean by &lt;em&gt;Error 42&lt;/em&gt;. &lt;code&gt;NSError&lt;/code&gt; is made for this, do not go with your own solution that works half of the time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Modeling&lt;/strong&gt;. Use your custom ORM only in specific cases. Apple provides a good framework that everybody knows and uses: &lt;em&gt;CoreData&lt;/em&gt;. It is a huge and complex piece of software but it can handle almost every situation and is battle tested.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code clarity&lt;/strong&gt;. You should always express the same concept with the same code structure. For example a screen showing a note should have a variable called &lt;code&gt;currentNote&lt;/code&gt;representing the note currently displayed. And not an array containing all the notes with another variable telling the index of the current note in the array. It confuses the reader. If you go that way, you must explain the reason in concise comments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Properties vs Instance variable&lt;/strong&gt;. Use one or the other but do not mix them without any reasons. As a side notes, accessors/mutators are generated for you. Do not replicate your Java habits in here.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Objective-C&lt;/strong&gt;. Obj-C has improved over time to make it easier to read, easier to write. The new features tend to make it easier to remove the boilerplate of the code. (&lt;code&gt;@&lt;/code&gt; notation, auto-synthesize properties, etc). Know the language you are using.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom UI&lt;/strong&gt;. Two simple rules :

&lt;ul&gt;
&lt;li&gt;Use the &lt;code&gt;appearance proxies&lt;/code&gt; if you want to the same component all over the app.&lt;/li&gt;
&lt;li&gt;Do not use magic constants for sizes and frames. If Apple changes the screen for the iPhone 6, you&#39;ll get screwed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Certificate&lt;/strong&gt;. Always use the signing certificate of your clients. If they don&#39;t know how to create it, generate it &lt;em&gt;with&lt;/em&gt; them, not &lt;em&gt;for&lt;/em&gt; them. The certificates control everything for publishing apps. If your clients are not happy with you, you should let them go.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Arc&lt;/strong&gt;. Use arc. You do not want to manage your memory by hand. The cases where the compiler gets it wrong are incredibly rare.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Post-mortem&lt;/h2&gt;

&lt;p&gt;Those notes are quite broken and do not follow any logic, I&#39;ve copy-pasted some snippets from some projects I&#39;ve helped to assess.&lt;/p&gt;

&lt;p&gt;I suck at editing, do not expect this blog post to be a complete, clean and accurate report of defects in iOS Code. It covers stuff at the code snippet level; there is more to tell about architecture of apps but the subject is too broad for this rant.&lt;/p&gt;

&lt;h3&gt;UIViewController &amp;amp; UI Tuning&lt;/h3&gt;

&lt;p&gt;Almost every single ViewController starts with the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [self loadApparence];

}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What&#39;s wrong with this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first method is useless. Why keep the cruft if you don&#39;t need it.&lt;/li&gt;
&lt;li&gt;Whitespace boy. One empty line between the methods is all I ask.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Ok. Let&#39;s have a look at &lt;code&gt;loadApparence&lt;/code&gt;. I&#39;m gonna split it to make it easier to read.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;- (void) loadApparence
{
    [[self navigationController] setNavigationBarHidden:NO];

    [self.navigationController.navigationBar setTintColor:[UIColor grayColor]];
    if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)])
    {
        [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@&quot;bg_Navigation_Header.png&quot;] forBarMetrics:UIBarMetricsDefault];
    }
    if ([self.navigationController.navigationBar respondsToSelector:@selector(setTitleTextAttributes:)])
    {
        [self.navigationController.navigationBar setTitleTextAttributes:
         [NSDictionary dictionaryWithObjectsAndKeys:[UIColor navigationTitleTextColor],
          UITextAttributeTextColor,
          [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0],
          UITextAttributeTextShadowColor,
          [NSValue valueWithUIOffset:UIOffsetMake(0, 0)],
          UITextAttributeTextShadowOffset,
          [UIFont fontWithName:@&quot;Klavika-Medium&quot; size:22.0],
          UITextAttributeFont,
          nil]];
    }
    …
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Mmmm. At first sight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;- (void) loadApparence&lt;/code&gt;. French developer spotted.&lt;/li&gt;
&lt;li&gt;I know that it&#39;s sometimes hard in Objective-C/Cocoa but the 80 caracter wide rules should be enforced when possible. Not everyone codes fullscreen on a 27&#39;&#39; monitor.&lt;/li&gt;
&lt;li&gt;I always worry when I see &lt;code&gt;respondsToSelector:&lt;/code&gt;. It usually means that the developer has missed some object-oriented polymorphism. In this case it looks like he is checking that the navigation bar has all the capabilities it is supposed to have. Maybe because of API changes in the UINavigationController? A comment would have been welcome.&lt;/li&gt;
&lt;li&gt;Changing the navigation bar background. I bet this happens everywhere in the project. BINGO, after a quick search, the line &lt;code&gt;[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@&quot;bg_Navigation_Header.png&quot;] forBarMetrics:UIBarMetricsDefault];&lt;/code&gt; appears 22 times in the project.  This code has been copy/pasted everywhere. Why not use the &lt;em&gt;appearance proxy&lt;/em&gt;  of externalise this code if you compile under iOS 5 (is there anyone still using iOS &amp;lt; 5 in 2013?)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;dictionaryWithObjectsAndKeys:&lt;/code&gt;? Really? The &lt;code&gt;@&lt;/code&gt; notation should be used everywhere.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  UIButton *buttonSave = [UIButton buttonWithType:UIButtonTypeCustom];
  [buttonSave setBackgroundImage:[UIImage imageNamed:@&quot;btn_blue_normal.png&quot;] forState:UIControlStateNormal];
  [buttonSave setBackgroundImage:[UIImage imageNamed:@&quot;btn_blue_pressed.png&quot;] forState:UIControlEventTouchUpInside];
  [buttonSave setBackgroundImage:[UIImage imageNamed:@&quot;btn_blue_pressed.png&quot;] forState:UIControlStateHighlighted];
  [buttonSave.titleLabel setFont:[UIFont fontWithName: @&quot;Custom-Medium&quot; size:16]];
  [buttonSave setFrame:CGRectMake(0, 0, 44, 31)];
  [buttonSave setTitleEdgeInsets:UIEdgeInsetsMake(8, 0, 0, 0)];
  [buttonSave setHighlighted:NO];
  [buttonSave addTarget:self action:@selector(save:) forControlEvents:UIControlEventTouchUpInside];
  [buttonSave setTitle:myFunkyLocalizeFunction(@&quot;Save&quot;) forState:UIControlStateNormal];
  UIBarButtonItem *saveButton = [[[UIBarButtonItem alloc] initWithCustomView:buttonSave] autorelease];
  self.navigationItem.rightBarButtonItem = saveButton;

  UIButton *buttonCancel = [UIButton buttonWithType:UIButtonTypeCustom];
  [buttonCancel setBackgroundImage:[UIImage imageNamed:@&quot;btn_grey_normal.png&quot;] forState:UIControlStateNormal];
  [buttonCancel setBackgroundImage:[UIImage imageNamed:@&quot;btn_grey_pressed.png&quot;] forState:UIControlEventTouchUpInside];
  [buttonCancel setBackgroundImage:[UIImage imageNamed:@&quot;btn_grey_pressed.png&quot;] forState:UIControlStateHighlighted];
  [buttonCancel.titleLabel setFont:[UIFont fontWithName: @&quot;Custom-Medium&quot; size:16]];
  [buttonCancel setFrame:CGRectMake(0, 0, 60, 31)];
  [buttonCancel setTitleEdgeInsets:UIEdgeInsetsMake(8, 0, 0, 0)];
  [buttonCancel setHighlighted:NO];
  [buttonCancel addTarget:self action:@selector(cancel:) forControlEvents:UIControlEventTouchUpInside];
  [buttonCancel setTitle:myFunkyLocalizeFunction(@&quot;Cancel&quot;) forState:UIControlStateNormal];
  [buttonCancel setTitleColor:[UIColor colorWithRed:0.5 green:0.52 blue:0.57 alpha:1] forState:UIControlStateNormal] ;
  UIBarButtonItem *cancelBtBar = [[[UIBarButtonItem alloc] initWithCustomView:buttonCancel]autorelease];
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This snippet has been copy/pasted everywhere the save and cancel button are neded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[UIFont fontWithName: @&quot;Custom-Medium&quot; size:16]]&lt;/code&gt; is everywhere.&lt;/li&gt;
&lt;li&gt;The experienced eye will have noticed that &lt;code&gt;[buttonSave setBackgroundImage:[UIImage imageNamed:@&quot;btn_blue_pressed.png&quot;] forState:UIControlEventTouchUpInside];&lt;/code&gt; will generate the warning &lt;em&gt;&quot;Implicit conversion from enumeration type &#39;enum UIControlEvents&#39; to different enumeration type &#39;UIControlState&#39; (aka &#39;enum UIControlState&#39;)&quot;&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Return codes&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;if(([description isEqualToString:@&quot;DELETE_NOTE&quot;])&amp;amp;&amp;amp;([targetType isEqualToString:@&quot;FOLDER&quot;]))
{
    XXXFolder *folder = [[XXXFolder alloc] initWithDictionnary:[adic objectForKey:@&quot;target&quot;]];
    XXXNote *note = [[XXXNote alloc] initWithDictionnary:[[adic objectForKey:@&quot;target&quot;] objectForKey:@&quot;note&quot;]];
    if((folder)&amp;amp;&amp;amp;(note))
    {
        self.objects = [[[NSDictionary alloc] initWithObjects:@[folder, note] forKeys:@[@&quot;folder&quot;, @&quot;note&quot;]] autorelease];
        return 20;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Does anybody knows what the return code 20 means? I do not have a clue. The other parts of the &lt;code&gt;if&lt;/code&gt; (and there are 13 consecutive &lt;code&gt;if&lt;/code&gt; clauses) return a different code.&lt;/p&gt;

&lt;p&gt;That line mixing two syntax is particularly cool. The array is declared the new way while the dictionary is declared the old school way (it was a one liner, I idented it to make it more readable):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;self.objects = [[[NSDictionary alloc]
    initWithObjects:@[folder, note]
            forKeys:@[@&quot;folder&quot;, @&quot;note&quot;]] autorelease];`
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;while they could have used:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;self.objects = @{ @&quot;folder&quot;:folder,
                  @&quot;note&quot;:note };
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or even:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;self.objects = NSDictionaryOfVariableBindings(folder, note);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Mixing Properties and instance variables&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;@interface XXXNoteDetailViewController : UIViewController &amp;lt;UITextFieldDelegate, UITextViewDelegate&amp;gt;
{
    SoundEffect *player;
    IBOutlet UIButton *addTaskButton;
    IBOutlet UIButton *connectToFolderButton;
    IBOutlet UIButton *shareNoteButton;
    IBOutlet UIButton *editTaskButton;
    IBOutlet UIButton *deleteNoteButton;
    IBOutlet UIView *controlBarView;
    IBOutlet UIButton *commentsButton;
}

@property (retain, nonatomic) IBOutlet UIImageView *photoImageView;
// And 21 more properties for UI elements.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pick one approach and stick with it. Don&#39;t mix them without reason.&lt;/p&gt;

&lt;h3&gt;Meta programming&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    [self performSelector:@selector(loadNote)];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&#39;m still wondering why the &lt;code&gt;performSelector:&lt;/code&gt; is there. Isn&#39;t&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;- (void)viewDidLoad {
    [super viewDidLoad];
    [self loadNote];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;easier to read?&lt;/p&gt;

&lt;h3&gt;Properties&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;XXXNoteDetailViewController&lt;/code&gt; displays a note. Why does it need to keep a whole &lt;code&gt;notes&lt;/code&gt; array and a property called &lt;code&gt;ind&lt;/code&gt; to hold the index of the note to display? &lt;code&gt;notes&lt;/code&gt; is never used. Except to retrieve the
note to display. Many methods start with: &lt;code&gt;Note *note = [notes objectAtIndex:ind];&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Oh oh no, it&#39;s used when the user deletes the currently displayed note:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[notes removeObjectAtIndex:ind];
if ([notes count] &amp;gt; 0) {
    ind--;
    if (ind &amp;gt; 0 &amp;amp;&amp;amp; ind &amp;lt; [notes count]) {
        [notes objectAtIndex:ind];
    } else {
        ind = 0;
        [notes objectAtIndex:0];
    }
} else {
    [[self navigationController] popViewControllerAnimated:YES];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ouch.&lt;/p&gt;

&lt;h3&gt;Java-ite&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;@property (nonatomic, retain, setter = setContent:, getter = getContent) NSString *content;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Accessors are generated for properties, do not try to make it look like Java.&lt;/p&gt;

&lt;h3&gt;Ifs&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;if(self.currentNote)
{
    if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath])
        NSLog(@&quot;fichier inexistant : %@&quot;, fullPath);
   // [[SoundManager getInstance] playSoundFromPath:fullPath];


    if([player loadContentsOfFile:fullPath])
    {
        NSLog(@&quot;playing %@&quot;, fullPath);
        [player play];
    }
    else{
        NSLog(@&quot;impossible de lire le fichier : %@&quot;, fullPath);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This if clause probably violates all the good practices you&#39;ve ever learned for conditions.&lt;/p&gt;

&lt;h3&gt;Whitespace&lt;/h3&gt;

&lt;p&gt;Method declaration identation is quite funky (white space preserved):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-(NSDictionary *)dicValue;
-(id)initWithContentArray:(NSMutableArray*)acontentArray;
- (id)initWithDictionnary:(NSDictionary*)adic;
-(void) addEmails:(NSString *)emails;
-(void)save;
- (void) setShareEmailsWithArray:(NSArray *)shareEmails;
- (NSArray *)getShareEmailsArray;
-(BOOL) isOwner;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One empty line between method declaration should be the norm.&lt;/p&gt;

&lt;h3&gt;Managing database&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;[dataBaseManager registerAndGetQueryResult:@&quot;INSERT OR REPLACE INTO tasks (id, description, date_creation, complete, date_complete, due_date, alarm_date, id_note, updatedate, tosend, ownerid, shareemails) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?,?)&quot; withParams:@&quot;%@%@%@%d%@%@%@%@%@%@&quot;, task.identifier, task.description, task.dateCreation, task.isComplete, task.dateComplete, task.dueDate, task.alarmDate, task.idNote, task.updateDate, task.ownerId, task.shareEmails];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All the database interaction is made in pure SQL. A custom in-house framework is used to manage all the queries/inserts/updates. Why not go with CoreData ? It&#39;s the standard on iOS and contains everything a developer need. It&#39;s a bit complex at first but it can save a lot of time afterwards.&lt;/p&gt;

&lt;h3&gt;Magic constants&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;- (void) showItemWithItem:(XXXTimelineItem *)timelineItem
{
    switch (timelineItem.type) {
        case 1:
        case 18:
        case 19:
            [self showTodo];
            break;
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 10:
        case 15:
        case 21:
            [self showFolderWithItem:timelineItem];
            break;
        case 2:
        case 8:
        case 9:
        case 11:
        case 12:
        case 13:
        case 14:
        case 16:
        case 17:
            [self showNoteWithItem:timelineItem];
            break;
        default:
            break;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;String typing&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;if ([self.currentNote.getType isEqualToString:@&quot;TEXT&quot;]) {…}
else if([self.currentNote.getType isEqualToString:@&quot;PHOTO&quot;]) {…}
else if([self.currentNote.getType isEqualToString:@&quot;AUDIO&quot;]) {…}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ouch.&lt;/p&gt;

&lt;h3&gt;Libraries&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;CocoaPods&lt;/em&gt; is the way to go to manage libraries.&lt;/p&gt;

&lt;p&gt;The projects has Stig Brautaset&#39;s JSON tools copied into the project. The AWSiOsSDK also uses this json parser. Boum.&lt;/p&gt;
</description>
        <pubDate>Sat, 26 Oct 2013 18:40:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2013/10/26/ios-legacy-code.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2013/10/26/ios-legacy-code.html</guid>
      </item>
      
    
      
      <item>
        <title>Gradle Build Variants for your android project</title>
        <description>&lt;p&gt;When developing an app, you usually have many slightly different versions of this app. The most common example is probably the backend you want to use: &lt;em&gt;production&lt;/em&gt; or &lt;em&gt;staging&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You usually define the base URLs with the other constants of the app. Switching from one environment to the other is done by (un)commenting the right lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public static String BASE_URL = &quot;http://staging.tamere.be&quot;
//public static String BASE_URL = &quot;http://production.tamere.be&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The process is manual, boring and error prone but hey, changing one line is not that bad, is it?&lt;/p&gt;

&lt;p&gt;Then you add more and more features that depends on the environment. You maybe want a different icon and then different input validation rules and then ...&lt;/p&gt;

&lt;p&gt;That&#39;s where your build tool can help. Let&#39;s see how we can automate the process of generating different APKs for different environment with Gradle.&lt;/p&gt;

&lt;h2&gt;Build variants&lt;/h2&gt;

&lt;p&gt;Gradle has the concepts of &lt;em&gt;Build Types&lt;/em&gt; and &lt;em&gt;Build Flavors&lt;/em&gt;. When combining the two, you get a &lt;em&gt;Build Variant&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There two default build types: &lt;em&gt;release&lt;/em&gt; and &lt;em&gt;debug&lt;/em&gt;. We won&#39;t change them in our example but we will create two new flavors: &lt;em&gt;production&lt;/em&gt; and &lt;em&gt;staging&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As a result, we&#39;ll have four different variants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ProductionDebug&lt;/li&gt;
&lt;li&gt;ProductionRelease&lt;/li&gt;
&lt;li&gt;StagingDebug&lt;/li&gt;
&lt;li&gt;StagingRelease&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Sample project&lt;/h2&gt;

&lt;p&gt;The project is pretty simple but shows how you can define for each build variant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an app name&lt;/li&gt;
&lt;li&gt;an icon&lt;/li&gt;
&lt;li&gt;constants (in our case a &lt;code&gt;BASE_URL&lt;/code&gt; variable)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You can download the project on &lt;a href=&quot;https://github.com/fstephany/gradle-build-variant-example&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here are two screenshots of the generated apps. Nothing really fancy:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2013/flavors-prod.png&quot; alt=&quot;Android App drawer showing the two differents flavors&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2013/flavors-staging.png&quot; alt=&quot;Android App drawer showing the two differents flavors&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;build.gradle file&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath &#39;com.android.tools.build:gradle:0.5.+&#39;
    }
}
apply plugin: &#39;android&#39;

repositories {
    mavenCentral()
}

android {
    compileSdkVersion 18
    buildToolsVersion &quot;18.0.1&quot;

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 18
    }

    productFlavors {
        production {
            packageName &quot;be.tamere.gradlebuildtypesexample&quot;
        }

        staging {
            packageName &quot;be.tamere.gradlebuildtypesexample.staging&quot;
        }
    }
}

dependencies {
    compile &#39;com.android.support:appcompat-v7:18.0.0&#39;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The definition of the flavors is super simple, all the magic will happen in their folders.&lt;/p&gt;

&lt;h2&gt;File structure&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;src&lt;/code&gt; folder, we&#39;ve created two directories whose names must match the flavors. We will define all the flavor-specific values. Only specific values are necessary.&lt;/p&gt;

&lt;p&gt;The staging version defines new icons while both flavors defines a &lt;code&gt;Constants.java&lt;/code&gt;. The app name is defined in the &lt;code&gt;string.xml&lt;/code&gt; files.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;├── main
│   ├── AndroidManifest.xml
│   ├── ic_launcher-web.png
│   ├── java
│   │   └── be
│   │       └── tamere
│   │           └── gradlebuildtypesexample
│   │               └── MainActivity.java
│   └── res
│       ├── drawable-hdpi
│       │   └── ic_launcher.png
│       ├── drawable-mdpi
│       │   └── ic_launcher.png
│       ├── drawable-xhdpi
│       │   └── ic_launcher.png
│       ├── drawable-xxhdpi
│       │   └── ic_launcher.png
│       ├── layout
│       │   └── activity_main.xml
│       ├── menu
│       │   └── main.xml
│       ├── values
│       │   ├── dimens.xml
│       │   ├── strings.xml
│       │   └── styles.xml
│       ├── values-v11
│       │   └── styles.xml
│       └── values-v14
│           └── styles.xml
├── production
│   └── java
│       └── be
│           └── tamere
│               └── gradlebuildtypesexample
│                   └── Constants.java
└── staging
    ├── java
    │   └── be
    │       └── tamere
    │           └── gradlebuildtypesexample
    │               └── Constants.java
    └── res
        ├── drawable-hdpi
        │   └── ic_launcher.png
        ├── drawable-mdpi
        │   └── ic_launcher.png
        ├── drawable-xhdpi
        │   └── ic_launcher.png
        ├── drawable-xxhdpi
        │   └── ic_launcher.png
        └── values
            └── string.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Android Studio&lt;/h2&gt;

&lt;p&gt;You can switch between the two flavors in the &lt;code&gt;Build variants&lt;/code&gt; tab of the IDE. Android Studio has some trouble identifying the resources for a non-active flavors.&lt;/p&gt;

&lt;p&gt;We are using the &lt;code&gt;production&lt;/code&gt; flavor, Studio does not understand that the &lt;code&gt;staging&lt;/code&gt; folder contains source code. Don&#39;t worry, it&#39;s normal, it will catch up when you switch to the staging variant.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2013/build-variants.png&quot; alt=&quot;Android Studio IDE showing different build variants&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Launch the app with the different flavors to see the result.&lt;/p&gt;

&lt;p&gt;The app drawer shows the two icons:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2013/app-drawer.png&quot; alt=&quot;Android App drawer showing the two differents flavors&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-flavors&quot;&gt;http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-flavors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Xav&#39;s answer on this &lt;a href=&quot;http://stackoverflow.com/questions/16737006/using-build-flavors-structuring-source-folders-and-build-gradle-correctly&quot;&gt;Stack overflow topic&lt;/a&gt; is particularly helpful.&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 06 Oct 2013 00:43:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2013/10/06/gradle-build-variants-for-your-android-project.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2013/10/06/gradle-build-variants-for-your-android-project.html</guid>
      </item>
      
    
      
      <item>
        <title>UILocalNotification alertBody</title>
        <description>&lt;p&gt;Once again, this post is more a reminder to &lt;code&gt;self&lt;/code&gt; than a real blog post but I&#39;ve been
bitten by that one.&lt;/p&gt;

&lt;p&gt;Always set the &lt;code&gt;alertBody&lt;/code&gt; of a &lt;code&gt;UILocalNotification&lt;/code&gt;. If you don&#39;t, nothing will appear when the application is on the background. The &lt;a href=&quot;https://developer.apple.com/library/ios/#documentation/iPhone/Reference/UILocalNotification_Class/Reference/Reference.html&quot;&gt;documentation&lt;/a&gt; mentions it but it&#39;s pretty easy to miss the remark:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Assign a string or, preferably, a localized-string key (using NSLocalizedString) as the value of the message. If the value of this property is non-nil, an alert is displayed. The default value is nil (no alert).&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Creating a local notification without any content is probably not common but it can happen while developing with the &lt;em&gt;I will add text later&lt;/em&gt; mindset.&lt;/p&gt;
</description>
        <pubDate>Thu, 06 Jun 2013 14:44:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2013/06/06/UILocalNotification-alertBody.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2013/06/06/UILocalNotification-alertBody.html</guid>
      </item>
      
    
      
      <item>
        <title>Scroll UITableView to currently selected UITextField</title>
        <description>&lt;h2&gt;Situation&lt;/h2&gt;

&lt;p&gt;I have a &lt;code&gt;UITableView&lt;/code&gt;. Each cell of the table view has a &lt;code&gt;UITextField&lt;/code&gt; in its &lt;code&gt;contentView&lt;/code&gt;. The table view is actually a giant form.&lt;/p&gt;

&lt;p&gt;In iOS when a tableView has cells containing textfield, it is supposed to scroll when a textfield becomes the first responder so focused textfield is visible when the user edits its content.&lt;/p&gt;

&lt;p&gt;It wasn&#39;t the case for me.&lt;/p&gt;

&lt;h2&gt;Solution&lt;/h2&gt;

&lt;p&gt;Do not forget the &lt;code&gt;[textField resignFirstResponder]&lt;/code&gt; when passing the &lt;code&gt;isFirstResponder&lt;/code&gt; to the next textfield. Otherwise the tableView won&#39;t scroll to the new first responder when editing.&lt;/p&gt;

&lt;p&gt;&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot; data-lang=&quot;objective-c&quot;&gt;- (BOOL)textFieldShouldReturn:(UITextField &lt;em&gt;)textField {
  NSInteger nextTag = textField.tag + 1;
  UIView&lt;/em&gt; nextResponder = [self.view viewWithTag:nextTag];
  [textField resignFirstResponder];&lt;/p&gt;

&lt;p&gt;  if (nextResponder) {
    [nextResponder becomeFirstResponder];
  }
  return YES;
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;Et voilà, the tableView will scroll as you expect.&lt;/p&gt;
</description>
        <pubDate>Tue, 21 May 2013 01:30:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2013/05/21/scroll-uitableview-to-currently-selected-uitextfield.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2013/05/21/scroll-uitableview-to-currently-selected-uitextfield.html</guid>
      </item>
      
    
      
      <item>
        <title>Pharo Sprint in Lille</title>
        <description>&lt;p&gt;The &lt;a href=&quot;http://rmod.lille.inria.fr/&quot;&gt;RMoD&lt;/a&gt; team held a sprint in their new office in &lt;a href=&quot;http://www.inria.fr/en/centre/lille&quot;&gt;Inria Lille&lt;/a&gt; last Friday. It was the occasion to meet in real life and to smash some bugs.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;https://twitter.com/camillobruni&quot;&gt;Camillo&lt;/a&gt; showed us how to use the bug tracker and how to submit a patch for integration. Overall the process is much easier than I expected.&lt;/p&gt;


&lt;p&gt;I paired with Mariano for a couple of hours. We started something too big for the time we had so we warmed up on &lt;a href=&quot;http://code.google.com/p/pharo/issues/detail?id=6902&quot;&gt;an annoying bug&lt;/a&gt; we found while fixing what we initially planned to do. We then tried to clean OSProcess&lt;a href=&quot;https://code.google.com/p/pharo/issues/detail?id=6855&quot;&gt; to load it in Pharo 2.0&lt;/a&gt;. Once again, we probably picked something too big and I had to leave early so we didn&#39;t finish but we made some progress (I hope ;))&lt;/p&gt;


&lt;p&gt;&lt;div class=&#39;p_embed p_image_embed&#39;&gt;
&lt;img src=&#39;/images/2012/11/45559858-DSC_0030.jpeg&#39;&gt;
&lt;img src=&#39;/images/2012/11/45559862-DSC_0036.jpeg&#39;&gt;
&lt;img src=&#39;/images/2012/11/45559863-IMG_1285.jpeg&#39;&gt;
&lt;img src=&#39;/images/2012/11/45559865-IMG_1286.jpeg&#39;&gt;
&lt;/div&gt;
(pictures by &lt;a href=&quot;http://marcusdenker.de/&quot;&gt;Marcus Denker&lt;/a&gt;)&lt;/p&gt;


&lt;p&gt;In total, 18 bugs were solved (only two of them are not integrated yet), 8 others were fixed but need a second review and around 10 were closed for other reasons. All of this in a happy english/french/spanish speaking atmosphere.&lt;/p&gt;


&lt;p&gt;I had never paired with someone in Smalltalk before. This kind of experience reminds me why I like programming. Thanks guys!&lt;/p&gt;

</description>
        <pubDate>Sun, 04 Nov 2012 13:30:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2012/11/04/pharo-sprint-in-lille.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/11/04/pharo-sprint-in-lille.html</guid>
      </item>
      
    
      
      <item>
        <title>Migrating from MS Works to LibreOffice - batch processing</title>
        <description>&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Forensic_Medicine&quot;&gt;forensic doctor&lt;/a&gt; came to me with a very specific problem; he was using &lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Works&quot;&gt;Microsoft Works&lt;/a&gt; for years. He upgraded version after version without too much hassle but when Microsoft discontinued it, this doctor was worried about the long-term preservation of his data (all documents must be kept available for 30 years).&lt;/p&gt;


&lt;p&gt;He grew up tired of Windows and to make things worse, he bought an iPhone last year. It was then decided that his next laptop would be a Mac.&lt;/p&gt;


&lt;p&gt;Executing Works on a Mac is not an option in the long term but is tolerate during the migration, &lt;a href=&quot;http://www.parallels.com/products/desktop/&quot;&gt;Parallels Desktop&lt;/a&gt; has a great Coherence mode where Windows application behave like Mac ones.&lt;/p&gt;

</description>
        <pubDate>Sat, 03 Nov 2012 04:48:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2012/11/03/migrating-from-ms-works-to-libreoffice-batch.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/11/03/migrating-from-ms-works-to-libreoffice-batch.html</guid>
      </item>
      
    
      
      <item>
        <title>Kill all the compiling!</title>
        <description>&lt;p&gt;Two cool projects, one in Ruby/Javascript, the other in Pharo Smalltalk. They both try to get rid of unnecessary compilation of source code.&lt;/p&gt;




&lt;h2&gt;TurboLinks&lt;/h2&gt;




&lt;p&gt;&lt;a href=&quot;https://github.com/rails/turbolinks&quot;&gt;TurboLinks&lt;/a&gt; speeds up Rails app. Basically, when you click on a link of your application,  &lt;code&gt;body&lt;/code&gt; and &lt;code&gt;title&lt;/code&gt; are replaced. The browser does not load a whole new page. This avoids the recompilation of all the javascript and CSS by the browser. TurboLinks takes care of the history by using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history&quot;&gt;pushState&lt;/a&gt;. It falls back to the regular behaviour if the browser does not support &lt;code&gt;pushState&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;The speedup is quite visible, especially if you have a lot of Javascript and are on a mobile browser.&lt;/p&gt;




&lt;h2&gt;Tanker&lt;/h2&gt;




&lt;p&gt;Managing packages in Pharo/Squeak is quite a pain. Metacello helps but loading a project and all its dependencies takes a loooooong time. Try to load &lt;a href=&quot;http://www.seaside.st/&quot;&gt;Seaside&lt;/a&gt;, &lt;a href=&quot;http://forum.world.st/Magritte-Pier-and-Related-Tools-f115649.html&quot;&gt;Magritte&lt;/a&gt;,  and &lt;a href=&quot;http://code.google.com/p/cloudfork/&quot;&gt;CloudFork&lt;/a&gt;, you&amp;rsquo;ll understand what I mean.&lt;/p&gt;




&lt;p&gt;The reason is simple: a Monticello package contains the plain sources. When loading it, Pharo has to compile all the sources.&lt;/p&gt;




&lt;p&gt;&lt;a href=&quot;http://marianopeck.wordpress.com/2012/09/28/new-tanker-current-status/&quot;&gt;Tanker&lt;/a&gt; uses the &lt;a href=&quot;http://rmod.lille.inria.fr/web/pier/software/Fuel&quot;&gt;Fuel serialiser&lt;/a&gt; to load your code. It serialises the compiled methods and can restore them in another image without the need for recompiling.&lt;/p&gt;




&lt;p&gt;Loading seaside now takes around 20 seconds (it could take ~10-15 minutes before).&lt;/p&gt;




&lt;p&gt;&lt;em&gt;edit:&lt;/em&gt; &lt;a href=&quot;http://marianopeck.wordpress.com/&quot;&gt;Mariano&lt;/a&gt;&amp;rsquo;s comment clarifies the loading speed of Tanker versus Monticello loading. I went a bit too fast to my conclusion ;)&lt;/p&gt;




&lt;p&gt;&lt;img src=&quot;http://imgs.xkcd.com/comics/compiling.png&quot; alt=&quot;xkcd compiling&quot; /&gt;
&lt;/p&gt;

</description>
        <pubDate>Fri, 28 Sep 2012 14:44:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/09/28/kill-all-the-compiling.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/09/28/kill-all-the-compiling.html</guid>
      </item>
      
    
      
      <item>
        <title>Seaside wrapper for Filepicker.io</title>
        <description>&lt;p&gt;To me, uploading has always been the messier part in web application. Some will argue that the fun starts when you want to do ajax uploading.&lt;/p&gt;




&lt;p&gt;&lt;a href=&quot;http://filepicker.io/&quot;&gt;Filepicker.io&lt;/a&gt; solves the problem quite elegantly. Mega bonus point, they integrate nicely with Dropbox, Gmail, Google drive, Facebook and others. So your user can pick a file on her hard drive, dropbox or even take a picture with the webcam.&lt;/p&gt;




&lt;p&gt;The &lt;a href=&quot;https://developers.filepicker.io/docs/web/&quot;&gt;integration&lt;/a&gt; is pretty straightforward but to make things even easier I&amp;rsquo;ve started a small wrapper for Seaside. You can find it on &lt;a href=&quot;http://ss3.gemstone.com/ss/Filepickerio.html&quot;&gt;Squeaksource 3&lt;/a&gt;. Right now, it only performs the basic but I&amp;rsquo;ll add features when I need them.&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;html form with: [
      html fileInput
           on: #uploadedFileUrl of: self;
           apiKey: &#39;yourApiKey&#39;;
           beDragNDrop.
      html break.
      html submitButton with: &#39;Send the form.&#39;
 ].&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;When the user selects a file and sends the form, the instance variable &lt;code&gt;uploadedFileUrl&lt;/code&gt; will contain the url of the uploaded file. You can then grab it and do whatever you want with the file.&lt;/p&gt;




&lt;p&gt;You can grab the &lt;code&gt;Filepickerio-Test&lt;/code&gt; package in the repo, it contains a sample application showing how to use it.&lt;/p&gt;




&lt;p&gt;I&amp;rsquo;ve only tested on Pharo 1.4 Summer edition and Seaside 3.0.7. The code is quite simple and should work everywhere though…&lt;/p&gt;




&lt;p&gt;Oh, the repo is global read/write and the code is MIT ;)&lt;/p&gt;

</description>
        <pubDate>Wed, 26 Sep 2012 20:17:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/09/26/seaside-wrapper-for-filepickerio.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/09/26/seaside-wrapper-for-filepickerio.html</guid>
      </item>
      
    
      
      <item>
        <title>Deploying Pharo Application</title>
        <description>&lt;p&gt;People sometimes asks me how to deploy Smalltalk applications. I&amp;rsquo;ve only worked with Squeak and Pharo with server side application so I only covers those two dialects in that context.&lt;/p&gt;




&lt;p&gt;It all start easy. Basically, you write a script that you can use with a process monitoring daemon (I use &lt;a href=&quot;http://rfw.posterous.com/monit-101-an-developers-guide-to-system-monit&quot;&gt;monit&lt;/a&gt; but any will do the trick). This daemon will start/restart/stop your application with your script. So far, I never had any problems with this system.&lt;/p&gt;




&lt;p&gt;Now how does your startup script should look like? Here is an overview of the different possibilities. Please comment if you use an other strategy.&lt;/p&gt;




&lt;h1&gt;Create an image locally and upload it&lt;/h1&gt;




&lt;p&gt;That&amp;rsquo;s the most basic scenario. You create your image locally, load everything you need and then upload it to your server with S/FTP. Slow and painful, you want to avoid this process.&lt;/p&gt;




&lt;h1&gt;Load everything all the time&lt;/h1&gt;




&lt;p&gt;Your script takes a fresh image, load your Metacello configuration and hopla, it&amp;rsquo;s ready to go. You never save the image. It is used as a runtime and there&amp;rsquo;s no need to save it. I love this approach for its simplicity. It is also pretty clean as you never rot your image and everything is wiped out when you restart.&lt;/p&gt;




&lt;p&gt;Acutally it looks like a regular web application in, say, Ruby. Ruby loads your code and the dependent gems and run your code.&lt;/p&gt;




&lt;p&gt;Unfortunately it has a huge drawback. Metacello will look at all your dependencies and load the versions you defined. You need to rely on other people configurations and hope that their repo are still reachable. Have you ever encoutered a broken Metacello configuration? How many time &lt;a href=&quot;http://squeaksource.com&quot;&gt;squeaksource&lt;/a&gt; has been down lately? The recent outage with Lukas Renggli repository (which contained many open source projects) also shows the limitation of this model.&lt;/p&gt;




&lt;p&gt;Another issue is the time it takes to load packages with Monticello. Most of my projects depends on Seaside, Magritte, Cloudfork and others. Loading all those can take up to 20 minutes.  It means that you need to wait every time your application restarts. Annoying.&lt;/p&gt;




&lt;p&gt;There&amp;rsquo;s a GSOC project going on that will solve this problem by providing binary packages (so you don&amp;rsquo;t need to recompile everything you load). It&amp;rsquo;s not there yet and you need a binary version of all the project you depend on.&lt;/p&gt;




&lt;h1&gt;Prepare a base image with CI server&lt;/h1&gt;




&lt;p&gt;For this one, you load your project and its dependencies once in an image. You save it. Then you tell your process monitoring daemon to just launch it. Once it started, you never save it. If it crashes, you simply restart the prepared image.&lt;/p&gt;




&lt;p&gt;With this approach, you need to generate the base image. You can do it manually but a continuous integration server can help a lot. You can create a hook that regenerate the base image when you update your Metacello configuration for example.&lt;/p&gt;




&lt;p&gt;This scenario removes the problem of loading time. When your application crashes, it can restart instantly, you don&amp;rsquo;t need to reload everything. But you need a CI server to automate the construction of the image.&lt;/p&gt;




&lt;h1&gt;Conclusion&lt;/h1&gt;




&lt;p&gt;The first approach is clearly not optimal. It works for &lt;em&gt;very&lt;/em&gt; small project but does not scale at all. Ideally, your deployment process should be as smooth as possible. A &lt;a href=&quot;http://heroku.com&quot;&gt;Heroku&lt;/a&gt; like deployment would be super cool to have but so far Smalltalkers all have their own scripts, there are no standardized solutions.&lt;/p&gt;




&lt;p&gt;Note that those strategies show their limitation only at the first launch or when they restart. In many situations, you can update your code when it&amp;rsquo;s running, without restarting the image.&lt;/p&gt;




&lt;p&gt;Smalltalker, what is your deployment process?&lt;/p&gt;

</description>
        <pubDate>Wed, 04 Jul 2012 15:59:10 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/07/04/deploying-pharo-application.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/07/04/deploying-pharo-application.html</guid>
      </item>
      
    
      
      <item>
        <title>Misc stuff about Voyage and MongoDB</title>
        <description>&lt;p&gt;&lt;a href=&quot;http://smallworks.com.ar/&quot;&gt;Esteban&lt;/a&gt; replied to my &lt;a href=&quot;http://articles.tulipemoutarde.be/mongodb-with-voyage-in-pharo&quot;&gt;first post&lt;/a&gt; about &lt;a href=&quot;smalltalkhub.com/#!/~estebanlm/Voyage/&quot;&gt;Voyage&lt;/a&gt;. Unfortunately, my blog provider messed up when formatting the comment. Here&amp;rsquo;s a summary of his remarks:&lt;/p&gt;




&lt;h2&gt;Magritte&lt;/h2&gt;




&lt;p&gt;Magritte is not necessary for the basic scenarios. Voyage is smart enough to infer the types of your instance variables and can serialize them. You don&amp;rsquo;t need to describe everything like you would do when building an UI with Magritte.&lt;/p&gt;




&lt;p&gt;The Magritte descriptions are only needed when you want to override the defaults of want to have a one-to-many relationships.&lt;/p&gt;




&lt;p&gt;In the future, it will be able to infer the to-many relations automatically but at the moment you still have to tell voyage how to deal with them.&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;^VOMongoToManyDescription new
    attributeName: &#39;myInstVar&#39;; &amp;quot;Acts on this inst var&amp;quot;
    kindCollection: Set; &amp;quot;Set instead an OrderedCollection&amp;quot;
    beLazy; &amp;quot;I want that references to be retrieved lazily&amp;quot;
    yourself.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Browse &lt;code&gt;VOMongoRelationDescription&lt;/code&gt; and its subclasses to see what is possible.&lt;/p&gt;




&lt;h2&gt;Embedded documents&lt;/h2&gt;




&lt;p&gt;As we&amp;rsquo;ve seen &lt;a href=&quot;http://articles.tulipemoutarde.be/embedded-document-with-voyage-in-mongodb&quot;&gt;previously&lt;/a&gt;, it is pretty easy to map a relation. In our example, we declared both &lt;code&gt;MQSpaceship&lt;/code&gt; and &lt;code&gt;MQPilot&lt;/code&gt; as persistent by implementing &lt;code&gt;isPersistent&lt;/code&gt; on the class side.&lt;/p&gt;




&lt;p&gt;This &lt;code&gt;isPersistent&lt;/code&gt; method has an unfortunate name. It actually means that a collection with the name of the class will be created in the database. If we hadn&amp;rsquo;t declared &lt;code&gt;MQPilot&lt;/code&gt; persistent, it would have been completely embedded in the spaceship.&lt;/p&gt;




&lt;h2&gt;Ignore instance variable&lt;/h2&gt;




&lt;p&gt;Sometimes you do not want to serialize &lt;strong&gt;all&lt;/strong&gt; your instance variables. In such cases, add a &lt;code&gt;VOMongoTransientDescription&lt;/code&gt; like this:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;mongoTransientDescription

  ^VOMongoTransientDescription new
    attributeName: &#39;puppies&#39;;
    yourself.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Now, the &lt;code&gt;puppies&lt;/code&gt; instance variable will be ignored by the serializer and won&amp;rsquo;t be stored in Mongo.&lt;/p&gt;




&lt;p&gt;That&amp;rsquo;s all for today. Once again, huge thanks to Esteban for this super nice library!&lt;/p&gt;

</description>
        <pubDate>Mon, 28 May 2012 19:01:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/05/28/misc-stuff-about-voyage-and-mongodb.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/05/28/misc-stuff-about-voyage-and-mongodb.html</guid>
      </item>
      
    
      
      <item>
        <title>Embedded Document with Voyage in MongoDB</title>
        <description>&lt;p&gt;In my &lt;a href=&quot;http://articles.tulipemoutarde.be/mongodb-with-voyage-in-pharo&quot;&gt;previous post&lt;/a&gt; I was wondering how Voyage would handle embedded documents. The answer is pretty simple. Let&amp;rsquo;s see with an example ( &lt;strong&gt;MQ&lt;/strong&gt; stands for for &lt;em&gt;Mars Quest&lt;/em&gt;):&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;Object subclass: #MQSpaceship
   instanceVariableNames: &#39;pilot name&#39;
   classVariableNames: &#39;&#39;
   poolDictionaries: &#39;&#39;
   category: &#39;MarsQuest&#39;

Object subclass: #MQPilot
   instanceVariableNames: &#39;name&#39;
   classVariableNames: &#39;&#39;
   poolDictionaries: &#39;&#39;
   category: &#39;MarsQuest&#39;

MQSpaceship class&amp;gt;&amp;gt;isPersistent
   ^true

MQPilot class&amp;gt;&amp;gt;isPersistent
   ^true&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Generate the accessors for the instance variables (yeah, &lt;code&gt;name&lt;/code&gt; is super annoying). And execute the following:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;(MQSpaceship new
    name: &#39;Batmobile&#39;;
    pilot: (MQPilot new name: &#39;Batman&#39;)) save.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Voyage will generate two collection in your database: &lt;code&gt;spaceship&lt;/code&gt; and &lt;code&gt;pilot&lt;/code&gt;. The spaceship record we&amp;rsquo;ve just created is:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;{
   &amp;quot;_id&amp;quot;: ObjectId(&amp;quot;f65bd8790000000000000000&amp;quot;),
   &amp;quot;#instanceOf&amp;quot;: &amp;quot;MQSpaceship&amp;quot;,
   &amp;quot;name&amp;quot;: &amp;quot;Batmobile&amp;quot;,
   &amp;quot;pilot&amp;quot;: {
      &amp;quot;#collection&amp;quot;: &amp;quot;pilot&amp;quot;,
      &amp;quot;#instanceOf&amp;quot;: &amp;quot;MQPilot&amp;quot;,
      &amp;quot;__id&amp;quot;: ObjectId(&amp;quot;85f61e070000000000000000&amp;quot;)
   }
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;And the pilot record:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;{
  &amp;quot;_id&amp;quot;: ObjectId(&amp;quot;85f61e070000000000000000&amp;quot;),
  &amp;quot;#instanceOf&amp;quot;: &amp;quot;MQPilot&amp;quot;,
  &amp;quot;name&amp;quot;: &amp;quot;Batman&amp;quot;
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;So we didn&amp;rsquo;t completely embed the Pilot into the Spaceship document but have defined a relation. This is something you would or wouldn&amp;rsquo;t want depending of your data and what kind of query you need to perform on them (&lt;a href=&quot;https://www.youtube.com/watch?v=PIWVFUtBV1Q&quot;&gt;this talk&lt;/a&gt; explains modeling choices in MongoDB).&lt;/p&gt;




&lt;p&gt;When you retrieve the Spaceship, the Pilot is also automatically fetched.&lt;/p&gt;




&lt;p&gt;Once again, this post is pretty straightforward and more a loud thinking about &lt;a href=&quot;http://smalltalkhub.com/#!/~estebanlm/Voyage/&quot;&gt;Voyage&lt;/a&gt; than a real structured tutorial/article. Hopefully it will end up in something useful for someone.&lt;/p&gt;




&lt;p&gt;If not, you can always enjoy the uber cool hair design in the videoclip of &lt;em&gt;Voyage, voyage&lt;/em&gt; from Desireless:&lt;/p&gt;




&lt;iframe src=&quot;http://www.youtube.com/embed/6PDmZnG8KsM?wmode=transparent&quot;
        frameborder=&quot;0&quot;
        height=&quot;417&quot;
        width=&quot;628&quot;&gt;video&lt;/iframe&gt;



</description>
        <pubDate>Thu, 24 May 2012 21:15:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/05/24/embedded-document-with-voyage-in-mongodb.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/05/24/embedded-document-with-voyage-in-mongodb.html</guid>
      </item>
      
    
      
      <item>
        <title>MongoDB with Voyage  in Pharo</title>
        <description>&lt;p&gt;Esteban published &lt;a href=&quot;http://smalltalkhub.com/#!/~estebanlm/Voyage/&quot;&gt;Voyage&lt;/a&gt;, a library for persisting objects in Smalltalk. It uses &lt;a href=&quot;http://code.google.com/p/magritte-metamodel/&quot;&gt;Magritte&lt;/a&gt; to get descriptions from your domain model. At the moment, &lt;a href=&quot;http://www.mongodb.org/&quot;&gt;MongoDB&lt;/a&gt; and the image are the two possible backend for Voyage.&lt;/p&gt;




&lt;p&gt;If you are not familiar with MongoDB and Document based databases, this &lt;a href=&quot;https://www.youtube.com/watch?v=PIWVFUtBV1Q&quot;&gt;presentation&lt;/a&gt; (~1h) by Jared Rosoff should help you to grasp the differences with the RDBMS world.&lt;/p&gt;




&lt;p&gt;I wanted to play a bit with Pharo and MongoDB, there&amp;rsquo;s a &lt;a href=&quot;http://www.squeaksource.com/MongoTalk&quot;&gt;MongoTalk&lt;/a&gt;, a simple smalltalk driver which works well but is quite low level. I wanted something that can be easily integrated with Magritte.&lt;/p&gt;




&lt;p&gt;Here&amp;rsquo;s some dabbling with it and Pharo 1.4 (version 14441). Nothing really fancy, we will just save an object.&lt;/p&gt;




&lt;p&gt;The Metacello configuration will take care of installation:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;Gofer it
  url: &#39;http://smalltalkhub.com/mc/estebanlm/Voyage/main&#39;;
  package: &#39;ConfigurationOfVoyage&#39;;
  load.

ConfigurationOfVoyage project bleedingEdge load: &#39;Mongo&#39;.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;Update August 2012&lt;/strong&gt;
Esteban created two different configuration &lt;code&gt;ConfigurationOfVoyageMongo&lt;/code&gt; and &lt;code&gt;ConfigurationOfPierVoyage&lt;/code&gt;. You should use the former for loading Voyage:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;Gofer it
  url: &#39;http://smalltalkhub.com/mc/estebanlm/Voyage/main&#39;;
  package: &#39;ConfigurationOfVoyageMongo&#39;;
  load.

(ConfigurationOfVoyageMongo project version: &#39;1.0&#39;) load: &#39;Mongo&#39;.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;We are going to assume you have a default MongoDB setup.&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;repo := VOMongoRepository
  host: VOMongoRepository defaultHost
  database: &#39;voyage-play&#39;.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;And setup this repository as the default one:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;VORepository setRepository: repo.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Declare a new class. Don&amp;rsquo;t pay attention to my model, I&amp;rsquo;m designing the next social network that will bring humans to Mars.&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;Object subclass: #Brolinou
  instanceVariableNames: &#39;title&#39;
  classVariableNames: &#39;&#39;
  poolDictionaries: &#39;&#39;
  category: &#39;Brol&#39;

Brolinou&amp;gt;&amp;gt;title
  ^title

Brolinou&amp;gt;&amp;gt;title: aString
  title := aString

Brolinou class&amp;gt;&amp;gt;isPersistent
  ^true&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;The last one is important. Voyage is now aware that you can persist &lt;code&gt;Brolinou&lt;/code&gt; objects.&lt;/p&gt;




&lt;p&gt;The weird thing is that Voyage currently depends on Magritte 2. I don&amp;rsquo;t know if you&amp;rsquo;ve already migrated to Magritte 3 but it bothers me a bit to start a new project with Magritte 2. I&amp;rsquo;m by no means a Magritte expert, there a probably good reasons to stay with that version. It is maybe that time is scarce and that Esteban is working like crazy on many other projects ;)&lt;/p&gt;




&lt;p&gt;Anyway we gonna add a description for our title field:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;titleDescription
  ^MAStringDescription new
     label: &#39;titre&#39;;
     accessor: #title;
     yourself.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Time to open a workspace and dabble with our model:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;brol := Brolinou new title: &#39;Going to Mars!&#39;.
brol isNew. &amp;quot;=&amp;gt; true&amp;quot;
brol save.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Tadadada! Open the Mongo shell or your favorite interface to it (I&amp;rsquo;m using &lt;a href=&quot;http://rockmongo.com/&quot;&gt;RockMongo&lt;/a&gt;). You should see a new collection. The weird thing is that the new collection is named &lt;code&gt;olinou&lt;/code&gt; in the database &lt;code&gt;voyage-play&lt;/code&gt;. I was expecting something like &lt;code&gt;brolinou&lt;/code&gt;. Remember that we are running the bleeding edge version of Voyage so it&amp;rsquo;s not that important.&lt;/p&gt;




&lt;p&gt;You should have an entry that looks like:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;{
   &amp;quot;_id&amp;quot;: ObjectId(&amp;quot;69b4a62c0000000000000000&amp;quot;),
   &amp;quot;#instanceOf&amp;quot;: &amp;quot;Brolinou&amp;quot;,
   &amp;quot;title&amp;quot;: &amp;quot;Going to Mars!&amp;quot;
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;We can see here that a field `#instanceOf&quot; has been added to the record. It is probably used at materialization. You can now query your class to retrieve all the Brolinou instances:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;Brolinou selectAll.
Brolinou selectMany: { #title -&amp;gt; &#39;Going to Mars!&#39;} asDictionary.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;To see all the available methods, browse the &lt;code&gt;Voyage-Model-Core&lt;/code&gt; protocol in the class &lt;code&gt;Class&lt;/code&gt;. The &lt;code&gt;persistence&lt;/code&gt; protocol of &lt;code&gt;VOMongoRepository&lt;/code&gt; is quite interesting as well.&lt;/p&gt;




&lt;p&gt;That&amp;rsquo;s all! Here are the topics I&amp;rsquo;d like to cover next:&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Queries&lt;/li&gt;
&lt;li&gt;Index&lt;/li&gt;
&lt;li&gt;So far, Voyage will create a collection named after the class. With embedded objects you don&amp;rsquo;t always want that behavior. There&amp;rsquo;s probably a way to override that, i&amp;rsquo;m wondering how it is made.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;EDIT&lt;/h2&gt;




&lt;p&gt;The issue with the collection name is caused by the following code:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;VOMongoContainer class&amp;gt;&amp;gt;defaultCollectionName
  ^(self label allButFirst: 2) asLegalSelector&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;This decision was probably made because of the lack of namespaces in Pharo. So people prefix their model class with two letters (e.g., &lt;strong&gt;WA&lt;/strong&gt;Tag, &lt;strong&gt;FS&lt;/strong&gt;Locator, &lt;strong&gt;Zn&lt;/strong&gt;Entity). It makes sense now.&lt;/p&gt;




&lt;h2&gt;Edit two&lt;/h2&gt;




&lt;p&gt;It seems that the Magritte description is useless in this case. Voyage will happily serialize the &lt;code&gt;title&lt;/code&gt; instance variable automatically. See my &lt;a href=&quot;http://articles.tulipemoutarde.be/embedded-document-with-voyage-in-mongodb&quot;&gt;next post&lt;/a&gt; for more.&lt;/p&gt;

</description>
        <pubDate>Thu, 24 May 2012 19:21:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/05/24/mongodb-with-voyage-in-pharo.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/05/24/mongodb-with-voyage-in-pharo.html</guid>
      </item>
      
    
      
      <item>
        <title>Vancouver Smalltalk Developer Group</title>
        <description>&lt;p&gt;The first meeting of the &lt;a href=&quot;http://www.meetup.com/Vancouver-Smalltalk-Developers-Group/&quot;&gt;Vancouver Smalltalk Developer Group&lt;/a&gt; was pretty good! Nine people showed up, which is quite nice considering the size of the Smalltalk community and the fact that it was the first event. Unfortunately I forgot to take pictures, probably a side effect of interesting discussions ;)&lt;/p&gt;




&lt;p&gt;We got the meeting room of a Waves coffee shop in downtown Vancouver, the venue is allright but there is no projector and we were kicked out of the room at 8.30.&lt;/p&gt;




&lt;p&gt;The next event is on its way. The date is not decided yet but it will happen between the 11th and 16th of June (tell us what&amp;rsquo;s better for you in &lt;a href=&quot;http://www.doodle.com/bycw6xw9xtggt5ru&quot;&gt;the doodle&lt;/a&gt;). If you are in the area, you&amp;rsquo;re more than welcome even if you&amp;rsquo;re not a smalltalker.&lt;/p&gt;




&lt;p&gt;In the future, please subscribe to the &lt;a href=&quot;http://www.meetup.com/Vancouver-Smalltalk-Developers-Group/&quot;&gt;Meetup group&lt;/a&gt;, the &lt;a href=&quot;http://lists.esug.org/mailman/listinfo/esug-list_lists.esug.org&quot;&gt;ESUG&lt;/a&gt; list or the &lt;a href=&quot;http://scona.us/mailman/listinfo/scona-list&quot;&gt;SCONA&lt;/a&gt; list to be in the loop ;)&lt;/p&gt;

</description>
        <pubDate>Wed, 23 May 2012 18:13:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/05/23/vancouver-smalltalk-developer-group.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/05/23/vancouver-smalltalk-developer-group.html</guid>
      </item>
      
    
      
      <item>
        <title>Global package cache &amp; stdin, stdout, stderr on Pharo</title>
        <description>&lt;p&gt;When loading a package with Monticello, a copy is cached in the directory &amp;lsquo;package-cache&amp;rsquo; in your image folder. This is super useful when you need a package that you already have downloaded. Unfortunately, this cache is limited to the image directory. If you need that package in another image which is in another directory, you&amp;rsquo;ll have to &lt;em&gt;redownload&lt;/em&gt; the package.&lt;/p&gt;




&lt;p&gt;Here&amp;rsquo;s a little trick to have a global package cache:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;MCCacheRepository default directory:
  (FileDirectory on: &#39;/home/fstephany/package-cache/&#39;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Of course, adapt the path to your configuration. Thanks Mariano for the tips (&lt;a href=&quot;http://forum.world.st/Having-a-shared-package-cache-Re-MCDirectoryRepository-defaultDirectoryName-ignored-td3924814.html&quot;&gt;original discussion&lt;/a&gt;).&lt;/p&gt;




&lt;p&gt;Another super useful things is the ability to send stuff to &lt;code&gt;sdtin&lt;/code&gt;, &lt;code&gt;stdout&lt;/code&gt; and &lt;code&gt;stderr&lt;/code&gt;. I don&amp;rsquo;t know if it was present prior Pharo 1.3 but I&amp;rsquo;ve just discovered how to play with the standard streams:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;FileStream stdout nextPutAll: &#39;Yopla&#39;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Browse the class side of FileStream for more ;)&lt;/p&gt;

</description>
        <pubDate>Fri, 18 May 2012 15:17:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/05/18/global-package-cache-stdin-stdout-stderr-on-p.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/05/18/global-package-cache-stdin-stdout-stderr-on-p.html</guid>
      </item>
      
    
      
      <item>
        <title>Limit hard dependencies in your code</title>
        <description>&lt;p&gt;Igor Stasenko &lt;a href=&quot;http://forum.world.st/Moving-data-into-new-package-image-version-tp4628820p4630575.html&quot;&gt;summarizes what he does&lt;/a&gt; to avoid coding with hard dependencies in his code:&lt;/p&gt;




&lt;blockquote&gt;&lt;p&gt;Rule #1. never make more than 1 reference to any class external to your package in your code. an exception is kernel classes.&lt;/p&gt;

&lt;p&gt;which means, that you are allowed to do &lt;code&gt;Set new&lt;/code&gt; or &lt;code&gt;Array new&lt;/code&gt;, in any place of your code but never &lt;code&gt;SomeFooClass new&lt;/code&gt; more than once.&lt;/p&gt;

&lt;p&gt;If your code having such dependency, localize it in single method:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;fooClass
  ^ FooClass&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;and then use &lt;code&gt;self fooClass&lt;/code&gt; everywhere..
Like that, if you will figure out one day, that sand moves under your feets, you&amp;rsquo;ll have to change only single method. :)&lt;/p&gt;&lt;/blockquote&gt;




&lt;p&gt;I never felt the need of doing that when the refactoring browser can rename all that for you but it&amp;rsquo;s still make sense if you want cleaner code.&lt;/p&gt;




&lt;p&gt;Thanks Igor :)&lt;/p&gt;

</description>
        <pubDate>Thu, 17 May 2012 15:31:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/05/17/limit-hard-dependencies-in-your-code.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/05/17/limit-hard-dependencies-in-your-code.html</guid>
      </item>
      
    
      
      <item>
        <title>Migrating to Pharo 1.4</title>
        <description>&lt;p&gt;You&amp;rsquo;ve probably heard that Pharo 1.4 is out. This version contains many improvements (as software developers like to say) and some aspects have changed quite a lot.&lt;/p&gt;




&lt;p&gt;One the Pharo team&amp;rsquo;s goal is to clean Squeak. Version 1.4 has made some critical steps toward this goal and more than 850 tickets have been closed. Impressive.&lt;/p&gt;




&lt;p&gt;What is still lacking though is a detailed changelog of all the API changes. Sure, there&amp;rsquo;s a &lt;a href=&quot;http://code.google.com/p/pharo/wiki/ActionsInPharoOneDotFour&quot;&gt;release note&lt;/a&gt; but hey what does &lt;em&gt;Better headless support&lt;/em&gt; mean?&lt;/p&gt;




&lt;p&gt;I&amp;rsquo;ve switched some of my projects from 1.3 to 1.4. I haven&amp;rsquo;t tested everything in production yet but here are my first surprises:&lt;/p&gt;




&lt;h2&gt;FS integration&lt;/h2&gt;




&lt;p&gt;The &lt;a href=&quot;http://www.squeaksource.com/fs.html&quot;&gt;FileSystem&lt;/a&gt; (or FS) library has been integrated. FS is a replacement for the aging &lt;code&gt;FileDirectory&lt;/code&gt;. Manipulating files is now much easier and the API is less chaotic than its predecessor. The &lt;code&gt;FileDirectory&lt;/code&gt; is still there for compatibility reasons I guess but you shouldn&amp;rsquo;t use it anymore.&lt;/p&gt;




&lt;p&gt;If you used the FileSystem library before, beware that the FS prefix has been changed to &amp;ldquo;File&amp;rdquo; (i.e., &lt;code&gt;FSLocator&lt;/code&gt; becomes &lt;code&gt;FileLocator&lt;/code&gt;). Update your code accordingly.&lt;/p&gt;




&lt;p&gt;If your project has a MetacelloConfiguration that loads FS, you don&amp;rsquo;t need it anymore for 1.4&lt;/p&gt;




&lt;h2&gt;Startup scripts&lt;/h2&gt;




&lt;p&gt;That one was missing for quite a long time. Pharo will now look up in your home directory for startup file in the following order:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;#{image_directory}/startup.st
~/.config/pharo/#{version}/startup.st
~/.config/pharo/general/pharo#{version}.st&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;This has bitten me when deploying an a server. I used to launch my image with the following:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;exec $VM $VM_PARAMS $IMAGE $STARTUP_SCRIPT&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;where &lt;code&gt;$STARTUP_SCRIPT&lt;/code&gt; is the path to a &lt;code&gt;.st&lt;/code&gt; file. That file was named &lt;code&gt;startup.st&lt;/code&gt;. My startup script was executed twice without I realized it. It took me some time to realize what was going on ;)&lt;/p&gt;




&lt;p&gt;Beware, it seems that this feature is not reliable (or not implemented?) on Windows.&lt;/p&gt;




&lt;h2&gt;No default browser&lt;/h2&gt;




&lt;p&gt;Pharo 1.3 used to be shipped with OmniBrowser (OB). This is not the case anymore and the default browser is now the basic one. No advanced features, no refactoring, plain boring.&lt;/p&gt;




&lt;p&gt;The best choice is to load Nautilus, a browser developed by Benjamin Van Ryseghem. There is &lt;a href=&quot;https://ci.lille.inria.fr/pharo/view/Nautilus%201.4/job/Nautilus/&quot;&gt;a job on the CI build server&lt;/a&gt; which contains the latest version of Pharo 1.4 and Nautilus.&lt;/p&gt;




&lt;p&gt;Unfortunately, I had some troubles with it. When using the build from CI, loading seaside didn&amp;rsquo;t work. And when I load Seaside in a clean 1.4 image and then loading Nautilus, some strange problems occurs (like the font changes). I haven&amp;rsquo;t really investigated yet but that smells like bleeding edge piece of software.&lt;/p&gt;




&lt;p&gt;The browser is pretty cool though and it is definitely a huge step from OB. My muscle memory is still trained for OB, which complicates the transition :p&lt;/p&gt;




&lt;h2&gt;All in all&lt;/h2&gt;




&lt;p&gt;This release is a good one, the Pharo team did an awesome job and I can&amp;rsquo;t wait to see what the 2.0 will look like. They apparently &lt;a href=&quot;http://forum.world.st/About-the-new-release-process-td4574410.html&quot;&gt;changed their release process&lt;/a&gt; for a time-based versioning (à la Ubuntu). Time will say if it&amp;rsquo;s a good choice&amp;hellip;&lt;/p&gt;

</description>
        <pubDate>Wed, 02 May 2012 00:45:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2012/05/02/migrating-to-pharo-14.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2012/05/02/migrating-to-pharo-14.html</guid>
      </item>
      
    
      
      <item>
        <title>Send email from Pharo with Postmark</title>
        <description>&lt;p&gt;I recently needed to send emails from a Pharo image. There is a SMTP client integrated in the standard libray but I wanted  to wrap the excellent &lt;a href=&quot;http://postmarkapp.com/&quot;&gt;Postmark&lt;/a&gt; REST &lt;a href=&quot;http://developer.postmarkapp.com/developer-build.html&quot;&gt;API&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;You can load it from &lt;a href=&quot;http://ss3.gemstone.com/&quot;&gt;SqueakSource 3&lt;/a&gt;:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;Gofer it
     url: &#39;http://ss3.gemstone.com/ss/postmark&#39;;
     package: &#39;ConfigurationOfPostMark&#39;;
     load.

(Smalltalk at: #ConfigurationOfPostMark) project stableVersion load.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;And you can use it like:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;| email interface |
email := PMEmail new
  from: &#39;francois@wapict.be&#39;;
  to: &#39;francois@yopmail.com&#39;;
  subject: &#39;Test Application&#39;;
  textBody: &#39;Yeah baby&#39;;
  yourself.

interface := PMInterface new.
interface apiKey: &#39;blopblop&#39;.

interface send: email.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;The implementation is really basic and does not handle attachments at the moment. I use it on a staging application that will probably be in production in January. I will see how it behaves under small load and improve it if needed.&lt;/p&gt;




&lt;p&gt;edit: you can now attach files to your emails !&lt;/p&gt;

</description>
        <pubDate>Thu, 29 Dec 2011 18:22:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/12/29/send-email-from-pharo-with-postmark.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/12/29/send-email-from-pharo-with-postmark.html</guid>
      </item>
      
    
      
      <item>
        <title>Windows Phone 7</title>
        <description>&lt;p&gt;I&amp;rsquo;ve written this article in June 2011 and never published it. Now that Nokia has shipped their phones and the Mango (aka Windows Phone 7.5) is everywhere, it&amp;rsquo;s maybe time to click on the &lt;em&gt;publish&lt;/em&gt; button ;)&lt;/p&gt;




&lt;p&gt;When reading reviews of WP7.5, Microsoft has fixed almost all the issues I had with my LG Optimus 7 phone. Unfortunately, it broke during the (awesome) &lt;a href=&quot;http://dourfestival.be/&quot;&gt;Dour festival&lt;/a&gt;. The phone became crazy and kept rebooting. (In case you are wondering, fifteen minutes of cycling reboots keeps your phone hot). The shop where I bought it did not plan to get any Windows Phone soon so they gave me a Galaxy S2 (almost) for free.&lt;/p&gt;




&lt;p&gt;While Android 2.3 is packed with wonderful features, it&amp;rsquo;s not as polished as the WP7 phone I owned but it usually works well. Android 4 is said to address this but I don&amp;rsquo;t think it will be as fresh and usable than Windows Phone. Anyway, here&amp;rsquo;s the short review I wrote back in June:&lt;/p&gt;




&lt;p&gt;I was the first to be surprised when I came back home with a windows phone in my bag. Three months later, it&amp;rsquo;s time to report.&lt;/p&gt;




&lt;p&gt;A bit of context: I&amp;rsquo;m a big fan of Apple products for seven years now (and I was a Linux user before). MacOS X is an impressive operating system: the geek inside me loves UNIX, the end user part of me likes the &amp;lsquo;everything works out of the box&amp;rsquo; side of the Mac experience.&lt;/p&gt;




&lt;p&gt;Long story short, I love this Windows Phone 7.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Tiles are awesome. Simple, no gradient, no round corners, ni shiny effect, just the fact. Data-ink ratio is very high, Tuft would be happy.&lt;/li&gt;
&lt;li&gt;Menus are kept to their minimum. There are not tons of options everywhere. Microsoft provided a very opiniated way of using the phone and they made the right choice almost every time.&lt;/li&gt;
&lt;li&gt;All in all, this Metro UI is particularly well thought. Navigation follows a consistent pattern through the OS. Third party applications tend to adopt it.&lt;/li&gt;
&lt;li&gt;Animations are plain right. Very subtle, never too long, they are visually pleasant and serve their purpose very well. They bring a sensation of fluidity and smoothness.&lt;/li&gt;
&lt;li&gt;No custom ringtones. That sounds ridiculous but it clearly shows the direction taken by the creators of the OS.&lt;/li&gt;
&lt;li&gt;Actually one of the only possible customisation is to change the dominant color. My favourite is Magenta. The color will be used almost everywhere in your phone. Elegant.&lt;/li&gt;
&lt;li&gt;The Mac software is simple and easy to use. It synchronises your phone with iTunes&#39; data. Don&amp;rsquo;t know if Apple appreciates but it works just fine&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I have mixed feelings about the web browser though. Navigation is fast and fluid but javascript performance and CSS handling sucks at best. The navigation bar disappear when you are in landscape mode. That&amp;rsquo;s quite weird. Microsoft says it is based on a mix of IE 7 and 8. Fortunately, they will ship IE9 with the next release of Windows Phone.
The stuff that could have been added without too much boilerplate:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They screwed up with the first update of the OS. It brought copy-pasting but deployment was a nightmare for Microsoft.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notification LED. My android phone had a small LED hiddden in the speaker. Even when you&amp;rsquo;re phone is in silent mode you can see in one eye glance if you&#39;vre a text or missed a call. &lt;em&gt;very&lt;/em&gt; useful&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No threads in emails. Epic fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No tethering. Annoying in the train.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No multiple calendars when synced with Google Calendar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I cannot find a good Remember The Milk app. WinMilk is way to slow to be usable (yeah, I know, it is open source it is up to me to improve it instead of complaining)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This week, Microsoft unveiled a new version of WP7 called &amp;lsquo;Mango&amp;rsquo; or WP7.5. This update brings &lt;em&gt;a lot&lt;/em&gt; of new features. Hopefully they won&amp;rsquo;t screw the whole Metro experience (fingers crossed).&lt;/p&gt;




&lt;p&gt;All in all, forget Windows Mobile 6.x, Microsoft changed everything. The subtle rename from Windows Mobile to Windows Phone is not innocent.&lt;/p&gt;




&lt;p&gt;I can&amp;rsquo;t believe I&amp;rsquo;ve just said something good about Microsoft software.&lt;/p&gt;

</description>
        <pubDate>Wed, 28 Dec 2011 13:54:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/12/28/windows-phone-7.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/12/28/windows-phone-7.html</guid>
      </item>
      
    
      
      <item>
        <title>Legacy projects</title>
        <description>&lt;p&gt;As a company or freelance developer you have probably encounter the dilemma of taking over somebody else code. On one side you are happy to get new work, on the other side dealing with legacy code can be frightening.&lt;/p&gt;




&lt;p&gt;Here are some questions you will need to ask when you continue and maintain a project:&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;What kind of client will you get when accepting the project?&lt;/li&gt;
&lt;li&gt;How was the relation between the previous developer and the client?&lt;/li&gt;
&lt;li&gt;Where is the project hosted? Do you have control over it?&lt;/li&gt;
&lt;li&gt;What are the dependencies of the project? Ruby 1.8.6, Rails 1.2? RMagick? Will you have to migrate it to newer versions at some point? Does the client understand that you &lt;em&gt;need&lt;/em&gt; to upgrade libraries and frameworks?&lt;/li&gt;
&lt;li&gt;More generally, is the client aware that software needs maintenance?&lt;/li&gt;
&lt;li&gt;Will you be the one responsible for old bugs that are discovered &lt;em&gt;after&lt;/em&gt; you took over the project? Usually the client sees a bunch a stuff not working once you start to work on the project.&lt;/li&gt;
&lt;li&gt;Have you considered a code review before accepting the project? Who did it? Someone external? The previous developer (hint: blink in red in your radar)?&lt;/li&gt;
&lt;li&gt;Will you need to implement big new features? How the previous developer used to bill the client for them?&lt;/li&gt;
&lt;li&gt;Is the client aware that you will probably be a bit slower than the previous developer when you start working on the project?&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Many of these questions sounds stupid or simple good sense but a checklist is never too much when it comes to such a tricky decision.&lt;/p&gt;




&lt;p&gt;Everybody likes to write &lt;em&gt;new&lt;/em&gt; code. Maintaining code is usually less appealing.&lt;/p&gt;




&lt;p&gt;I &lt;em&gt;love&lt;/em&gt; to dig in somebody else code,to refactor it, to understand what the previous developer had in mind when doing it. I like to remove the small imprecisions here and there and to curse when I see useless javascript files or two hundreds lines of commented code.&lt;/p&gt;

</description>
        <pubDate>Mon, 19 Dec 2011 19:51:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/12/19/legacy-projects.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/12/19/legacy-projects.html</guid>
      </item>
      
    
      
      <item>
        <title>Smalltalk &amp; native UI</title>
        <description>&lt;p&gt;From time to time, someone on the Pharo mailing list asks how to build a desktop application.&lt;/p&gt;




&lt;p&gt;A long time ago, Smalltalk was a great way to make desktop apps. drag &amp;amp; drop, rich visual interface, mouse pointer. Yeah, the mouse was quite a big thing.&lt;/p&gt;




&lt;p&gt;Things have changed. People expect consistency from the software they use. Not only in the look but also in the feel. They want their applications to be tightly integrated with their operating systems. If you&amp;rsquo;re considering a niche application where people only care about the functional part of the system, that could work. Otherwise I would not bet a penny on a smalltalk dialect.&lt;/p&gt;




&lt;p&gt;&lt;img src=&quot;http://tulipemoutarde.be/documents/blog-files/squeak4.3.png&quot; alt=&quot;Squeak 4.3 pre&quot; /&gt;
&lt;img src=&quot;http://tulipemoutarde.be/documents/blog-files/pharo1.4.png&quot; alt=&quot;Pharo 1.4 pre&quot; /&gt;
&lt;img src=&quot;http://tulipemoutarde.be/documents/blog-files/visualworks.jpg&quot; alt=&quot;Visualworks on MacOS&quot; /&gt;&lt;/p&gt;




&lt;p&gt;Long story short, don&amp;rsquo;t use Smalltalk if you want to be the next WordPad or iTunes.&lt;/p&gt;




&lt;p&gt;I&amp;rsquo;m not saying that Smalltalk is bad at user interfaces, new UI paradigms are tested with Smalltalk. &lt;a href=&quot;http://en.wikipedia.org/wiki/Croquet_Project&quot;&gt;Croquet&lt;/a&gt; and &lt;a href=&quot;http://newspeaklanguage.org/&quot;&gt;Newspeak&lt;/a&gt;, &lt;a href=&quot;http://gaucho.inf.usi.ch/&quot;&gt;Gaucho&lt;/a&gt; are examples of some innovations in user interfaces (one for collaborating in 3D world, the other for IDE and GUI framework).&lt;/p&gt;




&lt;p&gt;footnote: I actually have to mention that I&amp;rsquo;ve heard that &lt;a href=&quot;http://www.object-arts.com/&quot;&gt;Dolphin&lt;/a&gt; and &lt;a href=&quot;http://www.cincomsmalltalk.com/main/products/objectstudio/&quot;&gt;ObjectStudio&lt;/a&gt; runs natively fine on windows.&lt;/p&gt;

</description>
        <pubDate>Sun, 11 Dec 2011 13:26:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/12/11/smalltalk-native-ui.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/12/11/smalltalk-native-ui.html</guid>
      </item>
      
    
      
      <item>
        <title>Smalltalk for the Rubyist</title>
        <description>&lt;p&gt;After my previous post about the &lt;a href=&quot;http://articles.tulipemoutarde.be/the-pharo-smalltalk-ecosystem&quot;&gt;Pharo ecosystem&lt;/a&gt;, some people asked me more about a comparison of Smalltalk and Ruby. And how a Rubyist could leverage his knowledge when learning Smalltalk.&lt;/p&gt;




&lt;p&gt;The two languages are class based, dynamic and their supporters like their clean and easy syntax. Actually, Smalltalk is sometimes considered as one of the father of Ruby. They share quite a lot and most of the patterns used in one can be easily expressed in the other.&lt;/p&gt;




&lt;p&gt;This post does not cover the basic syntax of Smalltalk. If you want to learn it (15 minutes max), &lt;a href=&quot;http://en.wikipedia.org/wiki/Smalltalk#Syntax&quot;&gt;wikipedia&lt;/a&gt; should be enough.&lt;/p&gt;




&lt;h1&gt;Implementations&lt;/h1&gt;




&lt;p&gt;Ruby comes in different flavors: MRI, YARV, &lt;a href=&quot;http://rubini.us/&quot;&gt;Rubinius&lt;/a&gt;, &lt;a href=&quot;http://jruby.org/&quot;&gt;JRuby&lt;/a&gt;, &lt;a href=&quot;http://maglev.github.com/&quot;&gt;Maglev&lt;/a&gt;, etc. So does Smalltalk. The principal difference is that they are no &amp;ldquo;official&amp;rdquo; distribution. Every dialect has its own ecosystem and tools. Some are open source, some are proprietary.&lt;/p&gt;




&lt;p&gt;Choosing an implementation can be a quite challenging task. If you want to go the open source way:&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://squeak.org/&quot;&gt;Squeak&lt;/a&gt;, the most famous implementation. The project has quite a long history. The development seems to have slowed down a bit 3-4 years ago but Squeakers are working hard now.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.pharo-project.org/home&quot;&gt;Pharo&lt;/a&gt;, a fork of Squeak. The goal of the Pharoers is to produce a clean and industry-capable Smalltalk. It all started when some people were really pissed off by the inaction of the Squeak community. Backward compatibility was a pretext for doing nothing. Pharo moves fast and does not aim to stay backward compatible with Squeak. Many projects still runs on the two without a itch though.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://smalltalk.gnu.org/&quot;&gt;GNU Smalltalk&lt;/a&gt;, an alien implementation. You can use your favorite text editor with it. It is a clean implementation but it maybe misses a complete environment.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://amber-lang.net/&quot;&gt;Amber&lt;/a&gt;, a smalltalk that compiles to Javascript. Pretty young but already impressive. It can be used with Node.js or in the browser.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I&amp;rsquo;m not really interested in proprietary implementations but there are three big players in that field: &lt;a href=&quot;http://www.cincomsmalltalk.com/main/&quot;&gt;Cincom Smalltalk&lt;/a&gt;, &lt;a href=&quot;http://www.instantiations.com/products/vasmalltalk/index.html&quot;&gt;VA Smalltalk&lt;/a&gt;, &lt;a href=&quot;http://gemstone.com/products/gemstone&quot;&gt;Gemstone/S&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Gemstone is not only a Smalltalk implementation but also an extremly scalable object-database. Actually &lt;a href=&quot;http://maglev.github.com/&quot;&gt;Maglev&lt;/a&gt; is a Gemstone based products. If you&amp;rsquo;re serious about Ruby, you should definitely give Maglev a look.&lt;/p&gt;




&lt;p&gt;My favorite implementation is Pharo. I like the energy in the community and its direction. It is for me the best bet for the future. It very similar to squeak but this screenshot of the main menu is enough to convince me.&lt;/p&gt;




&lt;p&gt;&lt;img src=&quot;http://tulipemoutarde.be/documents/blog-files/squeak4.2-pharo1.4-menu.png&quot; alt=&quot;Pharo 4.2 and Pharo 1.4 world menu&quot; /&gt;&lt;/p&gt;




&lt;p&gt;You can follow &lt;a href=&quot;http://stackoverflow.com/questions/8426981/squeak-or-pharo-for-the-beginning-smalltalker&quot;&gt;this thread on stackoverflow&lt;/a&gt; to get the opinions of others.&lt;/p&gt;




&lt;h1&gt;The Environment&lt;/h1&gt;




&lt;p&gt;Here comes the biggest problem when learning Smalltalk. That&amp;rsquo;s where people usually get lost.
Smalltalk code does not lie on a plain text file. There are literally no &amp;ldquo;code time&amp;rdquo;, it&amp;rsquo;s always runtime. It would be like coding in an IRB session. You manipulate objects all the time. Consequences ?&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;You can inspect object in live. You are working with a webservice and want to inspect the answer? Just inspect the response.&lt;/li&gt;
&lt;li&gt;Change values on the fly. You wanna know what happens if that variable is &lt;code&gt;-5&lt;/code&gt; instead of &lt;code&gt;5&lt;/code&gt;? Change its value to see what happens.&lt;/li&gt;
&lt;li&gt;You can actually code in the debugger. The debugger (or a stacktrace) is not an analysis tool anymore. You can actually code in it. A method is missing? Oops. Create it on the fly and continue the execution from where it failed.&lt;/li&gt;
&lt;li&gt;Fast tests, all the time. &lt;a href=&quot;http://coreyhaines.com/&quot;&gt;Corey Haines&lt;/a&gt; teaches you how to get &lt;a href=&quot;http://arrrrcamp.be/videos/2011/corey-haines---fast-rails-tests/&quot;&gt;fast tests&lt;/a&gt; in rails. You do not need this in Smalltalk as your web/test/whatever framework are &lt;em&gt;already loaded&lt;/em&gt;. Of course, if your tests starts to rely on external depencies (disk/network/etc) without mocking, they&amp;rsquo;ll get slow. No surprises.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Actually some tools are starting to appear in Ruby. &lt;a href=&quot;http://pry.github.com/&quot;&gt;Pry&lt;/a&gt; is pretty damn cool Ruby tool. Once you&amp;rsquo;ll get used to Smalltalk environments you&amp;rsquo;ll want more.&lt;/p&gt;




&lt;p&gt;When you load a library in your image, it lies next to your code. You can then read it, inspect it, put breakpoint in it and do whatever you want with it.&lt;/p&gt;




&lt;p&gt;An image contains your code and all the libraries you want. It acts as a container and is completely independent from other images.&lt;/p&gt;




&lt;h1&gt;Metaprogramming, Object and Classes&lt;/h1&gt;




&lt;p&gt;Okay, that one is tricky. What do you expect from meta-programming?&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Adding methods on runtime? You are already in runtime.&lt;/li&gt;
&lt;li&gt;Handle &lt;code&gt;method_missing&lt;/code&gt;? Welcome &lt;code&gt;doesNotUnderstand&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;As &lt;code&gt;method_missing&lt;/code&gt; in Ruby, &lt;code&gt;doesNotUnderstand&lt;/code&gt; must be used carefully. The usual advice applies in Smalltalk.&lt;/p&gt;




&lt;p&gt;Actually defining a class in Smalltalk is just sending a message (&amp;ldquo;calling a method&amp;rdquo; in Smalltalk jargon) to the class &lt;code&gt;Object&lt;/code&gt;. Adding a method is also a matter of sending a message to define it. The only difference is that you use tools to do it. Remember, it&amp;rsquo;s runtime and your environment is the &lt;em&gt;running&lt;/em&gt; your code. That living environment comes with great responsibilities. If you try something along &lt;code&gt;Object := nil&lt;/code&gt; I guess you&amp;rsquo;re a footing yourself in the foot.&lt;/p&gt;




&lt;p&gt;If you want to learn more about the Smalltalk object system, I warmly recommend the chapter 13 of the &lt;a href=&quot;http://pharobyexample.org/&quot;&gt;Pharo By Example&lt;/a&gt; free book. If you don&amp;rsquo;t know that much about Ruby&amp;rsquo;s object system, I recommend the &lt;a href=&quot;http://scotland-on-rails.s3.amazonaws.com/2A04_DaveThomas-SOR.mp4&quot;&gt;Dave Thomas presentation&lt;/a&gt; at Scotland on Rails 2009.&lt;/p&gt;




&lt;h1&gt;Returns&lt;/h1&gt;




&lt;p&gt;Methods need explicit returns (with &lt;code&gt;^&lt;/code&gt;). If omitted, the method will return self.&lt;/p&gt;




&lt;p&gt;You get implicit returns for blocks: the value of the last instruction is the the value returned by the block. If you return (with &lt;code&gt;^&lt;/code&gt;) inside a block, it is a return value for the method.&lt;/p&gt;




&lt;h1&gt;Syntax Convention&lt;/h1&gt;




&lt;p&gt;Methods name and variables are spelled in CamelCase. Abbreviations are usually avoided. Smalltalk uses keyword based method name (as in Objective-C). Many Ruby libraries/framework mimic this by passing an hash as argument.&lt;/p&gt;




&lt;p&gt;The tabs vs. spaces does not exist in the Smalltalk community. In every tool, press &lt;code&gt;Tab&lt;/code&gt; to indent and you&amp;rsquo;re done.&lt;/p&gt;




&lt;p&gt;As usual, just keep the global syntax style of the project you&amp;rsquo;re working on.&lt;/p&gt;




&lt;h1&gt;Usual suspects&lt;/h1&gt;




&lt;p&gt;Be careful when using cascades, a common is mistake is the following:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;programmingLanguages := OrderedCollection new
  add: &#39;Ruby&#39;;
  add: &#39;Java&#39;;
  add: &#39;Haskell&#39;.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;In the end of the execution, programmingLanguages will be the String &lt;code&gt;Haskell&lt;/code&gt;. That&amp;rsquo;s because the method &lt;code&gt;add:&lt;/code&gt; returns its argument, not &lt;code&gt;self&lt;/code&gt;. To prevent this, send &lt;code&gt;yourself&lt;/code&gt; at the end of the cascade:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;programmingLanguages := OrderedCollection new
  add: &#39;Ruby&#39;;
  add: &#39;Java&#39;;
  add: &#39;Haskell&#39;;
  yourself.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Another trick of the the language is the evaluation order:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;3 + 4 * 5  #=&amp;gt; 35 and not 23&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Evaluation is done from left to right. Mathematical order is not preserved. Indeed, &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;*&lt;/code&gt; are simple methods. Smalltalk does not even know (and does not care) that it is executing mathematical instructions. You must use parenthesis to express precedence:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;3 + ( 4 * 5 ) #=&amp;gt; 23&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;h1&gt;Version Control&lt;/h1&gt;




&lt;p&gt;&lt;a href=&quot;&quot;&gt;My previous post&lt;/a&gt; will explain you how to version Smalltalk code. Do not expect &lt;code&gt;Git&lt;/code&gt;, &lt;code&gt;Mercurial&lt;/code&gt; or &lt;code&gt;Subversion&lt;/code&gt; (although they can be used as backends for Monticello).&lt;/p&gt;




&lt;h1&gt;Conclusion&lt;/h1&gt;




&lt;p&gt;Once again, this post is inspired by someone else doing &lt;a href=&quot;http://tore.darell.no/pages/javascript_eye_for_the_ruby_guy&quot;&gt;the same for Javascript&lt;/a&gt; (thanks Greg Spurrier for the link). The &lt;a href=&quot;http://squeakbyexample.org/&quot;&gt;Squeak by Example&lt;/a&gt; or &lt;a href=&quot;http://pharobyexample.org/&quot;&gt;Pharo By Example&lt;/a&gt; books are worth to read. Beware that the tools described in the book are sometimes outdated but the principles are still perfectly valid.&lt;/p&gt;

</description>
        <pubDate>Fri, 09 Dec 2011 11:55:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/12/09/smalltalk-for-the-rubyist.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/12/09/smalltalk-for-the-rubyist.html</guid>
      </item>
      
    
      
      <item>
        <title>The Pharo Smalltalk ecosystem</title>
        <description>&lt;p&gt;This post is intented to developers who&amp;rsquo;ve heard that Smalltalk is hot and sexy. A fraction of them have tried to download a &lt;a href=&quot;https://gforge.inria.fr/frs/download.php/29274/Pharo-1.3-13315-OneClick.zip&quot;&gt;One-Click version of Pharo&lt;/a&gt; and played a bit with the language by following a tutorial or two.&lt;/p&gt;




&lt;p&gt;So now they have a taste of Smalltalk but they do not get the entire picture, how the environment work, how people actually build and deploy software with it. If you are one of them, you&amp;rsquo;ll probably want to take some time to read this :)&lt;/p&gt;




&lt;h1&gt;Images and VMs&lt;/h1&gt;




&lt;p&gt;If you&amp;rsquo;ve downloaded a One-Click image, you haven&amp;rsquo;t experimented with the notion of image and VM in Smalltalk. Actually you have but not in an explicit way, you&amp;rsquo;ve simply clicked on an icon and got your environment. You&amp;rsquo;ve maybe &amp;lsquo;Quit and Save&amp;rsquo; and when reopening the application you had the same state than when you left. Easy.&lt;/p&gt;




&lt;p&gt;In pratice, Pharo works with an image running on top of a virtual machine. If you come from another scripting language, it certainly offers a REPL (e.g., IRB for Ruby). Think of the image as a dump of that REPL at a given moment.&lt;/p&gt;




&lt;p&gt;A Pharo image contains everything: your code, the tools and the libraries. You can load code into it, you can save it and restart it at any moment. This image is closed. That&amp;rsquo;s why you cannot use your text editor to edit Pharo code (actually you could but you certainly would not want that).&lt;/p&gt;




&lt;p&gt;The VM is usually something you should not care about. My advice is to use the one given by the Pharo website, it is tested by a Jenkins server and is the one people use the most.&lt;/p&gt;




&lt;p&gt;In a nutshell: download a VM and an image from &lt;a href=&quot;http://www.pharo-project.org/pharo-download]&quot;&gt;the official website&lt;/a&gt;. At this moment, the stable version is Pharo 1.3 and the image is CogVM-13307. I personnaly put the VM in the &lt;code&gt;/Applications&lt;/code&gt; folder on my Mac. The image comes with a &lt;code&gt;.changes&lt;/code&gt; and &lt;code&gt;.sources&lt;/code&gt; files. Keep them in the same directory than your image.&lt;/p&gt;




&lt;p&gt;Beware that the evolutions of the image and the VM are not tight. It is possible that a Pharo 1.3 image will run on a new VM version in two years.&lt;/p&gt;




&lt;p&gt;To start an image, double-click on it. If your OS does not get it, you can drag the image icon on the VM icon. That should work.&lt;/p&gt;




&lt;h2&gt;Version numbers&lt;/h2&gt;




&lt;p&gt;When you download the image, you can see the exact version you are downloading: &lt;code&gt;Pharo-1.3-13315.zip&lt;/code&gt;. It means that it is the 315th revision of Pharo 1.3. The 13xxx part is redundant with the Pharo-1.3.&lt;/p&gt;




&lt;p&gt;The VM has currently the name &lt;code&gt;CogVM-Mac-13307.zip&lt;/code&gt;. Which means it was frozen with the 307th revision of the Pharo image.&lt;/p&gt;




&lt;h1&gt;Source version control&lt;/h1&gt;




&lt;p&gt;Your code is in the image. You don&amp;rsquo;t even have a full text view of your nice classes. How do you persist it? So far, you&amp;rsquo;ve probably save your image and re-open it later. That&amp;rsquo;s the best way to lose everything if your image crashes (and that happens). It&amp;rsquo;s also not really handy if you&amp;rsquo;re not alone on the project.&lt;/p&gt;




&lt;p&gt;Monticello comes to the rescue. It is a version control system like Git, Subversion or Mercurial. The only difference is that it does not version files but classes and methods. That&amp;rsquo;s pretty great for an object-oriented language, isn&amp;rsquo;t it?&lt;/p&gt;




&lt;p&gt;Historically, &lt;a href=&quot;http://www.squeaksource.com&quot;&gt;Squeaksource&lt;/a&gt; is the &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt; of Smalltalk. It is old, ugly and slow but it works. A more modern alternative is &lt;a href=&quot;http://ss3.gemstone.com/&quot;&gt;SqueakSource3&lt;/a&gt;, which brings Squeaksource to the latest frameworks. There are less projects than in the original Squeaksource but you should use it for your new projects.&lt;/p&gt;




&lt;p&gt;&lt;a href=&quot;http://www.smalltalkhub.com/&quot;&gt;SmalltalkHub&lt;/a&gt; is on its way. It is not stable enough to be used in production but we are all waiting for it :)&lt;/p&gt;




&lt;p&gt;&lt;a href=&quot;http://www.jarober.com/&quot;&gt;James Robertson&lt;/a&gt; has made two (very short screencasts to help you get up and running. You won&amp;rsquo;t need more than 4 minutes to watch them.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://vimeo.com/20016315&quot;&gt;Smalltalk For You, episode 48&lt;/a&gt;, you&amp;rsquo;ll see how to save a package in a Monticello repository. Gives you all the basic information you need to know to use Monticello. Three minutes. That&amp;rsquo;s it.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://vimeo.com/20105609&quot;&gt;Smalltalk For You, episode 49&lt;/a&gt;, this screencast will show you how reload the code you saved in the previous screencast in a fresh image. A little more than one minute.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;Load external libraries&lt;/h1&gt;




&lt;p&gt;Loading code in your image is pretty easy. Open a Monticello Browser and add the repository from which you want to load code. Et voilà, done.&lt;/p&gt;




&lt;p&gt;The problem is that sometimes, a package has dependencies. So you end up losing 4 hours only to track the dependencies of the package and to figure out a load order. Metacello was designed to help you.&lt;/p&gt;




&lt;p&gt;A project can provide a &amp;ldquo;Metacello Configuration&amp;rdquo;. This configuration describes the dependencies and the load order of the project. Of course a configuration can load an other one. You can also tag versions of your project.&lt;/p&gt;




&lt;p&gt;When you want to use a project, the first thing to do is to find its MetacelloConfiguration. As of today, the lookup to find a configuration is:&lt;/p&gt;




&lt;ol&gt;
&lt;li&gt;Check if the project exists in &lt;a href=&quot;http://www.squeaksource.com/MetacelloRepository.html&quot;&gt;http://www.squeaksource.com/MetacelloRepository.html&lt;/a&gt;. This repo is a goldmine.&lt;/li&gt;
&lt;li&gt;If it is not there, check in the project repository if you find a &lt;code&gt;ConfigurationOfTheProject&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ask the Pharo-users mailing list.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;If your project is not trivial, you should write a ConfigurationOfYourProject. You can get inspiration from other configurations. I personnaly like the ConfigurationOfFuel.&lt;/p&gt;




&lt;p&gt;Once again, James Robertson has already covered the subject in his Smalltalk For You screencast series. &lt;a href=&quot;http://vimeo.com/23666930&quot;&gt;Episode 82&lt;/a&gt; shows you how to load GlorpDBX (an object-relational mapping package for Smalltalk) in a fresh image using Metacello Configuration in a little more than two minutes.&lt;/p&gt;




&lt;h1&gt;Good practices&lt;/h1&gt;




&lt;p&gt;Ok, so now you know the tools that are used by Pharo developers. Let&amp;rsquo;s move on to the next critical point: Good habits.&lt;/p&gt;




&lt;h2&gt;New image everyday&lt;/h2&gt;




&lt;p&gt;As you save your image and reopen it 16 hours later in exactly the same state, you are probably tempted to keep it forever and do all your development in it. So convenient.&lt;/p&gt;




&lt;p&gt;In theory only. With time, you experiment and create a bunch of stuff you won&amp;rsquo;t need. You have loaded  many external packages and you don&amp;rsquo;t know anymore which are your dependencies. Your image becomes bloated, it may eventually crash.&lt;/p&gt;




&lt;p&gt;The best way to avoid rotten images is to get a new one everyday. Download a stock Pharo image (or keep one somewhere locally) and load your MetacelloConfiguration. This will have two benefits:&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Your image is always clean and not bloated.&lt;/li&gt;
&lt;li&gt;You know that your code load and works. This way you are sure that your co-workers can load your code and deployment is smooth.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Keep your images organized&lt;/h2&gt;




&lt;p&gt;I&amp;rsquo;m sure you&amp;rsquo;ve already think about it but try to keep your different images organized. it is not hard to end up with dozens of Pharo images scattered across your hard drive. Try to keep things simple. For example, I keep a directory with all my stock images (Pharo 1.2, 1.3, the preversion of 1.4, Squeak, One-Clicks, etc).&lt;/p&gt;




&lt;p&gt;Choose a convention and stick to it.&lt;/p&gt;




&lt;h2&gt;Syntax conventions &amp;amp; micro decisions&lt;/h2&gt;




&lt;p&gt;Follow the conventions used by many Smalltalkers. Naming conventions as well as indentation. A &lt;em&gt;very&lt;/em&gt; good read is &lt;a href=&quot;http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X/ref=sr_1_1?ie=UTF8&amp;amp;qid=1323126529&amp;amp;sr=8-1&quot;&gt;Smalltalk Best Practices Patterns&lt;/a&gt; by Kent Beck. Follow this style your code will follow Smalltalk idioms. Actually, the patterns discussed are also valid for Ruby. So go and grab your copy.&lt;/p&gt;




&lt;h1&gt;Conclusion&lt;/h1&gt;




&lt;p&gt;I wanted to write this guide for a long time now. This &lt;a href=&quot;http://mirnazim.org/writings/python-ecosystem-introduction/&quot;&gt;article&lt;/a&gt; for Python convinced me to post it.&lt;/p&gt;




&lt;p&gt;I hope it will be useful for some folks who want to try Smalltalk (and its Pharo implementation). Feel free to email me or to comment if you have any question or suggestion. If you are a Ruby developer wanting to learn Smalltalk, please &lt;a href=&quot;mailto:tulipemoutarde@gmail.com&quot;&gt;drop me an email&lt;/a&gt;, I need your help for future posts !&lt;/p&gt;

</description>
        <pubDate>Tue, 06 Dec 2011 04:00:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/12/06/the-pharo-smalltalk-ecosystem.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/12/06/the-pharo-smalltalk-ecosystem.html</guid>
      </item>
      
    
      
      <item>
        <title>Available for work!</title>
        <description>&lt;p&gt;As I&#39;m getting more and more addicted to Pharo Smalltalk, I would like to offer my services as a&amp;nbsp; Smalltalk developer.&lt;/p&gt;


&lt;p&gt;I&#39;m a freelance contractor with a belgian VAT number but I also have a valid working permit for Canada (I&#39;m currently living in Vancouver, BC).&lt;/p&gt;


&lt;p&gt;If you are looking for a part-time developer with a Ruby/Rails/Javascript  background, do not hesitate to contact me (even for a chat), I&#39;m all  ears!&lt;/p&gt;

</description>
        <pubDate>Wed, 16 Nov 2011 11:54:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/11/16/available-for-work.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/11/16/available-for-work.html</guid>
      </item>
      
    
      
      <item>
        <title>Pharo development</title>
        <description>&lt;p&gt;I sometimes wonder why &lt;a href=&quot;http://www.pharo-project.org/&quot;&gt;Pharo&lt;/a&gt; has such difficulties to get a stable version. Even when a release comes out, it is not that rock solid.&lt;/p&gt;




&lt;p&gt;When building an image, you get code from various locations. Integrating everything together seems hard. For example, a package will use a syntax highlighting mechanism, which will be different that the one used in another package. Different shape, different quality, different patterns, it is hard to get the same foundation for everything when you cover many areas: gui, drawing, threads, locks, filesystem, etc.&lt;/p&gt;




&lt;p&gt;Smalltalk acts as a whole operating system, it is one of its strength but also one of its weakness. It sounds wrong when you are used to the Unix philosophy where one tools equals one function. Smalltalk breaks that and want to do everything by itself. It becomes nice when you want to do something that crosses different layers (&lt;a href=&quot;https://github.com/tobi/delayed_job&quot;&gt;delayed_job&lt;/a&gt; would be almost useless in Smalltalk); you start your image and everything runs inside it. You stop it, everything stops. Easy. The drawback is obvious: Smalltalk environments tend to reinvent the wheel all the time.&lt;/p&gt;




&lt;p&gt;When you consider this, you start to realize the tremendous amount of work done by the developers. They proceed by baby steps but they are going very far&amp;hellip; And I can&amp;rsquo;t wait to use &lt;a href=&quot;http://rmod.lille.inria.fr/coral/index.html&quot;&gt;Pharo for system scripting&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Mon, 10 Oct 2011 16:34:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2011/10/10/pharo-development.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/10/10/pharo-development.html</guid>
      </item>
      
    
      
      <item>
        <title>Ruby frustration</title>
        <description>&lt;p&gt;The more I code in Smalltalk, the more I find the flow of developing in Ruby annoying. What I really miss is a good way to navigate code, the debugging facilities and the runtime aspect of a Smalltalk dialect.&lt;/p&gt;




&lt;h1&gt;Code navigation&lt;/h1&gt;




&lt;p&gt;The browser is the standard way to browse code in Smalltalk. While it can be seen as cumbersome and ugly (in the look and the feel) compared to a native UI or a text editor, experienced smalltalkers have a love-hate relationship with their browser.&lt;/p&gt;




&lt;p&gt;&lt;img src=&quot;http://tulipemoutarde.be/documents/blog-files/pharo1.3-browser.png&quot; alt=&quot;Pharo 1.3 browser&quot; /&gt;&lt;/p&gt;




&lt;p&gt;When using it, you do not need to have 45 tabs opened in your web browser. Almost all the documentation you need is right there in front of you. Browsing the senders and implementors of a method is so easy and convenient. When you come back to a text editor and Ruby code it&amp;rsquo;s just a pain in the ass to perform changes in your code.&lt;/p&gt;




&lt;p&gt;As a developer you will spend (by far) much more time debugging and reading code than writing it, why not have a dedicated tool to browse it ?&lt;/p&gt;




&lt;h1&gt;Runtime&lt;/h1&gt;




&lt;p&gt;One of the most frustrating point when developing in Rails is how slow it becomes when your Gemfile grows. Running the test suite is so slow, it feels like the old &amp;lsquo;code-compile-run&amp;rsquo; cycle is back again. It&amp;rsquo;s not the tests that are slow per se but loading the environment. Each time you run a test, you wait for Rails to start while the actual time spent in the test(s) is negligible. Very frustrating when doing TDD.&lt;/p&gt;




&lt;p&gt;There are some tools to overcome this problem but it&amp;rsquo;s sometimes quite hard to get them working (more on this in a later post).&lt;/p&gt;




&lt;h1&gt;Debugging&lt;/h1&gt;




&lt;p&gt;Take the browsing tools and the always-runtime feature and you get easy debugging. The TDD flow get much better when you can create methods on the fly, navigate the stack and change the state of your object on the fly. In Rails, I&amp;rsquo;m used to run the test, see it fails, switch to my text editor and re-run the test. Tools like &lt;a href=&quot;http://pry.github.com/&quot;&gt;Pry&lt;/a&gt; makes things much more smooth but they are quite far from a live debugger.&lt;/p&gt;




&lt;h1&gt;Closing&lt;/h1&gt;




&lt;p&gt;This post is already far too long for and probably not very well illustrated but I hope you get the idea. I&amp;rsquo;m not saying that Smalltalk is better; all the goodness mentioned before have their drawbacks, mainly when it comes to deployment. As your code is always running, it can be quite cumbersome to deploy it on a server in a fresh state. There are tools to help but they are not as nice as what you get in the Ruby world. A lot of smalltalkers seem to have their own recipes to deploy. It can be quite disturbing for someone coming from Ruby.&lt;/p&gt;




&lt;p&gt;Anyway, I gonna try to illustrate my arguments in the next posts. Thanks for reading !&lt;/p&gt;

</description>
        <pubDate>Fri, 30 Sep 2011 14:15:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2011/09/30/ruby-frustration.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/09/30/ruby-frustration.html</guid>
      </item>
      
    
      
      <item>
        <title>Seaside session timeout</title>
        <description>&lt;p&gt;As usual, this post is most a reminder for myself but it can be useful for others. In previous version of Seaside (prior to 3.0), it was possible to change the default session timeout by using:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;application preferencesAt: #sessionExpirySecond put: 1200&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;It has changed with Seaside 3.0 and looked a bit more complicated now:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;application cache expiryPolicy configuration
  at: #cacheTimeout
  put: 1200&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;If I&amp;rsquo;m missing something, &lt;a href=&quot;http://twitter.com/fstephany&quot;&gt;tweet me&lt;/a&gt; :)&lt;/p&gt;

</description>
        <pubDate>Sun, 28 Aug 2011 15:27:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2011/08/28/seaside-session-timeout.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/08/28/seaside-session-timeout.html</guid>
      </item>
      
    
      
      <item>
        <title>Metacello configurations readability</title>
        <description>&lt;p&gt;I&amp;rsquo;m polishing a &lt;em&gt;very&lt;/em&gt; small package to interact with &lt;a href=&quot;http://www.ogone.be&quot;&gt;ogone&lt;/a&gt;, a payment platform, from a &lt;a href=&quot;http://seaside.st/&quot;&gt;Seaside&lt;/a&gt; application. So it&amp;rsquo;s time to write a Metacello configuration to share it easily.&lt;/p&gt;




&lt;p&gt;I always have hard time to read Metacello configurations and wonder if a vertical alignment wouldn&amp;rsquo;t help. Basically, I find this:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;baseline10: spec
  spec for: #common do: [
    spec blessing: #baseline.
    spec
      repository: &#39;http://www.squeaksource.com/ogone&#39;;
      package: &#39;Ogone-Core&#39;;
      package: &#39;Ogone-Seaside-Example&#39; with: [spec requires: &#39;Ogone-Core&#39;];
      package: &#39;Ogone-Tests&#39;           with: [spec requires: &#39;Ogone-Core&#39;].

    spec
      group: &#39;default&#39;         with: #(&#39;Core&#39; &#39;Seaside-Example&#39; &#39;Test&#39;);
      group: &#39;Core&#39;            with: #(&#39;Ogone-Core&#39;);
      group: &#39;Seaside-Example&#39; with: #(&#39;Ogone-Core&#39; &#39;Ogone-Seaside-Example&#39;);
      group: &#39;Tests&#39;           with: #(&#39;Ogone-Core&#39; &#39;Ogone-Test&#39;)
  ].&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;More readable than this:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;baseline10: spec
  spec for: #common do: [
    spec blessing: #baseline.
    spec
      repository: &#39;http://www.squeaksource.com/ogone&#39;;
      package: &#39;Ogone-Core&#39;;
      package: &#39;Ogone-Seaside-Example&#39; with: [spec requires: &#39;Ogone-Core&#39;];
      package: &#39;Ogone-Tests&#39; with: [spec requires: &#39;Ogone-Core&#39;].

    spec
      group: &#39;default&#39; with: #(&#39;Core&#39; &#39;Seaside-Example&#39; &#39;Test&#39;);
      group: &#39;Core&#39; with: #(&#39;Ogone-Core&#39;);
      group: &#39;Seaside-Example&#39; with: #(&#39;Ogone-Core&#39; &#39;Ogone-Seaside-Example&#39;);
      group: &#39;Tests&#39; with: #(&#39;Ogone-Core&#39; &#39;Ogone-Test&#39;)
  ].&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Am I the only one ?&lt;/p&gt;

</description>
        <pubDate>Wed, 24 Aug 2011 09:46:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2011/08/24/metacello-configurations-readability.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/08/24/metacello-configurations-readability.html</guid>
      </item>
      
    
      
      <item>
        <title>Too much Smalltalk</title>
        <description>&lt;p&gt;I&amp;rsquo;m using way too much Smalltalk these days, I find myself typing:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;@articles do |each|
  # do something with each
end&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;instead of:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;@articles.each do |article|
  # do something with article
end&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;when coding in Ruby. Stupid brain&amp;hellip;&lt;/p&gt;

</description>
        <pubDate>Sat, 13 Aug 2011 14:15:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2011/08/13/too-much-smalltalk.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/08/13/too-much-smalltalk.html</guid>
      </item>
      
    
      
      <item>
        <title>Pharo Smalltalk experience report, part I</title>
        <description>&lt;p&gt;Hi there, I&amp;rsquo;d like to share some of my latest experiments with &lt;a href=&quot;http://www.pharo-project.org/home&quot;&gt;Pharo&lt;/a&gt;. This post is not very well structured and certainly needs some polishing but time is scarce.&lt;/p&gt;




&lt;p&gt;I use Ruby and Rail for my daily work at &lt;a href=&quot;http://agilitic.com&quot;&gt;agilitic&lt;/a&gt;. I&amp;rsquo;ve always dabbled with Smalltalk (Squeak then Pharo) and wanted to build a real world project with it. &lt;a href=&quot;http://wapict.be&quot;&gt;Wapict.be&lt;/a&gt; was the ideal candidate: not too big while not trivial.&lt;/p&gt;




&lt;p&gt;The idea behind wapict is simple: become the reference of photography in &lt;a href=&quot;http://en.wikipedia.org/wiki/Wallonie_Picarde&quot;&gt;Wallonie-Picarde&lt;/a&gt;, a region of Belgium. We sell stock pictures in digital or printed format, provide photographers for events and experiment with photography techniques&amp;hellip;&lt;/p&gt;




&lt;p&gt;It started with a simple presentation website and has now some nice features for photographers. A lot more is planned (e.g., buy online with credit card) but the project is advanced enough to do a first post about it.&lt;/p&gt;




&lt;h2&gt;Stack&lt;/h2&gt;




&lt;p&gt;Currently, wapict is running with:&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Pharo 1.3&lt;/li&gt;
&lt;li&gt;Seaside 3.0.5&lt;/li&gt;
&lt;li&gt;XMLSupport&lt;/li&gt;
&lt;li&gt;Fuel 1.4&lt;/li&gt;
&lt;li&gt;Zinc HTTP server&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;All managed via &lt;a href=&quot;http://code.google.com/p/metacello/&quot;&gt;Metacello&lt;/a&gt; Configurations.&lt;/p&gt;




&lt;p&gt;The project runs with the &lt;a href=&quot;http://www.mirandabanda.org/files/Cog/VM/&quot;&gt;Cog VMs&lt;/a&gt;. Development is done on MacOS while the staging and production servers are running Linux. A big problem with Pharo is that there are no official supported VMs. You are there on your own and choosing a suitable VM can be tedious. Hopefully this will change in the future.&lt;/p&gt;




&lt;h2&gt;Persistence&lt;/h2&gt;




&lt;p&gt;The traffic is quite low and a single Pharo image can handle the load while sipping a coffee. Persistence is primitive right now: I serialize everything with Fuel on disk. Nothing really fancy but it works well for what I need.&lt;/p&gt;




&lt;p&gt;Pictures are stored on disk and are served with Nginx. The originals are kept private and are not accessible from the public.&lt;/p&gt;




&lt;h2&gt;Deployment&lt;/h2&gt;




&lt;p&gt;At work we use Git + Capistrano or Vlad to deploy our rails applications. My usual flow is as simple as:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;git pull
git commit -am &amp;quot;fixed bug #456&amp;quot;
git push
cap staging deploy&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;and hopla my code is in staging. Once validated, &lt;code&gt;cap production deploy&lt;/code&gt; deploys on the production box. Easy.&lt;/p&gt;




&lt;p&gt;It seems that there are no equivalent on Pharo or at least there are no common workflow, everybody has his own recipe to roll out new code.&lt;/p&gt;




&lt;p&gt;I have added a link in the admin section that loads the latest stable Metacello release available. So my deployment flow is:&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;commit modified packages&lt;/li&gt;
&lt;li&gt;update and commit metacello configuration&lt;/li&gt;
&lt;li&gt;login to the application and click on the update link.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Not too bad but I have to leave my Smalltalk environment to deploy. I&amp;rsquo;ll probably create a small webservice to perform administrative operations on the deployed image.&lt;/p&gt;




&lt;h2&gt;Tools&lt;/h2&gt;




&lt;p&gt;I only use the tools shipped with Pharo 1.3. Nothing really fancy but they work well. The default for code highlighting and code completion suit me.&lt;/p&gt;




&lt;p&gt;I rebuild my development image as often as possible. Two benefits: I&amp;rsquo;m sure the whole project is easily loadable in a fresh image all the time and the mess I introduce in my image when developing is cleaned.&lt;/p&gt;




&lt;h2&gt;Conclusion&lt;/h2&gt;




&lt;p&gt;All in all, i&amp;rsquo;m quite happy with Seaside and Pharo. It is really refreshing to work with those when doing Ruby and Rails all the day. I cannot stand Rails when it comes to flow anymore. It just doesn&amp;rsquo;t feel right. I love to develop web applications with Javascript: I can code the behaviour much more easily than with plain HTTP requests and I feel this kind of joy when developing with Seaside.&lt;/p&gt;




&lt;p&gt;What I really miss though is the possibility to login and open an IRB on a server. That&amp;rsquo;s quite dangerous in production but it helps a lot when checking the state of an application. What would be &lt;em&gt;really&lt;/em&gt; nice to have is a set of remote tools to browse and debug an image from the outside. Some uses RFB to do that but I find it clumsy and slow.&lt;/p&gt;




&lt;p&gt;I&amp;rsquo;ve recently discovered &lt;a href=&quot;http://code.google.com/p/tode/&quot;&gt;tODE&lt;/a&gt;, a development environment that runs on top of Seaside, I haven&amp;rsquo;t checked it yet but Dale Henrichs use it for 80% of his development.&lt;/p&gt;




&lt;p&gt;All in all, my dream is pretty simple: Pharo 1.4 with &lt;a href=&quot;http://forum.world.st/Ring-model-infrastructure-for-Pharo-td3081971.html&quot;&gt;Ring&lt;/a&gt;, &lt;a href=&quot;http://rmod.lille.inria.fr/coral/index.html&quot;&gt;Coral&lt;/a&gt; and &lt;a href=&quot;http://forum.world.st/Seaside-on-Pharo-Kernel-td3729573.html&quot;&gt;remote tools&lt;/a&gt; =)&lt;/p&gt;

</description>
        <pubDate>Thu, 11 Aug 2011 13:34:05 +0200</pubDate>
        <link>http://tulipemoutarde.be/2011/08/11/pharo-smalltalk-experience-report-part-i.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/08/11/pharo-smalltalk-experience-report-part-i.html</guid>
      </item>
      
    
      
      <item>
        <title>Dynamically add/remove the Seaside's toolbar on an application</title>
        <description>&lt;p&gt;I wanted to display or hide the tool bar on a Seaside application. It turned out to be pretty simple.&lt;/p&gt;




&lt;p&gt;To remove it:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;app configuration
   at: #rootDecorationClasses
   addAll: #()
   removeAll: (Array with: WAToolDecoration)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;And to show it:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;app configuration
    at: #rootDecorationClasses
    addAll: (Array with: WAToolDecoration)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Another useful snippet to retrieve an application from its name:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;WAAdmin defaultDispatcher handlerAt: &#39;wapict&#39;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Seasiders won&amp;rsquo;t find this exciting but this post is more a reminder for myself than anything else. If I&amp;rsquo;m doing something overcomplicated for nothing, shout my ignorance in the comments ;)&lt;/p&gt;

</description>
        <pubDate>Wed, 13 Jul 2011 16:04:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2011/07/13/dynamically-addremove-the-seasides-toolbar-on.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/07/13/dynamically-addremove-the-seasides-toolbar-on.html</guid>
      </item>
      
    
      
      <item>
        <title>Pharo mailing list weekly summary</title>
        <description>&lt;p&gt;Hey there,&lt;/p&gt;


&lt;p&gt;As said earlier, the Pharo mailing list weekly summary is now hosted on &lt;a href=&quot;http://www.pharo-project.org/news&quot;&gt;the main Pharo website&lt;/a&gt; (which is powered by &lt;a href=&quot;http://www.cmsbox.com/en/cms&quot;&gt;Cmsbox&lt;/a&gt;). The editing porcess is quite different from what I&#39;m used to. Neat for someone who is not computer savvy but disturbing for someone who writes everything with Markdown!&lt;/p&gt;


&lt;p&gt;As usual, I&#39;ve probably forgotten some important topics, so do not hesitate to comment ;)&lt;/p&gt;

</description>
        <pubDate>Mon, 28 Mar 2011 15:08:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2011/03/28/pharo-mailing-list-weekly-summary-6-migration.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/03/28/pharo-mailing-list-weekly-summary-6-migration.html</guid>
      </item>
      
    
      
      <item>
        <title>Pharo mailing list weekly summary</title>
        <description>&lt;p&gt;Once again, the week was very busy in the Pharo mailing list. It seems that Pharo 1.2 release is imminent. I skipped a massive amount of threads in this summary. If I removed something important for you, just shout and I&amp;rsquo;ll edit this post.&lt;/p&gt;




&lt;p&gt;Next week, the &lt;em&gt;Pharo mailing list weekly summary&lt;/em&gt; will move to the &lt;a href=&quot;http://www.pharo-project.org/&quot;&gt;official Pharo website&lt;/a&gt;. Yeah !&lt;/p&gt;




&lt;h2&gt;Events&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.inria.fr/inria-research-centre/lille-nord-europe/calendar/smalltalk&quot;&gt;Deep into Smalltalk&lt;/a&gt; took place this week, about 45 people attended. It seems that Mariano &lt;a href=&quot;http://forum.world.st/THANKS-a-lot-for-the-awesome-Deep-Smalltalk-School-td3349178.html&quot;&gt;enjoyed&lt;/a&gt; it very much! Presentation slides are available and courses were recorded. Videos are not there yet but I&amp;rsquo;ll update this post as soon as they are.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Announcements&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://www.tudorgirba.com/&quot;&gt;Doru&lt;/a&gt; announced the &lt;strong&gt;Glamorous Tool Project&lt;/strong&gt;. The goald is to build a set of Smalltalk development tools based on &lt;a href=&quot;http://www.moosetechnology.org/tools/glamour&quot;&gt;Glamour&lt;/a&gt;. Is this the future of Pharo development tools ? &lt;a href=&quot;http://forum.world.st/the-glamorous-toolkit-project-td3349849.html&quot;&gt;full thread&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is now an &lt;a href=&quot;http://code.google.com/p/cog/&quot;&gt;issue tracker for Cog&lt;/a&gt;. &lt;a href=&quot;http://forum.world.st/ANN-Cog-issue-tracker-td3347097.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Esteban released a new Cocoa VM: 5.7.4.1. This is a non Cog VM. This release adds no feature but small steps are better than big jumps. &lt;a href=&quot;http://forum.world.st/ANN-Cocoa-Squeak-VM-5-7-4-1-non-Cog-released-td3341972.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Umezawa-san told us that SIXX now works on Pharo 1.2 and Squeak 4.2. &lt;a href=&quot;http://forum.world.st/Fwd-SIXX-in-Pharo-1-2-td3337674.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;InterpretorSimulator is now working with the latest images. Pavel warned us that it is far from perfect that it should work with small headless images. &lt;a href=&quot;http://forum.world.st/InterpreterSimulator-reloaded-td3342295.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Benjamin built a new Morphic widget: &amp;ldquo;SwitchableTreeWidget&amp;rdquo;. It should works fine on Pharo 1.2 (expect problems with 1.3). Load it and tell him what you think. &lt;a href=&quot;http://forum.world.st/New-widget-td3344098.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Discussions&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;There are some discussions about using the SqueakSSL plugin with Pharo. That would help to use HTTPS. At the moment, &lt;a href=&quot;http://stunnel.org/&quot;&gt;stunnel&lt;/a&gt; is a possible solution. &lt;a href=&quot;http://forum.world.st/Fwd-Https-Url-in-Pharo-1-2-td3337616.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are plans to bring Pharo in the Apple Store. The discussion moved to Apple vs the rest of the world and the future of computing and licensing questions. &lt;a href=&quot;http://forum.world.st/Pharo-on-Apple-App-Store-td3334878.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hilaire asked how to get bigger cursor in Pharo. Apparently Torsten has worked on this. full threads &lt;a href=&quot;http://forum.world.st/Bigger-cursor-td3339402.html&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://forum.world.st/Bigger-cursor-td3339843.html&quot;&gt;there&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Laurent is doing TDD for GUI development. There are no special tools for this and Laurent struggled a bit with &lt;code&gt;#visible&lt;/code&gt; which always returns true. Ben showed the trick to detect if a window is closed. &lt;a href=&quot;http://forum.world.st/Assert-SystemWindow-not-visible-td3330492.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef tried to install OSProcess in his image and ran into trouble. Beware that you need a VM with the OSProcess plugin. &lt;a href=&quot;http://forum.world.st/OSProcess-td3338691.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alexandre explained different solution on how to run Smalltalk in a web browser.&lt;a href=&quot;http://forum.world.st/Kernel-td3335157i20.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hilaire ran into trouble when installing DejaVuBitmapFonts on Pharo core 1.3. Fernando shared the snippet he uses. &lt;a href=&quot;http://forum.world.st/Error-installing-DejaVuBitmapFonts-td3316606.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Problems with the integration process and the Hudson server for 1.2. &lt;em&gt;The Great and Perfect Release Cycle&lt;/em&gt; is not an easy goal. &lt;a href=&quot;http://forum.world.st/Pharo-1-2-and-test-failures-td3337119.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;That&amp;rsquo;s all folks, see you next week !&lt;/p&gt;

</description>
        <pubDate>Sat, 12 Mar 2011 07:48:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/03/12/pharo-mailing-list-weekly-summary-5.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/03/12/pharo-mailing-list-weekly-summary-5.html</guid>
      </item>
      
    
      
      <item>
        <title>Pharo mailing list weekly summary</title>
        <description>&lt;p&gt;Here is the weekly summary of the Pharo project mailing list. If I missed something or say something wrong, please shout at me in the comments.&lt;/p&gt;




&lt;p&gt;My hightlights of the week: at least three different project are in the tracks for a squeaksource replacement. Pharo 1.2 is almost out but everybody feels the need for a better infrastructure/process. If you want to get involved on this side and if you have enough time, do not hesitate to send your ideas and contributions.&lt;/p&gt;




&lt;h2&gt;Events&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Pharo Sprint in Lille. Saturday 12th March. Tell if you plan to go ;) &lt;a href=&quot;http://forum.world.st/About-the-sprint-saturday-12-td3333884.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The sprint in Bern went very well. You can get an overview of what happened during the sprint on &lt;a href=&quot;http://twitter.com/#!/search/pharosprint&quot;&gt;Twitter&lt;/a&gt;. To keep it short, Camillo worked on &lt;em&gt;KeyMappings&lt;/em&gt; (see &lt;a href=&quot;http://forum.world.st/ANN-More-on-Keymappings-td3325569.html&quot;&gt;this thread&lt;/a&gt; for more info), Lukas playing &lt;em&gt;WeakAnnouncements&lt;/em&gt; and &lt;em&gt;OB&lt;/em&gt;. Adrian, Jorge and Toon started a debugger based on Glamour. They worked hard to decouple the model from the GUI. Mircea built a new widget for searching multiple categories of items in the same time. All in all, Glamour becomes more and more important in Pharo. &lt;a href=&quot;http://forum.world.st/ANN-pharo-focused-sprint-bern-feb-26-td3251860.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stephan and Diego participated in &lt;a href=&quot;http://eindhoven.startupweekend.org/&quot;&gt;Eindhoven startup weekend&lt;/a&gt;. They got the innovation price. I could not find more information on the event website :/ &lt;a href=&quot;http://forum.world.st/Startup-weekend-success-td3328004.html&quot;&gt;full thread&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Releases&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;New release of &lt;a href=&quot;http://www.ofset.org/drgeo&quot;&gt;Dr Geo II: 11.03&lt;/a&gt;. &lt;a href=&quot;http://forum.world.st/ANN-Dr-Geo-II-release-11-03-for-Linux-Mac-Windows-td3335915.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Olivier released a &lt;a href=&quot;http://www.squeaksource.com/LDAPlayer/&quot;&gt;LDAP package&lt;/a&gt; and a &lt;a href=&quot;http://www.auverlot.fr/index.php?z=21&quot;&gt;tutorial&lt;/a&gt;. It is known to work on Pharo 1.2rc. full threads &lt;a href=&quot;http://forum.world.st/LDAPlayer-td3333079.html&quot;&gt;here&lt;/a&gt; and &lt;a&gt;there&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pharo 1.2 should be released. The infrastructure should be improved. At the moment time is lost in Metacello configurations for external packages. Stef reminds us this fact and want to see 1.2 final soon. One solution pushed by Doru would be to set a hard deadline one month before the release. Packages that do not work are removed from the distributon. Laurent pointed that the Linux process could also be a goot candidate. &lt;a href=&quot;http://forum.world.st/About-1-2-td3326052.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alexandre reminds us about the existence of &lt;a href=&quot;http://www.silversmalltalk.com/&quot;&gt;SilverSmalltalk&lt;/a&gt;. &lt;a href=&quot;http://forum.world.st/SilverSmalltalk-td3323486.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Users&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;More information about Squeaksource 3 on a thread. Nobody have heard about it before. As we have seen last week, the future looks promising. &lt;a href=&quot;http://forum.world.st/Pharo-Sources-Google-Hit-Ratio-td3318289.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are some discussions about the state of &lt;a href=&quot;http://en.wikipedia.org/wiki/Croquet_Project&quot;&gt;OpenCroquet&lt;/a&gt; (now known as &lt;a href=&quot;http://www.opencobalt.org/&quot;&gt;OpenCobalt&lt;/a&gt;). (&lt;a href=&quot;http://forum.world.st/OpenCroquet-Website-td3319189.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Good thread on TDD. &lt;em&gt;How many time should spend on tests?&lt;/em&gt;. Laurent gave a nice reference to &lt;a href=&quot;http://www.amazon.com/Test-Driven-Development-Practical-David-Astels/dp/0131016490&quot;&gt;Dave Astels book&lt;/a&gt;. If you dont know TDD or find it difficult to apply in practice, read the &lt;a href=&quot;http://forum.world.st/Good-reference-on-time-on-unit-testing-td3326543.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Good question from Edouard. He pointed a stupid method: &lt;em&gt;2 days&lt;/em&gt; vs. &lt;em&gt;2 day&lt;/em&gt;. The latter evaluates to the duration of 1 day. &lt;a href=&quot;http://forum.world.st/2-days-vs-2-day-td3325706.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dennis asked if it is possible to use russian fonts with the CogVM. &lt;a href=&quot;http://forum.world.st/Is-it-possible-to-setup-Russian-fonts-in-Pharo-Cog-VM-td3329185.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nullPointer experiences a &lt;strong&gt;very&lt;/strong&gt; slow package loading on Windows. Mariano reminds that &lt;a href=&quot;http://www.pharo-project.org/documentation/faq&quot;&gt;antivirus could be the root of the problem&lt;/a&gt;. &lt;a href=&quot;http://forum.world.st/Great-slowness-for-install-CLFramework-td3327888.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alexandre asked what &lt;a href=&quot;&quot;&gt;Coral&lt;/a&gt; is about. Documentation is lacking but according the authors it should work. The &lt;a href=&quot;http://www.auverlot.fr/pharo/coralinstall/&quot;&gt;only tutorial&lt;/a&gt; you will find about it is written in french and does not go very deep. &lt;a href=&quot;http://forum.world.st/Coral-td3335190.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef explained to Miguel how to get a diff between to versions on Monticello. It is the kind of thing you will obviously need one day. Bookmark this post ;) &lt;a href=&quot;http://forum.world.st/Monticello-diff-between-2-version-td3336953.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Laurent discovered that SSL is not supported on Pharo out of the box. Sven mentioned &lt;a href=&quot;http://www.squeaksource.com/SqueakSSL.html&quot;&gt;SqueakSSL&lt;/a&gt; but it does not seem to work on Pharo (MacOS and Linux seem problematic as well). Esteban proposed to use &lt;a href=&quot;http://www.stunnel.org/&quot;&gt;stunnel&lt;/a&gt; to create an SSL tunneling proxy. Not very elegant and straightforward but it works. &lt;a href=&quot;http://forum.world.st/Url-HTTPSocket-with-https-td3331103.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Olivier asked if there are any documents on how to create GUIs in Pharo. &lt;a href=&quot;http://www.pharocasts.com/&quot;&gt;Pharocasts&lt;/a&gt; were mentioned and Bill explained briefly the born of Morphic and Polymorph. &lt;a href=&quot;http://forum.world.st/GUI-td3333102.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef struggled to load &lt;a href=&quot;http://www.lukas-renggli.ch/smalltalk/magritte&quot;&gt;Magritte&lt;/a&gt; without &lt;a href=&quot;http://seaside.st/&quot;&gt;Seaside&lt;/a&gt;. He gave the snippet:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;Gofer it
  renggli: &#39;magritte2&#39;;
  package: &#39;ConfigurationOfMagritte2&#39;;
  load.

(ConfigurationOfMagritte2 project version: &#39;2.0.6&#39;) load: #(&#39;Core&#39;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Internal and discussions&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dale did a &lt;em&gt;solo sprint&lt;/em&gt; to fix the failing tests in Metacello and released a new version. full threads &lt;a href=&quot;http://forum.world.st/Metacello-Configuration-Pharo1-2-solo-sprint-Portland-Oregon-Saturday-and-Sunday-td3325475.html&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://forum.world.st/Fwd-Metacello-Metacello-1-0-beta-28-3-1-released-td3325601.html&quot;&gt;there&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef introduced RPackage, a rewrite of PackageInfo. &lt;a href=&quot;http://forum.world.st/introducing-RPackage-td3326084.html&quot;&gt;full thread&lt;/a&gt;. More discussion about it in this &lt;a href=&quot;http://forum.world.st/About-RPackage-td3330650.html&quot;&gt;other thread&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef continues his war against uncommented classes. It is sometimes &lt;strong&gt;very&lt;/strong&gt; difficult to use a class/package/framework when you do not know where to start. &lt;a href=&quot;http://forum.world.st/comments-comments-comments-again-td3326862.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Discussion about &lt;a href=&quot;http://www.infoq.com/articles/azul_gc_in_detail&quot;&gt;the Azul Pauseless garbage collector&lt;/a&gt;. If you are into the VM things, you could be interested with how it compare with the VisualWorks garbge collector. &lt;a href=&quot;http://forum.world.st/Azul-Pauseless-GC-td3326066.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Marcus have some news from the Hudson front. They now have a Mac (so mac VMs will probably soon get the benefits of the continuous integration server). The Cog Unix VMs are also continuously built. And there is a new build for Project Sista. &lt;a href=&quot;http://forum.world.st/Hudson-News-td3327917.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eliot wrote a &lt;a href=&quot;http://www.mirandabanda.org/cogblog/2011/03/01/build-me-a-jit-as-fast-as-you-can/&quot;&gt;blog post&lt;/a&gt; about JIT. &lt;a href=&quot;http://forum.world.st/another-blog-post-td3331940.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef warned the community about &lt;em&gt;XXX&lt;/em&gt;. He seems to approach people with (crazy) business plans. He sent proposals to VCs where he mentioned virtual key team members who are in fact not related with him. German did not have bad experience with &lt;em&gt;XXX&lt;/em&gt;. Anyway, be careful if you&amp;rsquo;re approached by a suspicious VC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pavel opened a &lt;a href=&quot;http://code.google.com/p/pharo/issues/detail?id=3782&quot;&gt;ticket&lt;/a&gt; to get pangrams for various language. &lt;a href=&quot;http://forum.world.st/pangrams-td3334971.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hilaire wants to get Locale works with a CogVM (to use it with the underpowered XO laptop). If you want to play with GDB and to dig into the VM the thread should interest you. &lt;a href=&quot;http://forum.world.st/COG-VM-and-Locale-td3331775.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://www.squeakdbx.org/&quot;&gt;SqueakDBX&lt;/a&gt; will get slots for &lt;a href=&quot;http://esug.org/wiki/pier/Promotion/SummerTalk&quot;&gt;SummerTalk&lt;/a&gt;. Three mentors, three students. Very good news for this project. &lt;a href=&quot;http://forum.world.st/ANN-ESUG-supports-once-again-SqueakDBX-td3334864.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The state of Smalltalk on tablets and mobile in &lt;a href=&quot;http://forum.world.st/Squeak-Pharo-Cuis-on-Android-td3333463.html&quot;&gt;this thread&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Benjamin announced that he (with Igor) managed to get a new Smalltalk kernel based on Pharo which is 2.2Mb and includes 230 classes. Impressive. This is very important to reach one the Pharo&amp;rsquo;s goal: have a minimal kernel from which needed packages are loaded. &lt;a href=&quot;http://forum.world.st/Kernel-td3335157.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;As usual, a lots of bugs were fixed and technical details were discussed both in the mailing list and in the &lt;a href=&quot;http://code.google.com/p/pharo/issues/list&quot;&gt;bug tracking system&lt;/a&gt;.&lt;/p&gt;

</description>
        <pubDate>Sat, 05 Mar 2011 14:03:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/03/05/pharo-mailing-list-weekly-summary-4.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/03/05/pharo-mailing-list-weekly-summary-4.html</guid>
      </item>
      
    
      
      <item>
        <title>Pharo mailing list weekly summary</title>
        <description>&lt;p&gt;End of week, time for the weekly Pharo digest. Following Ken Brown&amp;rsquo;s suggestion, I&amp;rsquo;ve renamed it &lt;em&gt;weekly summary&lt;/em&gt; to avoid the confusion with the digest you automatically get from mailing list servers.&lt;/p&gt;




&lt;p&gt;As I was on holidays, the summary will be short this week. If I missed something really important, let me know, I&amp;rsquo;ll edit this post.&lt;/p&gt;




&lt;h2&gt;Events&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://forum.world.st/ANN-pharo-focused-sprint-bern-feb-26-td3251860.html&quot;&gt;Pharo sprint organised&lt;/a&gt; in Bern this Saturday (26th October). The taks of the day is to discuss and improve the Pharo IDE. Anyone can join (Smalltalk newcomers are welcome).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Announces&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://www.moosetechnology.org/&quot;&gt;Moose&lt;/a&gt; is available in version 4.3. Moose is a platform for software and data analysis. (&lt;a href=&quot;http://forum.world.st/ANN-Moose-4-3-td3316625.html&quot;&gt;the announcement&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Miguel updated the configuration of OSProcess. The confifuration takes the &lt;a href=&quot;http://gemstonesoup.wordpress.com/2011/01/17/metacello-1-0-beta-28-unearthed/&quot;&gt;symbolic versions&lt;/a&gt; into account. OSProcess provides access to operating system functions (&lt;a href=&quot;http://forum.world.st/ANN-ConfigurationOfOSProcess-with-symbolic-versions-td3313985.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Benjamin wrote a Messenger application to run inside Pharo. Hopefully that could help the developers to communicate when working on Pharo. (&lt;a href=&quot;http://forum.world.st/Community-in-the-IDE-td2543540.html&quot;&gt;full thread&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Laurent wrote a simple &lt;a href=&quot;http://magaloma.blogspot.com/2011/02/xml-browser-with-pharo.html&quot;&gt;XML browser&lt;/a&gt;. Very handy ! (&lt;a href=&quot;http://forum.world.st/XML-browser-td3320622.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alexandre announced &lt;a href=&quot;http://metacellobrowser.dcc.uchile.cl/&quot;&gt;MetacelloBrowser&lt;/a&gt;. This tool seems to be the best friend of Metacello. (&lt;a href=&quot;http://forum.world.st/MetacelloBrowser-td3321023.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;User&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Adrien asked how to load OmniBrowser in PharoCore 1.3. Guillermo gave the magic command ;) (&lt;a href=&quot;http://forum.world.st/OmniBrowser-in-PharoCore-1-3-td3317323.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hilaire asked how to change the default font size (he is working on the XO laptop). It is always the kind of tips you eventually need. (&lt;a href=&quot;http://forum.world.st/StandardFonts-defautFont-td3317772.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;He also got some problems with the Cog VM and the locale plugin. (&lt;a href=&quot;http://forum.world.st/COG-and-locale-td3318081.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef asked how people reify XML and objects. Using XMLParser is always the same the same boring work. &lt;a href=&quot;http://forum.world.st/Pattern-for-reifying-XML-doc-td3319260.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Olivier asked how to change the Pharo logo in the IDE. This is also the kind of simple question that you will probably ask one day. (&lt;a href=&quot;http://forum.world.st/Replacing-the-pharo-logo-td3322504.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Pharo&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mariano is back after 25 days of holidays without internet. I guess I&amp;rsquo;ll have much more work for my weekly summaries now ;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef continues to comment FileSystem and asked the opinion of the community on some point. (&lt;a href=&quot;http://forum.world.st/Need-your-point-of-view-on-FSPath-and-others-td3313975.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The virtual sprint for Pharo 1.2 was a bit hard to organise because of timezones (&lt;a href=&quot;http://www.doodle.com/byvynpkmm87hc3x8&quot;&gt;doodle&lt;/a&gt;). I have no idea if it was successful though.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://squeaksource.com&quot;&gt;Squeaksource&lt;/a&gt; is down more and more often these days. As usual, people talked about possible replacements. There will be at least one alternative (Esteban has something, The Iliad guys and Esug are working and I&amp;rsquo;ve heard about a possible Squeaksource 3). Read the (&lt;a href=&quot;http://forum.world.st/SqueakSource-down-again-td3317484.html&quot;&gt;full thread&lt;/a&gt;) if you&amp;rsquo;re interested. &lt;a href=&quot;http://forum.world.st/Pharo-Sources-Google-Hit-Ratio-td3318289.html&quot;&gt;Another thread&lt;/a&gt; can also be a good read in you are in the version control thing. With the success of &lt;a href=&quot;http://github.com&quot;&gt;Github&lt;/a&gt;, it is crucial from a community perspective to have a nice place to host our beloved source code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another consulting company &lt;a href=&quot;http://www.channelregister.co.uk/2011/02/20/cobol_is_the_new_language_to_know/&quot;&gt;said&lt;/a&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote class=&quot;posterous_short_quote&quot;&gt;&lt;p&gt;Smalltalk or FoxPro should be junked or moved to a new system immediately as
a result of non-support and no further development of the environments.&lt;/p&gt;&lt;/blockquote&gt;




&lt;p&gt;You can imagine the reactions in the mailing list ;) &lt;a href=&quot;http://forum.world.st/Cobol-is-the-new-language-to-know-td3317188.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;State of Magma in Pharo by Miguel. Magma is an object-oriented database. &lt;a href=&quot;http://forum.world.st/Is-repository-down-for-Magma-td3321104.html&quot;&gt;thread&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading !&lt;/p&gt;

</description>
        <pubDate>Thu, 24 Feb 2011 13:02:24 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/02/24/pharo-mailing-list-weekly-summary-3.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/02/24/pharo-mailing-list-weekly-summary-3.html</guid>
      </item>
      
    
      
      <item>
        <title>Pharo mailing list weekly digest</title>
        <description>&lt;p&gt;End of the week, time for the Pharo weekly digest. This week was quite busy on the mailing list, if I overlooked something important, please comment this post.&lt;/p&gt;




&lt;p&gt;At some point, this digest will probably be hosted on the main &lt;a href=&quot;http://www.pharo-project.org/&quot;&gt;Pharo website&lt;/a&gt;. If you want to help, you are more welcome !&lt;/p&gt;




&lt;p&gt;I&amp;rsquo;ll be absent until Wednesday (Italy!), so I&amp;rsquo;ll probably miss some threads for the next digest :/&lt;/p&gt;




&lt;h2&gt;Pharo promotion&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Pharo board calls for Pharo support in the industry. It wants to create a legal infrastructure to collect funds to perform engineering tasks. The end goal is to streghten Pharo. The consortium is not limited to research groups and companies; individuals are welcome! If you are interested in Pharo, download the letter, sign it and send it back. It is &lt;strong&gt;crucial&lt;/strong&gt; to get a stronger open source Smalltalk. Beware that there are two versions of the letter, be sure to get the latest one. &lt;a href=&quot;http://forum.world.st/Call-for-Pharo-Support-important-td3306729.html&quot;&gt;See the thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stef created a &lt;a href=&quot;http://www.linkedin.com/e/hzbhb7-gkawp6l9-36/vgh/2558378/&quot;&gt;LinkedIn group&lt;/a&gt; for Pharo. It is quite successful (76 members so far).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Events&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;Laurent proposed to do some virtual sprint next week from monday to wednesday (evening &amp;ndash; France timezone). Check &lt;a href=&quot;http://www.doodle.com/byvynpkmm87hc3x8&quot;&gt;the Doodle&lt;/a&gt; if you want to join. (&lt;a href=&quot;http://forum.world.st/Pharo-1-2-virtual-sprint-td3305846.html&quot;&gt;full thread&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Misc&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Discussion about &lt;a href=&quot;https://www.hpi.uni-potsdam.de/hirschfeld/trac/SqueakCommunityProjects/wiki/designer&quot;&gt;the new GUI visual designer&lt;/a&gt; developed in HPI. This GUI designer targets Squeak but could be porter to Pharo. If I understood correctly, the authors use &lt;a href=&quot;https://www.hpi.uni-potsdam.de/hirschfeld/trac/SqueakCommunityProjects/wiki/signals&quot;&gt;Signal&lt;/a&gt; while Pharo has an explicit preference for &lt;a href=&quot;http://book.pharo-project.org/book/announcements/&quot;&gt;Announcements&lt;/a&gt;. The discussion moved to the old debate about GUI construction (should we use something like XML to describe a user interface ?), on the topic of how to integrate a big framework into Pharo and how to serialize smalltalk code. If you have followed the thread and if I missed something, please comment ! (&lt;a href=&quot;http://forum.world.st/A-new-GUI-visual-designer-td3067111.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There was a doubt that the introduction of the Hudson build server was putting too much stress on Squeaksource (which is clearly unstable). Stéphane mentions a &lt;em&gt;new cool server&lt;/em&gt;. I once heard about a SqueakSource-like project written in &lt;a href=&quot;http://www.iliadproject.org/&quot;&gt;iliad&lt;/a&gt; and running on top of (GNU Smalltalk)[&lt;a href=&quot;http://smalltalk.gnu.org/&quot;&gt;http://smalltalk.gnu.org/&lt;/a&gt;]. Is there a correlation ? (&lt;a href=&quot;http://forum.world.st/Hudson-and-Squeaksource-statistics-td3301186.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Janko announces a new version of Aida: Aida/web 6.2 Spring edition is out. Aida is a web framework written in Smalltalk. Janko uses it in production for years now. It is good to see that things are also moving outside the Seaside sphere. (&lt;a href=&quot;http://forum.world.st/ANN-Aida-Web-6-2-Spring-edition-is-out-td3301723.html&quot;&gt;full thread&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A recurring question on the Seaside mailing-list is how to make a multilanguage (I18n) application in Seaside (or Smalltalk in general). Sebastian wrote a &lt;a href=&quot;http://blog.flowingconcept.com/brandIt/multiligual-web-applications-design-ala-smalltalk&quot;&gt;blog post&lt;/a&gt; some time ago to explain his approach. There is a &lt;a href=&quot;http://book.pharo-project.org/book/Localisation&quot;&gt;dedicated chapter in the collaborative Pharo book&lt;/a&gt; as well. If I remember well, some others do not follow the same approach. Please comment if you do.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/pharo/issues/detail?id=3699&quot;&gt;A very important issue&lt;/a&gt; was reported and closed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two new success story were added on the website: a workflow platform called &lt;em&gt;Issys Tracking&lt;/em&gt; and &lt;em&gt;DrGeo&lt;/em&gt;, a scriptable tool used to teach geometry and mathematics in high school. More info on the &lt;a href=&quot;http://pharo-project.org/about/success-stories&quot;&gt;Pharo Website&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Cog Unix VM is now built with Hudson. The &lt;a href=&quot;http://rmod.lille.inria.fr/web/&quot;&gt;RMoD Team&lt;/a&gt; in Lille will soon get a Mac Mini to build the Mac VMs. (&lt;a href=&quot;http://forum.world.st/Hudson-Cog-Unix-build-td3302938.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A good reminder of how to call an external executable from an image. (&lt;a href=&quot;http://forum.world.st/Call-a-external-executable-file-What-is-the-best-option-td3303894.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dale explained how to load the latest Seaside in Pharo 1.2. Very nice and clear post. (&lt;a href=&quot;http://forum.world.st/Loading-Seaside-into-Pharo-1-2-core-td3305778.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/pharo/issues/detail?id=3609&quot;&gt;RPackage&lt;/a&gt; is &lt;a href=&quot;https://pharo-ic.lille.inria.fr/hudson/view/Pharo-TaskForces/job/Pharo%20RPackage%20All%20Tests/&quot;&gt;now built&lt;/a&gt; on the Hudson server. According to &lt;a href=&quot;http://code.google.com/p/pharo/issues/detail?id=3609&quot;&gt;ticket 3609&lt;/a&gt;, RPackage wants to replace PackageInfo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Awesome news from the &lt;a href=&quot;http://blog.doit.st/&quot;&gt;Cloudfork&lt;/a&gt; project: OpenID and OAuth support in Smalltalk. More info on a &lt;a href=&quot;http://blog.doit.st/2011/02/15/cloudforksso-openid-and-oauth-support-for-smalltalk/&quot;&gt;dedicated blog post&lt;/a&gt;. This project will help &lt;strong&gt;a lot&lt;/strong&gt; when it comes to integrate external APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The state of WeakAnnouncements was discussed in &lt;a href=&quot;http://forum.world.st/Working-with-weak-announcements-td3305802.html&quot;&gt;this thread&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;&lt;em&gt;Huge&lt;/em&gt;¨&lt;/em&gt; thread &lt;em&gt;could we agree to remove caseOf: and   caseOf:otherwise:&lt;/em&gt;. I reckon that I didn&amp;rsquo;t follow the whole stuff but the conversation seems interesting for those enlightened enough to understand. The discussion covers the new compiler &lt;em&gt;Opal&lt;/em&gt;. (&lt;a href=&quot;http://forum.world.st/could-we-agree-to-remove-caseOf-and-caseOf-otherwise-td3302475.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Olivier tries to use the &lt;a href=&quot;http://www.squeaksource.com/LDAPlayer.html&quot;&gt;LDAPlayer&lt;/a&gt; in Pharo. He needs to send requests to an LDAP server for a Seaside application. (&lt;a href=&quot;http://forum.world.st/Pharo-amp-LDAP-td3308841.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;German gave us a state of the &lt;a href=&quot;http://www.squeaksource.com/XMLRPC.html&quot;&gt;XMLRPC Project&lt;/a&gt; which is funded by &lt;a href=&quot;http://esug.org&quot;&gt;ESUG&lt;/a&gt;. He will focus on Pharo 1.1.1 and 1.2. It is broken in Squeak 4.2 at the momend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Levente &lt;a href=&quot;http://lists.squeakfoundation.org/pipermail/vm-dev/2011-February/006886.html&quot;&gt;proposed a fix&lt;/a&gt; for the UUID plugin problem. That will surely cures the headaches of some people.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nicolas pointed some stuff in the String API and possible replacements to make it more smalltalkish. (&lt;a href=&quot;http://forum.world.st/Smalltalk-string-API-td3308431.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HwaJong Oh works on a &lt;a href=&quot;http://en.wikipedia.org/wiki/Collada&quot;&gt;COLLADA&lt;/a&gt; file parser and wants to render it with &lt;a href=&quot;http://www.squeaksource.com/AlienOpenGL.html&quot;&gt;AlienOpenGL&lt;/a&gt;. Fernando said that he has stopped to maintain the AlienOpenGL package but that it should be complete and stable enough to perform the task (&lt;a href=&quot;http://forum.world.st/Render-a-COLLADA-mesh-with-OpenGL-td3308632.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Guillermo updates us about the state of Pharo 1.2. Hopefully we&amp;rsquo;ll see the official release quite soon ;) (&lt;a href=&quot;http://forum.world.st/1-2-Dev-Status-td3312363.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fernando likes the PragmaMenuBuilder. You should look at it if you haven&amp;rsquo;t yet. The discussion moved to the local and global searches for pragmas. (&lt;a href=&quot;http://forum.world.st/Menu-creation-and-invocation-td3311552.html&quot;&gt;full thread&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;See you next week !&lt;/p&gt;

</description>
        <pubDate>Fri, 18 Feb 2011 09:09:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/02/18/pharo-mailing-list-weekly-digest.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/02/18/pharo-mailing-list-weekly-digest.html</guid>
      </item>
      
    
      
      <item>
        <title>This week in the Pharo-Project mailing list</title>
        <description>&lt;p&gt;In the following weeks, I will try to provide a weekly digest of the activity going in the pharo-developer mailing list (and sometimes some bits from the Seaside mailing list).&lt;/p&gt;




&lt;p&gt;This digest will be biased by my own priorities and usage of Pharo. There are chances that &lt;em&gt;the commit you are waiting for ages that fix this broken hidden property in Pharo&lt;/em&gt; will not be part of my digest. Do not hesitate to comment if I forgot something important.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Laurent launched a new game last week: &lt;strong&gt;Comment of the Day Contest&lt;/strong&gt;. The principle is simple: every day a class without comment is randomly chosen. Mailing list participants propose a comment and at the end of the day, the best comment is integrated. It has generated some nice discussions so far.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://ci.pharo-project.org&quot;&gt;The Hudson server&lt;/a&gt; now builds a Seaside and runs all the tests in the Pharo 1.2 build. Continuous integration is definitely the big new thing in the Pharo community.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Esteban wrote a new article about the &lt;a href=&quot;http://smallworks.com.ar/en/community/Reef/&quot;&gt;Reef framework&lt;/a&gt;. Simply put, Reef is a framework on top of Seaside that let you build dynamic components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Joachim announced the release of &lt;a href=&quot;http://jniport.wikispaces.com/&quot;&gt;JNIPort 2.0&lt;/a&gt;. This library allows you invoke Java code from Smalltalk. The big change of this version is the port to Squeak/Pharo (previous versions were only running with VisualWorks).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tony &lt;a href=&quot;http://www.tonyfleig.com/smallthoughts/blog/tffiler&quot;&gt;published&lt;/a&gt; a great tool to manage external files with Monticello. When writing web applications you often have javascript/CSS/png files hanging around. It can be a mess to deal with Monticello on one side and Git/SVN on the other. &lt;a href=&quot;http://www.squeaksource.com/TFFiler&quot;&gt;TFFiler&lt;/a&gt; puts everything into Monticello. Very handy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New COG VMs are available: &lt;a href=&quot;http://www.mirandabanda.org/files/Cog/VM/VM.r2359/&quot;&gt;SimpleStackBasedCogit&lt;/a&gt; and &lt;a href=&quot;http://www.mirandabanda.org/files/Cog/VM/VM.r2361&quot;&gt;StackToRegisterMappingCogit&lt;/a&gt;. The latter one is faster but SimpleStackBasedCogit still exists just in case people find bugs with the StackToRegisterMappingCogit that are not in SimpleStackBasedCogit. SimpleStackBasedCogit is &amp;ldquo;mature&amp;rdquo;. See the &lt;a href=&quot;http://forum.world.st/new-Cog-VMs-available-td3263525.html&quot;&gt;whole thread&lt;/a&gt; for more technical details. Those VMs are no longer one-way street. With previous releases, once you had saved an image with a Cog VM you could not open it in a regular VM anymore. This is no longer the case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Guillermo &lt;a href=&quot;http://forum.world.st/copying-all-versions-to-squeaksource-td3263732.html&quot;&gt;shared a nice trick&lt;/a&gt; to push and load all versions to/from Squeaksource with &lt;a href=&quot;http://www.lukas-renggli.ch/blog/gofer&quot;&gt;Gofer&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Oscar posted a link to a &lt;a href=&quot;https://gforge.inria.fr/frs/download.php/28243/Settings.pdf&quot;&gt;draft chapter about the Settings Framework&lt;/a&gt;. It will be included in  &lt;a href=&quot;http://pharobyexample.org/&quot;&gt;&lt;em&gt;Pharo By Example 2&lt;/em&gt;&lt;/a&gt;. Comments are welcome.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There was a discussion about syntax highlighting for Smalltalk code in HTML pages. Laurent uses &lt;a href=&quot;http://softwaremaniacs.org/soft/highlight/en/&quot;&gt;highlight.js&lt;/a&gt; on the PharoCast website, Max Leske wrote a &lt;a href=&quot;http://buildinggitfs.blogspot.com/2010/04/smalltalk-brush-for-syntax-highlighter.html&quot;&gt;a brush for Syntaxhighlighter&lt;/a&gt; and Nick pointed that &lt;a href=&quot;http://pygments.org/&quot;&gt;Pygments&lt;/a&gt; supports Smalltalk syntax.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stephane announced that the talk of the &lt;a href=&quot;http://www.inria.fr/centre-de-recherche-inria/lille-nord-europe/agenda/smalltalk&quot;&gt;Deep into Smalltalk school&lt;/a&gt; will probably be recorded. &lt;em&gt;Deep into Smalltalk&lt;/em&gt; is five days of lectures about advanced Smalltalk topics given by a great selection of speaker. Make sure you attend if you&amp;rsquo;re interested by VMs, sockets, FFI or C-Smalltalk interactions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stephane decided to bring FileSystem into Pharo for real and posted a roadmap of what would be cool to have this package.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PharoConf in Annecy. Lots of tickets were processed. Congrats !&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Marcus &lt;a href=&quot;http://forum.world.st/Hudson-updates-td3300535.html&quot;&gt;gave the state&lt;/a&gt; of the Hudson build server for Pharo and related project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Of course, there were &lt;strong&gt;a lot&lt;/strong&gt; of bug fixes and improvements.&lt;/p&gt;




&lt;p&gt;See you next week !&lt;/p&gt;

</description>
        <pubDate>Fri, 11 Feb 2011 14:47:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/02/11/this-week-in-the-pharo-project-mailing-list.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/02/11/this-week-in-the-pharo-project-mailing-list.html</guid>
      </item>
      
    
      
      <item>
        <title>Javascript, The Good Parts</title>
        <description>&lt;p&gt;I&#39;ve just finished to read &lt;a href=&quot;http://oreilly.com/catalog/9780596517748&quot;&gt;Javascript: The Good
Parts&lt;/a&gt; of &lt;a href=&quot;http://www.crockford.com/&quot;&gt;Douglas
Crockford&lt;/a&gt;. If you&amp;rsquo;re doing Javascript
development you should read it if you haven&amp;rsquo;t.&lt;/p&gt;




&lt;p&gt;This book is not a definitive guide to Javascript but will show you
which part of the language to avoid if you want to eliminate a whole
class of problems.&lt;/p&gt;




&lt;p&gt;Here are some striking (at least for me) examples:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt; == &lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;content&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;   &lt;span class=&quot;comment&quot;&gt;// false&lt;/span&gt;
 &lt;span class=&quot;integer&quot;&gt;0&lt;/span&gt; == &lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;     &lt;span class=&quot;comment&quot;&gt;// true&lt;/span&gt;
 &lt;span class=&quot;integer&quot;&gt;0&lt;/span&gt; == &lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;content&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;    &lt;span class=&quot;comment&quot;&gt;// true&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;That&amp;rsquo;s because == tries to coerce the values if they are of different types.&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;
 {
   &lt;span class=&quot;key&quot;&gt;status&lt;/span&gt;: &lt;span class=&quot;predefined-constant&quot;&gt;true&lt;/span&gt;
 };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Will not return an object with a &lt;code&gt;status&lt;/code&gt; field. It will return
&lt;code&gt;undefined&lt;/code&gt;. Do you know why?&lt;/p&gt;




&lt;p&gt;Another nice one is the &lt;code&gt;parseInt()&lt;/code&gt; function.&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;parseInt(&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;content&quot;&gt;07&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;comment&quot;&gt;// returns 7&lt;/span&gt;
 parseInt(&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;content&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;comment&quot;&gt;// returns 0&lt;/span&gt;
 parseInt(&lt;span class=&quot;string&quot;&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;content&quot;&gt;09&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;comment&quot;&gt;// returns 0&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;That&amp;rsquo;s because when the first character of the parsed string is a zero,
it is evaluated in base 8. Seriously. In javascript. A high level
language. Wow.&lt;/p&gt;




&lt;p&gt;Don&amp;rsquo;t worry, the book is not only a compilation of the weird design
choices of Javascript. It will guide you through a world without global
variables and will show you how to use functions to create modules. You
will learn to master the prototypal object model and understand why the
&lt;code&gt;new&lt;/code&gt; construct in Javascript is evil.&lt;/p&gt;




&lt;p&gt;Highly recommended.&lt;/p&gt;

</description>
        <pubDate>Tue, 11 Jan 2011 14:08:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2011/01/11/javascript-the-good-parts-tags-javascript-boo.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2011/01/11/javascript-the-good-parts-tags-javascript-boo.html</guid>
      </item>
      
    
      
      <item>
        <title>HEMA Packaging &amp; Design</title>
        <description>&lt;p&gt;&lt;p&gt;I&#39;ve always liked HEMA shops. They basically all you need for everyday life. From candies, to socks through contact lenses, you always find what you need. Many of those goods and their packaging are greatly designed.&lt;p /&gt;I recently bought an economical light bulb. The packaging is great.&lt;p /&gt;&lt;div class=&#39;p_embed p_image_embed&#39;&gt;
&lt;img src=&#39;/images/2010/12/18380096-lightbulb-hema.jpg&#39;&gt;
&lt;/div&gt;
&lt;p /&gt;Check how informations are displayed. The socket size (E27) is on the socket. The luminosity on the light bulb. Simple and beautiful. No plastic.&lt;p /&gt;Now compare it with that.&lt;p /&gt;&lt;div class=&#39;p_embed p_image_embed&#39;&gt;
&lt;img src=&#39;/images/2010/12/18380243-philips.jpg&#39;&gt;
&lt;/div&gt;
&lt;p /&gt;HEMA has a great sense of functional design. Unfortunately, not all their products get the same love. Here is for example halogen lightbulb (no, I don&#39;t own a lightbulbs collection) package.&lt;br /&gt;&lt;div class=&#39;p_embed p_image_embed&#39;&gt;
&lt;img src=&#39;/images/2010/12/18380099-lightbulb3.jpg&#39;&gt;
&lt;/div&gt;
&lt;p /&gt;Sorry, it is open but I needed some light to shave this morning. The package is simple but it looks like any other brand. And it has unnecessary plastic.&lt;p /&gt;&lt;br /&gt;Their products reminds me an other line of products from &lt;a href=&quot;http://www.actulogo.fr/2010/11/mdr-la-mdd/&quot;&gt;Monoprix&lt;/a&gt;. The packagings were full of puns about the product.&lt;p /&gt;&lt;p /&gt;I&#39;m quite receptive to this kind of attention from the makers of the products I buy. Are you ?&lt;/p&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 07 Dec 2010 12:11:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2010/12/07/hema-packaging-design.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2010/12/07/hema-packaging-design.html</guid>
      </item>
      
    
      
      <item>
        <title>The ubiquitous Bancontact</title>
        <description>&lt;p&gt;I strongly believe that one day we will ge the &lt;em&gt;zero-note wallet&lt;/em&gt;. Your debit card (or your phone, or the &lt;a href=&quot;http://www.thecheers.org/Tech/article_734_Get-identified-under-your-skin.html&quot;&gt;RFID chip implanted in your arm&lt;/a&gt;)&amp;nbsp; will take over notes and coins.&lt;/p&gt;


&lt;p&gt;&lt;div class=&#39;p_embed p_image_embed&#39;&gt;
&lt;img src=&#39;/images/2010/11/16936339-Logo_Bancontact_Mister_Cash_tcm39-5406.jpg&#39;&gt;
&lt;/div&gt;
&lt;/p&gt;


&lt;p&gt;In Belgium, the main actor in the debit card market is Bancontact/Mistercash. It is virtually anywhere. I had my croissant and coffee in &lt;a href=&quot;http://www.lepainquotidien.be/&quot;&gt;Le Pain Quotidien&lt;/a&gt; this morning and tried to pay with Bancontact. The lady told me that I could not pay if the order is less than10&amp;euro;. What ? How many persons have a +10&amp;euro; breakfast ?&lt;/p&gt;


&lt;p&gt;I went to the local McDonalds to have another (much cheaper) coffee. Big sign on the cash machine &lt;em&gt;For your comfort and our safety, pay by debit card&lt;/em&gt;. Ok. Fine. When I gave my card, the cashier showed me sign in his back. &lt;em&gt;No Bancontact under 10&amp;euro;&lt;/em&gt;. Coffee is 1.75&amp;euro;. He let me pay by card but still.&lt;/p&gt;


&lt;p&gt;What&#39;s wrong with Bancontact ? Are the fees per transaction so high that shops lose money when the transaction is less than 10&amp;euro; ? If they want to be ubiquitous why are putting such a high barrier ?&lt;/p&gt;

</description>
        <pubDate>Mon, 01 Nov 2010 03:44:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2010/11/01/bancontact-mistercash.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2010/11/01/bancontact-mistercash.html</guid>
      </item>
      
    
      
      <item>
        <title>Design is more than pretty picture</title>
        <description>&lt;div style=&quot;&quot;&gt;
&lt;strong style=&quot;display: block; margin: 12px 0 4px;&quot;&gt;&lt;a href=&quot;http://www.slideshare.net/novaurora/10-things-ceos-need-to-know-about-design&quot;&gt;10 Things CEOs Need to Know About Design &lt;/a&gt;&lt;/strong&gt; 
&lt;object height=&quot;355&quot; width=&quot;425&quot;&gt;
&lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=bessemertalk-100512183606-phpapp01&amp;amp;stripped_title=10-things-ceos-need-to-know-about-design&quot; /&gt;
&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot; /&gt;
&lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot; /&gt; &lt;embed src=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=bessemertalk-100512183606-phpapp01&amp;amp;stripped_title=10-things-ceos-need-to-know-about-design&quot; type=&quot;application/x-shockwave-flash&quot; height=&quot;355&quot; width=&quot;425&quot;&gt;&lt;/embed&gt;
&lt;/object&gt;
&lt;/div&gt;


&lt;blockquote&gt;
&lt;div style=&quot;padding: 5px 0 12px;&quot;&gt;Talk benefits, not features&lt;/div&gt;
&lt;/blockquote&gt;


&lt;div style=&quot;padding: 5px 0 12px;&quot;&gt;Is my favorite quote of the presentation.&lt;/div&gt;

</description>
        <pubDate>Tue, 06 Jul 2010 03:58:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2010/07/06/design-is-more-than-pretty-picture.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2010/07/06/design-is-more-than-pretty-picture.html</guid>
      </item>
      
    
      
      <item>
        <title>Seaside WAAnchor fun</title>
        <description>&lt;p&gt;I&amp;rsquo;m currently playing with &lt;a href=&quot;http://seaside.st&quot; title=&quot;Seaside website&quot;&gt;Seaside&lt;/a&gt; (a Smalltalk web framework) for a pet project. As you maybe know, Seaside is, by default, not very friendly with URLs. I wanted to have bookmarkable URLs for user convenience and for search engine. Ramon Leon explains how he managed to get nice urls for his blog in a super-interesting &lt;a href=&quot;http://onsmalltalk.com/clean-urls-in-seaside&quot;&gt;blog post&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;When playing with WAAnchor methods, I fought with a weird behaviour:&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;html anchor
  callback: [self moveToPage: page];
  useBaseUrl;
  extraPath: page slug;
  with: page title.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;did not work, while&lt;/p&gt;




&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;html anchor
  useBaseUrl;
  extraPath: page slug;
  callback: [self moveToPage: page];
  with: page title.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;worked fine. Can you see the difference in these two snippets?&lt;/p&gt;




&lt;p&gt;The reason of the resulting bug is quite simple but is hard to spot when you&amp;rsquo;re not careful: the method &lt;code&gt;useBaseUrl&lt;/code&gt; should always be the first to be called in a method cascade on a WAAnchor. Indeed, both &lt;code&gt;extraPath:&lt;/code&gt; and &lt;code&gt;callback:&lt;/code&gt; will affect the url of the WAAnchor while &lt;code&gt;useBaseUrl&lt;/code&gt; will reset it. This reset will cancel all the operations you&amp;rsquo;ve done before on the url of the WAAnchor.&lt;/p&gt;




&lt;p&gt;Moral of the story: beware of side effect (or How I Learned to Stop Worrying and Love Functional Programming)&lt;/p&gt;

</description>
        <pubDate>Mon, 14 Jun 2010 15:10:00 +0200</pubDate>
        <link>http://tulipemoutarde.be/2010/06/14/seaside-waanchor-fun.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2010/06/14/seaside-waanchor-fun.html</guid>
      </item>
      
    
      
      <item>
        <title>Better, Faster, Stronger</title>
        <description>&lt;p&gt;Web development is a quite hot topic for developers these days. Some think that the web is the future and that native apps are a relic of the past. I would not say that it is that simple (iPhone/iPad apps anyone?) but it is clear that webapps work well for many tasks. &lt;p /&gt; Some years ago frameworks started to appear in order to facilitate the development of web applications. They promise faster development time, more robust application and easy maintenance. We all know that a silver bullet does not exist in software development but it&#39;s kinda funny to see what all those frameworks promise. Here are some excerpts from some website of them. &lt;p /&gt; &lt;h2&gt;&lt;a href=&quot;http://www.springsource.org/&quot;&gt;Spring&lt;/a&gt; (Java)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_short_quote&quot;&gt; &lt;br /&gt;Spring delivers significant benefits for many projects, increasing development productivity and runtime performance while improving test coverage and application quality. &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt; &lt;h2&gt;&lt;a href=&quot;http://cakephp.org/&quot;&gt;CakePHP&lt;/a&gt; (PHP)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_short_quote&quot;&gt; &lt;br /&gt;CakePHP enables PHP users at all levels to rapidly develop robust web applications. &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt; &lt;h2&gt;&lt;a href=&quot;http://www.iliadproject.org/&quot;&gt;iliad&lt;/a&gt; (Smalltalk)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_short_quote&quot;&gt; &lt;br /&gt;Iliad is a Smalltalk web application framework. It is designed to be simple and make web development as effective as possible. &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt; &lt;h2&gt;&lt;a href=&quot;http://www.catalystframework.org/&quot;&gt;Catalyst&lt;/a&gt; (Perl)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_short_quote&quot;&gt; &lt;br /&gt;Catalyst will make web development something you had never expected it to be: Fun, rewarding and quick. &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt; &lt;h2&gt;&lt;a href=&quot;http://www.symfony-project.org/&quot;&gt;Symfony&lt;/a&gt; (PHP)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_short_quote&quot;&gt; &lt;br /&gt;It [Symfony] provides an architecture, components and tools for developers to build complex web applications faster. &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt; &lt;h2&gt;&lt;a href=&quot;http://rubyonrails.org/&quot;&gt;Ruby on Rails&lt;/a&gt; (Ruby)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_medium_quote&quot;&gt; &lt;br /&gt;Ruby on Rails is an open-source web framework that&#39;s optimized for programmer happiness and sustainable productivity. It lets you write beatiful code by favoring convention over configuration. &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt;  &lt;br /&gt;&lt;h2&gt;&lt;a href=&quot;http://pylonshq.com/&quot;&gt;Pylons&lt;/a&gt; (Python)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_short_quote&quot;&gt; &lt;br /&gt;Pylons is a lightweight web framework &lt;br /&gt;emphasizing flexibility and rapid development &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt; &lt;h2&gt;&lt;a href=&quot;http://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt; (Python)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_short_quote&quot;&gt; &lt;br /&gt;Django makes it easier to build better Web apps more quickly and with less code. &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt; &lt;h2&gt;&lt;a href=&quot;http://www.seaside.st&quot;&gt;Seaside&lt;/a&gt; (Smalltalk)&lt;/h2&gt;&lt;blockquote class=&quot;posterous_short_quote&quot;&gt; &lt;br /&gt;Seaside provides a layered set of abstractions over HTTP and HTML that let you build highly interactive web applications quickly, reusably and maintainably. &lt;br /&gt;&lt;/blockquote&gt; &lt;p /&gt; Wow with all those promises, you have no excuse to deliver crappy webapps. I like those headlines have no meaning at all. Do not trust someone who is pretending that everything will be easy with his tool/framework. Except when the tool in question is Clojure or Smalltalk of course :)&lt;/p&gt;
</description>
        <pubDate>Fri, 02 Apr 2010 09:17:14 +0200</pubDate>
        <link>http://tulipemoutarde.be/2010/04/02/better-faster-stronger.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2010/04/02/better-faster-stronger.html</guid>
      </item>
      
    
      
      <item>
        <title>On API Consistency</title>
        <description>&lt;p&gt;&lt;p&gt;Interacting with a well design API is a pleasure. When an interface is consistent and works in the way I expect it to work I feel good. Gregory T. Brown wrote an &lt;a href=&quot;http://blog.rubybestpractices.com/posts/gregory/rbp-ch2-3.html&quot;&gt;excellent chapter&lt;/a&gt; on this subject in his (now freely available) book &#39;Ruby Best Practices&#39;. &lt;p /&gt; Something struck me in jQuery last week: map() and each()&#39;s parameters. &lt;p /&gt;  From &lt;a href=&quot;http://jqapi.com/&quot;&gt;jQuery&#39;s documentation&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;terminal&quot;&gt;.map( callback(index, domElement) ) .each( function(index, Element) ) jQuery.each( collection, callback(indexInArray, valueOfElement) ) jQuery.map( array, callback(elementOfArray, indexInArray) )&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;&lt;br /&gt;Ok, what&#39;s the deal ? &lt;br /&gt;Look at the parameters of the callback of jQuery.map(). The order is different than all the others. Why?&lt;p /&gt; This kind of things drives me nuts.&lt;/p&gt;&lt;/p&gt;
</description>
        <pubDate>Sat, 20 Mar 2010 04:03:00 +0100</pubDate>
        <link>http://tulipemoutarde.be/2010/03/20/on-api-consistency.html</link>
        <guid isPermaLink="true">http://tulipemoutarde.be/2010/03/20/on-api-consistency.html</guid>
      </item>
      
    
  </channel>
</rss>
