<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Phusion Corporate Blog</title>
	<atom:link href="http://blog.phusion.nl/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.phusion.nl</link>
	<description></description>
	<lastBuildDate>Fri, 12 Mar 2010 17:16:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Creating our very first Mac application with Ruby, how exciting!</title>
		<link>http://blog.phusion.nl/2010/03/12/creating-our-very-first-mac-application-with-ruby-how-exciting/</link>
		<comments>http://blog.phusion.nl/2010/03/12/creating-our-very-first-mac-application-with-ruby-how-exciting/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 13:09:00 +0000</pubDate>
		<dc:creator>Jean Pierre Hernandez</dc:creator>
				<category><![CDATA[MacRuby]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=509</guid>
		<description><![CDATA[People always ask me why I never find a programming language for the Mac and settle down down down. C&#8217;est absolument incroyable indeed as the answer should be pretty straight forward to those who have already written an application for the Mac using Objective-C.
As a matter of fact, in France, raising such a question is [...]]]></description>
			<content:encoded><![CDATA[<p>People always ask me why I never find a programming language for the Mac and settle down down down. C&#8217;est absolument incroyable indeed as the answer should be pretty straight forward to those who have already written an application for the Mac using Objective-C.</p>
<p>As a matter of fact, in France, raising such a question is like asking whether or not Camembert goes well with French fries or not. The answer to this question is obvious as it&#8217;s a known fact that Camembert goes well with everything. Seeing as not everyone is blessed with a taste for fine French cuisine and/or is from French héritage however, I&#8217;ll try to give an approximation in this blog.</p>
<p><img src="http://media.tumblr.com/tumblr_kw275hreIS1qayff0.jpg" /></p>
<p>For this, we need to emphasize the differences of developing Mac applications with and without MacRuby.</p>
<p>After setting up MacRuby as described <a href="http://blog.phusion.nl/2010/03/12/a-gentle-introduction-to-macruby/">in our previous blog post</a> and having set up Xcode, it is now time to create our very first Mac application in Ruby. In this series of articles, we assume that you have the latest version of OS X installed on your Mac. By the time of this writing, that is Snow Leopard and it is important to emphasize this seeing as some Cocoa API methods have been deprecated or added since its last iteration. Without further ado, allons-y!</p>
<h2>Creating a new project</h2>
<p>After starting up Xcode:</p>
<ol>
<li>Select File</li>
<li>Select New Project</li>
</ol>
<p>A dialog window as shown below should appear.</p>
<p><img src="http://media.tumblr.com/tumblr_kw0367Syhm1qayff0.png" /></p>
<p>From this window</p>
<ol>
<li>Select MacRuby application</li>
<li>Click on Choose&#8230;</li>
</ol>
<p>A file save dialog should now appear as displayed below.</p>
<p><img src="http://media.tumblr.com/tumblr_kw03egcWtw1qayff0.png" /></p>
<p>In this window:</p>
<ol>
<li>Type in <i>BornToBeAlive</i> as our project name.</li>
<li>Click on Save.</li>
</ol>
<p>A new window should now appear representing the newly created project in the Xcode environment.</p>
<p><img src="http://media.tumblr.com/tumblr_kw03jwPEMz1qayff0.png" /></p>
<p>By the time of this writing our environment is setup to target OS X 10.5 (Leopard). As mentioned before, we&#8217;re going to target OS X 10.6 (Snow Leopard) seeing as we want to utilize the most mature Cocoa API and platform. As such we need to set this target environment to OS X 10.6 in the overview popup menu.</p>
<p><img src="http://media.tumblr.com/tumblr_kw03paLXXk1qayff0.png" /></p>
<p>Now that that&#8217;s been dealt with, we can finally really start working on our application.</p>
<h2>Designing our Interface</h2>
<p>Before we&#8217;re going to write even a single line of code, let&#8217;s first start off by designing the user interface to our application. To do this, we first need to discuss how our programming environment deals with this kind of information.</p>
<p>Certain information about our interfaces, in particular the one&#8217;s we&#8217;ve created using Interface Builder (the UI design application of Xcode) are usually stored in bundles called NIB files.</p>
<p>As of Xcode 3, these are actually stored in files with the <em>xib</em> file extension as opposed to the <em>nib</em> file extension. Worry not however, as they are just different formats for storing the same information: where <em>xib</em> files appear to be represented as XML text files, a <em>nib</em> file is an archive. More importantly however, the difference between <em>xib</em> and <em>nib</em> files are that the former will be compiled within the executable and will not appear in the final <em>.app</em> bundle.</p>
<p>In general, Xcode will ultimately know what to do with these files and how to treat them. It is for this reason that we&#8217;ll refer to both formats as <em>nib</em> files and basically assume no distinction between them.</p>
<p>In the <em>Groups &amp; Files</em> panel, expand the <em>NIB Files</em> group.</p>
<p><img src="http://media.tumblr.com/tumblr_kw08qzpuuf1qayff0.png" /></p>
<p>In this panel</p>
<ol>
<li>Double click on <em>MainMenu.xib</em></li>
</ol>
<p>This action should result in Interface Builder firing up for this <em>MainMenu.xib</em> file. Various windows of Interface Builder should now be visible to you.</p>
<p>In the MainMenu.xib window:</p>
<p><img src="http://media.tumblr.com/tumblr_kw0908fBao1qayff0.png" /></p>
<p>You see a collection of objects and proxy objects that are necessary for describing our user interface. The objects displayed in this window are objects that describe our application&#8217;s user interface and are stored in a freeze dried manner, i.e. serialized. Upon loading the NIB file, they get thawed and instantiated again.</p>
<p>In light of this, it is considered good practice to store only one window object per nib file. This way, we only load in the windows when we really need them (thus conserving memory) and will keep our design more maintainable too as each window and its components will be contained by its own NIB file. The latter will allow us to possibly recycle NIB files too in other projects.</p>
<p>Strictly speaking, we also shouldn&#8217;t store a window in our <em>MainMenu.xib</em> as is now the case, but in order to load this in, we require a notion of delegates. The latter is something we&#8217;ll discuss in a later article so for now, we&#8217;ll keep the window object in <em>MainMenu.xib</em>.</p>
<p>For now:</p>
<ol>
<li>Double click on <em>Window</em></li>
</ol>
<p>This should put the focus on our initial window and via the inspector, we can edit some of its properties, such as the title of the window instance.</p>
<p>While having selected the Window in the <em>MainMenu.xib</em> window, in the inspector window:</p>
<ol>
<li>Select the first tab, so that the inspector window is displaying the Window Attributes.
<p><img src="http://media.tumblr.com/tumblr_kw094qPOez1qayff0.png" /></p>
</li>
<li>Edit the Title field to <em>Born to be Alive<em>
<p><img src="http://media.tumblr.com/tumblr_kw099suATZ1qayff0.png" /></p>
</li>
<li>Hit the enter key</li>
</ol>
<p>Your window should now bare the title <em>Born to be Alive</em>. How exciting!</p>
<p><img src="http://media.tumblr.com/tumblr_kw09boAO641qayff0.png" /></p>
<p>Let&#8217;s add a <em>Label</em> to this window proclaim this message of life even bigger. To add cocoa components to our window, we need to drag and drop them from our <em>Library</em> panel to the window we want to add them to.</p>
<p>In the <em>Library</em> panel:<br />
<img src="http://media.tumblr.com/tumblr_kw09js3LFd1qayff0.png" /></p>
<ol>
<li>Set the focus on the search field at the bottom of the <em>Library</em> panel.</li>
<li>Type in Label. Notice that as we type character per character, the components get filtered based on our query.</li>
</ol>
<p>Your <em>Library</em> panel should now display a few options for labels and should look something like the following:</p>
<p><img src="http://media.tumblr.com/tumblr_kw09pyr4vS1qayff0.png" /><br />
Note that my <em>Library</em> panel will most likely display more options here in terms of labels as I&#8217;ve also installed the <a target="_blank" href="http://brandonwalkin.com/bwtoolkit/">BWToolkit</a> palette too. We won&#8217;t be using any of those components for our MacRuby applications though, so it&#8217;s safe for you to ignore them for now.</p>
<p>Now it&#8217;s time to actually add the <em>Label</em> component to our window. As mentioned earlier on, we do this by simply dragging and dropping the <em>Label</em> icon from our <em>Library </em>panel to the window we want to add it to. Doing so should result in something similar to the following:</p>
<p><img src="http://media.tumblr.com/tumblr_kw09sx05ji1qayff0.png" /></p>
<p>Great! Let&#8217;s rename the newly added <i>Label</i> to something more fitting. In the window displayed above:</p>
<ol>
<li>Double click on the newly added <em>Label. </em>This should now open up the ability to edit value of this <em>Label</em>.
<p><img src="http://media.tumblr.com/tumblr_kw09v13zoQ1qayff0.png" /></p>
</li>
<li>Type in <em>Born</em>
<p><img src="http://media.tumblr.com/tumblr_kw09vuL2fw1qayff0.png" /></p>
</li>
<li>Hit the enter key.</li>
</ol>
<p>Your window should now look something like this:</p>
<p><img src="http://media.tumblr.com/tumblr_kw09ziBfrF1qayff0.png" /></p>
<p>Wouldn&#8217;t it be fun if we would have a button that we could press to unveil the full message of life? Let&#8217;s do just that by adding a button to the window we&#8217;re designing.</p>
<p>In the <em>Library </em>panel:</p>
<ol>
<li>Type <em>Button</em> in the search box at the bottom of the <em>Library</em> panel. In a similar fashion as the label, it should filter away the components that do not match the <em>Button</em> search description.
<p><img src="http://media.tumblr.com/tumblr_kw0a8qWmWz1qayff0.png" /></p>
<p>Whoah, so many buttons! Let&#8217;s just stick with the first shiny one for now.</p>
</li>
<li>Drag and drop the first button that appears in the filtered selection to our window. Depending on where you dragged and dropped the button to, your window should now look something like this:
<p><img src="http://media.tumblr.com/tumblr_kw0abtwk8l1qayff0.png" /></p>
</li>
<li>Double click on the newly added button to be able to edit its title.
<p><img src="http://media.tumblr.com/tumblr_kw0ad2T2V11qayff0.png" /></p>
</li>
<li>Type in <em>Unveil full message</em>
<p><img src="http://media.tumblr.com/tumblr_kw0aefhMLg1qayff0.png" /></p>
</li>
<li>Hit the enter key.</li>
</ol>
<p>Your window should now be shaping up pretty nicely and look something like:</p>
<p><img src="http://media.tumblr.com/tumblr_kw0afhCu5H1qayff0.png" /></p>
<p>We can actually build this project at this stage and see what we&#8217;ve just designed in the form of a real application! Indeed, the standard MacRuby cocoa template has set up most of the boilerplate to get us started. At a later stage, we&#8217;ll dive into the details of the bootstrapping process, but for now let&#8217;s just assume that it set it up all correctly and save our changes by selecting File-&gt;Save from the Interface Builder main menu.</p>
<p><img src="http://media.tumblr.com/tumblr_kw0ajj9I821qayff0.png" /></p>
<p>Compiling is not the task of Interface Builder, but the task of Xcode so let&#8217;s switch back to Xcode. In the project window, click on the <em>Build and Run</em> button in its toolbar.</p>
<p><img src="http://media.tumblr.com/tumblr_kw0anmv30j1qayff0.png" /></p>
<p>After compiling for a few seconds and linking all the dependencies, your new application should launch in your OS X dock, and in particular, the window you just designed should show up.</p>
<p>Clicking on the <em>Unveil full message button</em> doesn&#8217;t do a lot though, but that should come as no surprise seeing as we&#8217;ve only been designing the interface up to this point. We haven&#8217;t yet specified what should happen if one presses the <em>Unveil full message button</em> button.</p>
<p>In terms of <a target="_blank" href="http://en.wikipedia.org/wiki/Model_view_controller">Model-View-Controller (MVC)</a> (a separation of concerns design pattern Cocoa relies heavily on), we need a controller to handle this kind of user input.</p>
<h2>Writing our very first controller in MacRuby</h2>
<p>As mentioned in the previous section, Cocoa was designed with the MVC paradigm in mind. Within this paradigm, we need some kind of controller layer to process the input provided by the user. This input ranges from keyboard events to mouse events. For our intents and purposes, we&#8217;re interested in handling mouse events on our <em>Unveil full message </em>button. In order to be able to do that, we need to create a controller that will be able to deal with that.</p>
<p>Also, we may want to process events employed by the user onto the window itself. This would normally require a <em>NSWindowController</em> instance. Taking in mind we want to process events from components within the window as well, we could choose to create a separate controller for these components as well, but that would likely make things overly granular, especially for the simple scenario we&#8217;re currently dealing with.</p>
<p>So in place of the latter, we can also just choose to consolidate the ability to process the events of a window and its components all together into a subclass of <em>NSWindowController</em>. This allows us to handle the general case of controlling an <em>NSWindow</em> as well as specify our own actions for handling the components contained by our <em>NSWindow</em>.</p>
<p>To do this, in the <em>Groups &amp; Files</em> panel, expand the <em>BornToBeAlive</em> project as displayed below by clicking on the triangle next to it.</p>
<p><img src="http://media.tumblr.com/tumblr_kw046c1EJB1qayff0.png" /></p>
<p>In this expanded project outline view:</p>
<ol>
<li>Right click (or ctrl+click) on <i>Classes</i></li>
<li>Select Add-&gt;New File</li>
</ol>
<p><img src="http://media.tumblr.com/tumblr_kw04a5qAg31qayff0.png" /></p>
<p>A new window should now appear giving you the options of what kind of new file you would like to add.</p>
<ol>
<li>From the Ruby user templates, select Ruby File.</li>
<li>Click on Next</li>
</ol>
<p><img src="http://media.tumblr.com/tumblr_kw04cq53ub1qayff0.png" /></p>
<p>This will open up a Save File dialog.</p>
<ol>
<li>Type in <em>MyWindowController.rb</em> as the name for the new Ruby file.</li>
<li>Click on Finish.</li>
</ol>
<p>Your window should now look something like this:</p>
<p><img src="http://media.tumblr.com/tumblr_kw04koMu3e1qayff0.png" /></p>
<p>As decided upon earlier, we now need to implement our <em>MyWindowController</em> class in a consolidated way such that it can control both the window and the elements contained by that window. We will achieve this by implementing <em>MyWindowController</em> as being a subclass of NSWindowController, and in doing so, specialize the NSWindowController class for our window.</p>
<p>In the code editor, type in:</p>
<pre>
class MyWindowController &lt; NSWindowController
end
</pre>
<p>Tres bien! But how do we access the label to modify its value after a user has clicked on the <em>Unveil full message</em> button?</p>
<p>Well, according to <a target="_blank" href="http://developer.apple.com/Mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindowController_Class/Reference/Reference.html#//apple_ref/occ/instm/NSWindowController/setWindow:">the Apple cocoa documentation on NSWindowController</a>, it is capable hold a reference to the window it controls/manages. Instinctively, we assume that through this reference, we could access the elements of the window.</p>
<p>Even though this is kind of true, the NSWindow class was designed for general cases as well and not just our specific window. This means that its design is well <a target="_blank" href="http://en.wikipedia.org/wiki/Object_composition">composed</a> and that it will be rather tedious to acquire a reference to the element of the window we&#8217;re interested in manipulating. Most likely, it will involve a lot of chaining query calls which violates the <a target="_blank" href="http://en.wikipedia.org/wiki/Law_Of_Demeter">principle of least knowledge</a>.</p>
<p>To drive the point home, accessing an element in such a fashion in general will look something like: window.view.subviews[0]</p>
<p>A non-food solution to this would be to subclass our <em>NSWindow</em> to hold a direct reference to the elements we&#8217;re interested in manipulating, but that would require an assumption in terms of type seeing as our <em>NSWindowController</em> only deals with <em>NSWindow</em> and not <em>OurSpecificWindow</em>.</p>
<p>Taking all this into account, it&#8217;s probably just better to give our <em>MyWindowController</em> a direct reference to the element of the window we&#8217;re interested in manipulating.</p>
<p>In our particular case, we&#8217;d like to change the label&#8217;s string value after the user has clicked on the <em>Unveil full message</em> button to show the true message of life. This means we need a reference to the label within our <em>MyWindowController</em> and as such our code listing of <em>MyWindowController</em> now is:</p>
<pre>
class MyWindowController &lt; NSWindowController
    attr_accessor :my_label
end
</pre>
<p>In Cocoa, such a reference is usually referred to as an <em><strong>outlet</strong></em>, in our case, representing the metaphor of &#8220;being able to plug a label object into the outlet&#8221;. C&#8217;est bon indeed!</p>
<p>We now need to define the action to be taken when a user has clicked on our <em>Unveil full message</em> button. You might be wondering right now whether or not we also need a reference to the button from within <em>MyWindowController</em> as was the case for the label. This however, is not necessarily the case for us seeing as the button &#8212; an instance of <em>NSButton</em> &#8212; is an action emitter. More specifically, an <a target="_blank" href="http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSButton_Class/Reference/Reference.html"><em>NSButton</em></a> inherits from <a target="_blank" href="http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#//apple_ref/occ/cl/NSControl"><em>NSControl</em></a> and <a target="_blank" href="http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html#//apple_ref/occ/cl/NSResponder"><em>NSResponder</em></a> allowing it to receive user input (e.g. mouse events) and convert these to action events and dispatch the latter to our code. We may touch base on this subject in more detail in a later article, but for now, suffice it to say that we don&#8217;t need such a property reference.</p>
<p>When the button receives a mouse event from the user that is of our interest, i.e. a click event, it will convert this event into a click action and try to dispatch the action message to our code. To that end, the button expects us to provide an object with an action handler method to handle the action on delivery. In Cocoa terminology, this object containing the action handler method is referred to as the <em>target</em> of the button.</p>
<p>An action handler method in MacRuby has a distinct method signature: it is a method with one parameter named <em><strong>sender</strong></em>. It is important to adhere to this rule for action handler methods as Xcode and Interface Builder will only then recognize them as being actions.</p>
<p>Let&#8217;s open up our code editor in Xcode for <em>MyWindowController.rb</em> and change the listing to:</p>
<pre>
class MyWindowController &lt; NSWindowController
    attr_accessor :my_label</blockquote>

    def unveil_full_message_clicked(sender)
        @my_label.stringValue = "42"
    end
end
</pre>
<p>Here, we&#8217;ve added the <em>unveil_full_message_clicked</em> action, which will change the <em>stringValue</em> property of our label to the true message of life. Excellent! We&#8217;ve now set up all our code, and what remains now is to tell our button to who it should dispatch its action to.</p>
<p>We can setup this <em>target-action</em> for our button programmatic, but Interface Builder provides us with a visual solution for setting these up as well. For the sake of clarity and convenience, the visual solution that we&#8217;ll go over with in a few moments enjoys our preference for now.</p>
<h2>Hooking our MyWindowController up to our window</h2>
<p>In the previous sections we&#8217;ve gone from designing our window to providing an implementation for our <em>MyWindowController</em> class. They still need to be hooked up to one another however as they are now still disjoint entities that don&#8217;t know of eachothers existence. In this section, we&#8217;ll describe how we&#8217;ll be able to hook these things up visually using Interface Builder.</p>
<p>In Xcode:</p>
<ol>
<li>Double click on MainMenu.xib to open up Interface Builder for this nib file.</li>
</ol>
<p>As we&#8217;ve discussed earlier, objects are stored in a freeze dried manner in our NIB file that get &#8220;thawed for use&#8221; when the NIB file is loaded again. In this case, we need an instance of <em>MyWindowController</em> to hook it up to our freeze dried window instance.</p>
<p>In Interface Builder in the <em>Library</em> Panel:</p>
<ol>
<li>Type in <em>NSObject</em> in the search field.
<p><img src="http://media.tumblr.com/tumblr_kw2142EP8v1qayff0.png" /></p>
</li>
<li>Drag and drop the <em>Object</em> from the panel to the <em>MainMenu.xib</em> window of Interface Builder. This will create a new freeze dried object in the NIB file that will be instantiated when the NIB file gets loaded in.
<p><img src="http://media.tumblr.com/tumblr_kw21hnAQiM1qayff0.png" /></p>
</li>
<li>Select the object.</li>
</ol>
<p>In the <em>Inspector</em> panel:</p>
<ol>
<li>Click on the <em>Object Identity</em> tab.
<p><img src="http://media.tumblr.com/tumblr_kw23kccXxy1qayff0.png" /></p>
<p>As we can see, the object is of class type <em>NSObject</em>. We need to change this to be <em>MyWindowController</em> to let this object be an instance of that type.</p>
</li>
<li>In the class identity field, type in <em>MyWindowController</em>.
<p><img src="http://media.tumblr.com/tumblr_kw23mjva2E1qayff0.png" /></p>
<p>Our object is now of type <em>MyWindowController</em>. Tres bien!</p>
</li>
</ol>
<p>Now that we&#8217;ve created a freeze dried <em>MyWindowController</em> object, it&#8217;s time to hook it up to our window instance.</p>
<p>Recall from the code listing on <em>MyWindowController</em> that we have defined an accessor &#8212; i.e. outlet &#8212; for our label, but have not yet set this property. In particular, we need to set the <em>my_label</em> property of our <em>MyWindowController</em> instance to point to the label of our window. In Cocoa jargon, we need to &#8220;plug our window&#8217;s label into our <em>MyWindowController</em>&#8217;s <em>my_label</em> outlet&#8221;.</p>
<p>In the MainMenu.xib window of Interface Builder:</p>
<ol>
<li>Hold down the right button (or hold ctrl+click) on the <em>MyWindowController</em> object and drag your mouse to the label in the designer.
<p><img src="http://media.tumblr.com/tumblr_kw245lYF1z1qayff0.png" /></p>
</li>
<li>Release the right mouse button above the label. A popup menu as displayed below should now appear showing you the outlets to which you can hook the label up to.
<p><img src="http://media.tumblr.com/tumblr_kw247oRA1V1qayff0.png" /></p>
</li>
<li>Click on <em>my_label</em> in the Outlet popup menu to hook the label in the window up to our <em>MyWindowController</em>&#8217;s my_label property.</li>
</ol>
<p>Our <em>MyWindowController</em> now knows what object it should refer to when we use <em>@my_label</em> in <em>MyWindowController</em>. What remains is to set up the <em>target-action</em> for our button to our controller&#8217;s action handler method. We&#8217;re almost there indeed!</p>
<p>To set the target-action for our button:</p>
<ol>
<li>Hold down the right mouse button (or ctrl+click) on the button in our window and drag to our <em>My Window Controller</em> object in the MainMenu.xib window as illustrated below.
<p><img src="http://media.tumblr.com/tumblr_kw25z4dBjG1qayff0.png" /></p>
</li>
<li>Release the right mouse button. A popup menu should now appear displaying the controller&#8217;s action handler methods we can dispatch the button&#8217;s (click) action to.
<p><img src="http://media.tumblr.com/tumblr_kw261nl6Vg1qayff0.png" /></p>
</li>
<li>Click on <em>unveil_full_message_clicked:</em> to allow the button to dispatch the click action event to this method of our <em>MyWindowController</em> instance.</li>
<li>Hit cmd+s to save our changes in Interface Builder.</li>
<li>Return to Xcode. Make sure we&#8217;ve saved all the changes we&#8217;ve made to the files here too via cmd+s.</li>
<li>Hit the Build &amp; Run button in the toolbar as we&#8217;ve done before.</li>
</ol>
<p>Congratulations, your very first MacRuby application should now be in working order! Go ahead, click on the button to unveil the full message of life!</p>
<p><img src="http://media.tumblr.com/tumblr_kw266z8Pbj1qayff0.png" /></p>
<h2>Epilogue</h2>
<p>For the sake of brevity &#8212; something I know is hard to believe looking at the volume of this first tutorial &#8212; we&#8217;ve omitted a few steps you&#8217;d normally like to take into consideration.</p>
<p>For instance, we&#8217;ve not connected the window outlet of <em>MyWindowController</em> (an outlet it inherited from <em>NSWindowController</em>) to our window instance to allow it to manage the window. Connecting this outlet occurs in a similar fashion as was the case with connecting the label outlet by holding down the right mouse button on the MyWindowController instance and dragging it to the window instance.</p>
<p><img src="http://media.tumblr.com/tumblr_kw26r4usyV1qayff0.png" /></p>
<p>Releasing the right mouse button will display a popup menu outlining the outlets we can connect the window to. Clearly we should select the window outlet here.</p>
<p><img src="http://media.tumblr.com/tumblr_kw26si0QQt1qayff0.png" /></p>
<p>We&#8217;ve also not yet discussed how we can adhere to the one window per nib file, moving the window object from our MainMenu.xib to its own nib file and load it in programmatically. As mentioned before, this will require knowledge of a programming concept called delegates which we&#8217;ll discuss in our next tutorial. This will also allow us to explain the concept of File&#8217;s Owner and so on, which will require us to refine some of the techniques we&#8217;ve explained up to this point.</p>
<p>For now, go out and celebrate your victory of writing your very first MacRuby application.</p>
<p><object data="http://www.youtube.com/v/BVgM7qeAlko&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" height="344" width="425"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/BVgM7qeAlko&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /></object></p>
<h2>Homework Assignment</h2>
<p>Port the following <a href="http://github.com/jfahrenkrug/Born-To-Be-Alive">Born to be Alive</a> application by <a href="http://springenwerk.com">Johannes Fahrenkrug</a> to MacRuby! Post your <a href="http://github.com">GitHub</a> links in the comments for extra street credit <img src='http://blog.phusion.nl/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  Having a hard time being able to do so? Stay tuned for our next installment in the MacRuby series with moi as we&#8217;ll dive into objective-c for rubyists!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/03/12/creating-our-very-first-mac-application-with-ruby-how-exciting/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A gentle introduction to MacRuby</title>
		<link>http://blog.phusion.nl/2010/03/12/a-gentle-introduction-to-macruby/</link>
		<comments>http://blog.phusion.nl/2010/03/12/a-gentle-introduction-to-macruby/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 13:08:41 +0000</pubDate>
		<dc:creator>Jean Pierre Hernandez</dc:creator>
				<category><![CDATA[MacRuby]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=506</guid>
		<description><![CDATA[Bonjour les amis! My name is Jean Pierre Hernandez, I work at Phusion and indeed, am a direct relative of legendary super star disco god Patrick Hernandez.
Where Patrick was born to do disco, I was born to dabble in code, in particular with Cocoa. My brother would often use a cane to emphasize his graceful [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour les amis! My name is Jean Pierre Hernandez, I work at <a href="http://phusion.nl">Phusion</a> and indeed, am a direct relative of legendary super star disco god Patrick Hernandez.</p>
<p>Where Patrick was born to do disco, I was born to dabble in code, in particular with Cocoa. My brother would often use a cane to emphasize his graceful dance moves, and following suit, we&#8217;ll use Ruby to emphasize our élégance and love for fine Mac application development.</p>
<p>It brings me enormous joy to have you here on my blog, most likely resulting from a latent hate [[[towards] angular] brackets]. That’s okay, we’ve all been there, the important thing is we’ve found out that this torture is absolutement not necessary and that verbosity and masochism are still choices when it comes to developing delicious Mac applications. Not here however, as we’ll settle with no less than élégance and beauty! Painlessly incroyable indeed!</p>
<p>Before we’re able to start cooking on our first of many delicious Mac applications, we first need to set up the environment where all the magic happens.</p>
<p>As elegant and beautiful as MacRuby may appear to the developer, make no mistake, it’s also a beast when it comes to performance. Via techniques such as Just-in-Time (JIT) and ahead-of-time compilation, MacRuby applications can achieve performance comparable to native applications. Ahead-of-time compilation in particular is useful if you would like to keep your delicious mac recipes private to a larger extend.</p>
<p>In order to achieve all this goodness, MacRuby employs one of the most sophisticated compiler infrastructures at this moment in the form of <a href="http://llvm.org" target="_blank">LLVM</a>. Depending on your needs and intentions with MacRuby you may want to choose to compile all these components from source by grabbing it from <a href="http://www.macruby.org/source.html" target="_blank">SVN or Git</a>. Keep in mind that in the case of the latter, LLVM is still a moving target in terms of releases and is subjected to rapid API and feature changes. It is for this reason that MacRuby is forced to use specific builds as specified in the README.</p>
<p>Compiling LLVM and MacRuby from source can be quite time consuming and tedious. In particular, LLVM will take about 1 hour to compile utilizing both CPU cores on a unibody MacBook Pro. Luckily, our community is blessed with nice people who made sure we could also utilize <a href="http://www.macruby.org/downloads.html">already-compiled binaries</a> and <a href="http://macruby.icoretech.org/">nightlies</a>, the latter containing nightly edge builds of MacRuby. For the sake of stability, we’d recommend you to use the former instead.</p>
<p>Once you’ve installed these components, we can start cooking up our first cocoa application for the mac using Ruby, which is exciting indeed!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/03/12/a-gentle-introduction-to-macruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 2.2.11 released</title>
		<link>http://blog.phusion.nl/2010/03/05/phusion-passenger-2-2-11-released/</link>
		<comments>http://blog.phusion.nl/2010/03/05/phusion-passenger-2-2-11-released/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 10:24:12 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=500</guid>
		<description><![CDATA[This release fixes a regression that appeared in 2.2.10 which only affects Apache. When under high load, Apache might freeze and stop responding to requests. The regression was caused by an attempt in 2.2.10 to fix various file descriptor passing problems. The fix introduced a race condition in one of the Phusion Passenger components, and [...]]]></description>
			<content:encoded><![CDATA[<p>This release fixes a regression that appeared in 2.2.10 which only affects Apache. When under high load, Apache might freeze and stop responding to requests. The regression was caused by an attempt in 2.2.10 to fix various file descriptor passing problems. The fix introduced a race condition in one of the Phusion Passenger components, and since the problem only occurs under certain high-concurrency workloads it escaped our last release testing.</p>
<p>This problem does not affect Nginx; you only have to upgrade if you&#8217;re using Apache.</p>
<p>More information about the problem can be found at the following discussion thread: <a href="http://groups.google.com/group/phusion-passenger/t/d5bb2f17c8446ea0">http://groups.google.com/group/phusion-passenger/t/d5bb2f17c8446ea0</a></p>
<h2>How do I upgrade to 2.2.11?</h2>
<h3>Via a gem</h3>
<p>Please install it with the following command:</p>
<pre>gem install passenger</pre>
<p>Next, run:</p>
<pre>passenger-install-apache2-module</pre>
<p>Or, if you&#8217;re an Nginx user:</p>
<pre>passenger-install-nginx-module</pre>
<p>Please don&#8217;t forget to copy &#038; paste the Apache/Nginx config snippet that the installer gives you.</p>
<h3>Via a native Linux package</h3>
<p>John Leach from <a href="http://www.brightbox.co.uk/">Brightbox</a> has kindly provided an Ubuntu 8.04 package for Phusion Passenger. The package is available from the Brightbox repository which you can find at:</p>
<pre>http://apt.brightbox.net</pre>
<p>Add the following line to the Third Party Software Sources:</p>
<pre>deb http://apt.brightbox.net hardy main</pre>
<p>(The simplest way to do that is to create a file in /etc/apt/sources.list.d/ containing the deb instruction, and then run &#8216;apt-get update&#8217;).</p>
<p>Once you’ve done this then you can install Phusion Passenger by running:</p>
<pre>sudo apt-get install libapache2-mod-passenger</pre>
<p>-or-</p>
<pre>sudo apt-get install nginx-brightbox</pre>
<p>(Note that John is currently packaging 2.2.11, so it might take a while before this release shows up in the apt repository.)</p>
<h2>Final</h2>
<p>Phusion Passenger is provided to the community for free. If you like Phusion Passenger, please consider sending us a <a href="http://www.modrails.com/enterprise.html">donation</a>. Thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/03/05/phusion-passenger-2-2-11-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 2.2.10 released</title>
		<link>http://blog.phusion.nl/2010/02/22/phusion-passenger-2-2-10-released/</link>
		<comments>http://blog.phusion.nl/2010/02/22/phusion-passenger-2-2-10-released/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 12:53:20 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=497</guid>
		<description><![CDATA[Phusion Passenger is an Apache and Nginx module for deploying Ruby on Rails web applications, and is mainly focused on ease of use and stability.
Recent changes
Phusion Passenger is under constant maintenance and development. We are pleased to announce Phusion Passenger version 2.2.10. This is a bug fix release.

Fixed some Bundler compatibility problems.
Fixed some file descriptor [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.modrails.com/">Phusion Passenger</a> is an Apache and Nginx module for deploying Ruby on Rails web applications, and is mainly focused on ease of use and stability.</p>
<h2>Recent changes</h2>
<p>Phusion Passenger is under constant maintenance and development. We are pleased to announce Phusion Passenger version 2.2.10. This is a bug fix release.</p>
<ul>
<li>Fixed some Bundler compatibility problems.</li>
<li>Fixed some file descriptor passing problems, which previously could lead to mysterious crashes.</li>
<li>Fixed some compilation problems on newer GCC versions. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=430">Issue #430</a>.</li>
<li>Support #size method in rack.input.</li>
</ul>
<h2>How do I upgrade to 2.2.10?</h2>
<h3>Via a gem</h3>
<p>Please install it with the following command:</p>
<pre>gem install passenger</pre>
<p>Next, run:</p>
<pre>passenger-install-apache2-module</pre>
<p>Or, if you&#8217;re an Nginx user:</p>
<pre>passenger-install-nginx-module</pre>
<p>Please don&#8217;t forget to copy &#038; paste the Apache/Nginx config snippet that the installer gives you.</p>
<h3>Via a native Linux package</h3>
<p>John Leach from <a href="http://www.brightbox.co.uk/">Brightbox</a> has kindly provided an Ubuntu 8.04 package for Phusion Passenger. The package is available from the Brightbox repository which you can find at:</p>
<pre>http://apt.brightbox.net</pre>
<p>Add the following line to the Third Party Software Sources:</p>
<pre>deb http://apt.brightbox.net hardy main</pre>
<p>(The simplest way to do that is to create a file in /etc/apt/sources.list.d/ containing the deb instruction, and then run &#8216;apt-get update&#8217;).</p>
<p>Once you’ve done this then you can install Phusion Passenger by running:</p>
<pre>sudo apt-get install libapache2-mod-passenger</pre>
<p>-or-</p>
<pre>sudo apt-get install nginx-brightbox</pre>
<p>(Note that John is currently packaging 2.2.10, so it might take a while before this release shows up in the apt repository.)</p>
<h2>Final</h2>
<p>Phusion Passenger is provided to the community for free. If you like Phusion Passenger, please consider sending us a <a href="http://www.modrails.com/enterprise.html">donation</a>. Thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/02/22/phusion-passenger-2-2-10-released/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ruby Enterprise Edition 1.8.7-2010.01 released</title>
		<link>http://blog.phusion.nl/2010/01/20/ruby-enterprise-edition-1-8-7-2010-01-released/</link>
		<comments>http://blog.phusion.nl/2010/01/20/ruby-enterprise-edition-1-8-7-2010-01-released/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 22:05:30 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Ruby Enterprise Edition]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=445</guid>
		<description><![CDATA[What is Ruby Enterprise Edition?
Ruby Enterprise Edition (REE) is a server-oriented distribution of the official Ruby interpreter, and includes various additional enhancements, such as:

A &#8220;copy-on-write friendly&#8221; garbage collector, capable of reducing Ruby on Rails applications&#8217; memory usage by 33% on average.
The tcmalloc memory allocator, which lowers overall memory usage and boosts memory allocation speed.
The ability [...]]]></description>
			<content:encoded><![CDATA[<h2>What is Ruby Enterprise Edition?</h2>
<p><a href="http://www.rubyenterpriseedition.com/">Ruby Enterprise Edition</a> (REE) is a server-oriented distribution of the official Ruby interpreter, and includes various additional enhancements, such as:</p>
<ul>
<li>A &#8220;copy-on-write friendly&#8221; garbage collector, capable of <a href="http://www.rubyenterpriseedition.com/comparisons.html#overall_conclusion">reducing Ruby on Rails applications&#8217; memory usage by 33%</a> on average.</li>
<li>The <a href="http://code.google.com/p/google-perftools/">tcmalloc</a> memory allocator, which lowers overall memory usage and boosts memory allocation speed.</li>
<li>The ability to <a href="http://www.rubyenterpriseedition.com/documentation.html#_garbage_collector_performance_tuning">performance tune</a> the garbage collector.</li>
<li>The <a href="http://sites.google.com/site/brentsrubypatches">MBARI patch set</a>, for improved garbage collection efficiency.</li>
<li>The <a href="http://timetobleed.com/fixing-threads-in-ruby-18-a-2-10x-performance-boost/">zero-copy context switching patch</a>, included as an experimental feature.</li>
<li>Various analysis and debugging features.</li>
</ul>
<p>REE can be easily installed in parallel to your existing Ruby interpreter, allowing you switch to REE with minimal hassle or risk. REE has been out for about a year now and is already used by many high-profile websites and organizations, such as <b>New York Times, Shopify and 37signals</b>.</p>
<blockquote><p>&#8220;We switched to enterprise ruby to get the full benefit of the [copy-on-write] memory characteristics and we can absolutely confirm the memory savings of 30% some others have reported. This is <b>many thousand dollars of savings</b> even at today’s hardware prices.&#8221;<br />
&#8211; <a href="http://blog.leetsoft.com/2008/11/15/passenger">Tobias Lütke</a> (<a href="http://www.shopify.com/">Shopify</a>)</p></blockquote>
<p>Ruby Enterprise Edition is 100% open source.</p>
<h2>Changes</h2>
<dl>
<dt>Upgraded to Ruby 1.8.7-p248</dt>
<dd>The previous REE release was based on 1.8.7-p174.</dd>
<dt>Improved compiler optimization options</dt>
<dd>The previous REE release was compiled with <code>-Os -fno-strict-aliasing</code>.</p>
<p><code>-fno-strict-aliasing</code> was used to avoid <a href="http://groups.google.com/group/emm-ruby/browse_thread/thread/d327b07bbcb1351c/3e6d8056c734f19a">improper code generation</a> by GCC 4.4. This was actually caused by some <a href="http://en.wikipedia.org/wiki/Aliasing_%28computing%29">aliasing</a> bugs in Ruby&#8217;s util.c source file. The problems have been fixed in 1.8.7-p174 so we&#8217;ve now removed this compilation flag, allowing for better compiler optimizations.</p>
<p>It turned out that <code>-O2</code> yields better performance than -Os in many production environments, though some microbenchmarks might indicate otherwise. Therefore we&#8217;ve now replaced -Os with -O2.</dd>
<dt>Fixed OpenSSL extension compilation problems on systems with OpenSSL 1.0</dt>
<dd>At this time, upstream Ruby cannot be compiled on systems with OpenSSL 1.0 because of compatibility problems in the Ruby OpenSSL extension. Fedora 12 includes OpenSSL 1.0. We&#8217;ve applied a patch by the Fedora guys and added some minor changes to fix some compilation warnings. These patches have been send upstream. <a href="http://redmine.ruby-lang.org/issues/show/2022">Ruby issue #2022.</a></dd>
<dt>Backported an IO#write exception bug fix</dt>
<dd>Upstream Ruby 1.8.7-p248 has a bug in its IO#write method: it always raises Errno::EINVAL even when a different error occured. We found this problem while testing Phusion Passenger on this Ruby release.</p>
<p>We&#8217;ve <a href="http://redmine.ruby-lang.org/issues/show/2559">submitted a patch</a> upstream. This patch is also applied in this REE release.</dd>
<dt>Thread timer fix now merged upstream</dt>
<dd>Previous REE releases included Joe Damato&#8217;s and Aman Gupta&#8217;s <a href="http://timetobleed.com/ruby-threading-bugfix-small-fix-goes-a-long-way/">thread timer fix</a>. This fix has now found its way back upstream and is included by default in 1.8.7-p248, so we&#8217;ve removed the patch from our source tree.</dd>
<dt>Fix a crash bug in the zero-copy context switching patch set</dt>
<dd>This crash can be reproduced by running &#8220;god&#8221;, which will eventually cause a crash. Aman Gupta has fixed this problem.</p>
<p>Please note that the zero-copy context switching patch set is disabled by default, and must be explicitly enabled by passing &#8211;fast-threading to the installer. It is currently still marked as experimental because there are some known issues with the Kernel::fork method. <a href="http://code.google.com/p/rubyenterpriseedition/issues/detail?id=9">Issue #9.</a></dd>
<dt>Ubuntu package now contains debugging symbols</dt>
<dd>Previous REE Ubuntu packages that we release had binaries with debugging symbols stripped, in order to minimize the package sizes. We no longer strip the debugging symbols now because Joe and Aman&#8217;s <a href="http://timetobleed.com/memprof-a-ruby-level-memory-profiler/">Memprof</a> depends on the presence of debugging symbols. Memprof should work out-of-the-box with this release of REE.</p>
<p>Please note that although the binaries are larger, this does <b>not</b> affect performance in any way. The debugging symbols are only used for debugging and introspection purposes and do not affect the runtime behavior of Ruby at all.</dd>
<dt>Developer documentation is now installed by default</dt>
<dd>RDoc and RI documentation are now installed by default. You can avoid this by passing <tt>--no-dev-docs</tt> to the installer.</p>
<p>The Ubuntu packages include developer documentation.</dd>
<dt>Installer now checks for the existence of the &#8216;patch&#8217; utility</dt>
<dd>This fixes <a href="http://code.google.com/p/rubyenterpriseedition/issues/detail?id=10&#038;can=1&#038;colspec=ID%20Type%20Status%20Priority%20Milestone%20Summary">bug #10</a>.</dd>
<dt>Some documentation updates</dt>
<dd>Parts are contributed by Trevor Turk.</dd>
</dl>
<h2>Download &amp; upgrade</h2>
<p>To install Ruby Enterprise Edition, please visit <a href="http://www.rubyenterpriseedition.com/download.html">the download page</a>. To upgrade from a previous version, simply install into the same prefix that you installed to last time. Please also refer to <a href="http://www.rubyenterpriseedition.com/documentation.html">the documentation</a> for upgrade instructions.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/01/20/ruby-enterprise-edition-1-8-7-2010-01-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 2.2.9 released</title>
		<link>http://blog.phusion.nl/2010/01/08/phusion-passenger-2-2-9-released/</link>
		<comments>http://blog.phusion.nl/2010/01/08/phusion-passenger-2-2-9-released/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 10:53:56 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=456</guid>
		<description><![CDATA[Phusion Passenger is an Apache and Nginx module for deploying Ruby on Rails web applications, and is mainly focused on ease of use and stability.
Recent changes
Phusion Passenger is under constant maintenance and development. We are pleased to announce Phusion Passenger version 2.2.9. This is a bug fix release.

Fixed compatibility with Rails 3.

Actually, previous Phusion Passenger [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.modrails.com/">Phusion Passenger</a> is an Apache and Nginx module for deploying Ruby on Rails web applications, and is mainly focused on ease of use and stability.</p>
<h2>Recent changes</h2>
<p>Phusion Passenger is under constant maintenance and development. We are pleased to announce Phusion Passenger version 2.2.9. This is a bug fix release.</p>
<dl>
<dt>Fixed compatibility with Rails 3.</dt>
<dd>
<p>Actually, previous Phusion Passenger releases were already compatible with Rails 3, depending on the spawn method that would be invoked. Here&#8217;s the story:</p>
<p>Since Phusion Passenger 2.2.8, when the file config.ru exists, Phusion Passenger will treat the app as a Rack app, not as a Rails app. This is in contrast to earlier versions which gave Rails detection more priority than Rack detection. Phusion Passenger loads Rack apps and Rails apps in different ways. The Rails loader was not compatible with Rails 3, which is what we&#8217;ve fixed in this release.</p>
<p>That said, a Rails 3 app would have worked out-of-the-box on Phusion Passenger 2.2.8 as well because Rails 3 apps include a config.ru file by default, causing Phusion Passenger 2.2.8 to use the Rack loader. Earlier versions of Phusion Passenger would just completely bail out because they&#8217;d use the Rails loader.</p>
<p>With 2.2.9 there are still some caveats:</p>
<ul>
<li>Smart spawning (the mechanism with which REE&#8217;s 33% memory reduction is implemented) is *not* supported for Rack apps. This means that if you want to utilize smart spawning with Rails 3, then you should remove your config.ru file.</li>
<li>Rails 3 depends on Rack 1.1.0. You must have Rack 1.1.0 installed as a gem, even if you&#8217;ve bundled it with the gem bundler. This is because Phusion Passenger itself depends on Rack.</li>
</ul>
<p>Both of these caveats are temporary. We have plans to solve both of these properly in the future.</p>
</dd>
<dt>What&#8217;s up with the Gem Bundler?</dt>
<dd>
<p>There has been some reports that Phusion Passenger is not compatible with <a href="http://github.com/wycats/bundler">Yehuda Katz&#8217;s gem bundler</a>. This might have been true for an earlier version of the gem bundler, but the latest version seems to work fine. Please note that you need to insert the following snippet in config/preinitializer.rb, as instructed by the gem bundler&#8217;s README:</p>
<pre lang="ruby">require &quot;#{RAILS_ROOT}/vendor/gems/environment&quot;</pre>
<p>The Rails::Boot monkey patching code as posted <a href="http://yehudakatz.com/2009/11/03/using-the-new-gem-bundler-today/">here</a> does not seem to be required anymore.</p>
</dd>
<dt>Fixed support for ActiveRecord subclasses that connect to another database.</dt>
<dd>ActiveRecord subclasses that connect to a database other than the default one did not have their connection correctly cleared after forking. This can result in weird errors along the lines of &quot;Lost connection to MySQL server during query&quot;. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=429">Issue #429</a>.</dd>
<dt>[Nginx] Fixed PCRE URL.</dt>
<dd>passenger-install-nginx-module downloads PCRE 7.8 if PCRE is not already installed. However PCRE 7.8 has been removed from their FTP server, so we&#8217;ve updated the URL to point to the latest version, 8.0.</dd>
</dl>
<h2>How do I upgrade to 2.2.9?</h2>
<h3>Via a gem</h3>
<p>Please install it with the following command:</p>
<pre>gem install passenger</pre>
<p>Next, run:</p>
<pre>passenger-install-apache2-module</pre>
<p>Or, if you&#8217;re an Nginx user:</p>
<pre>passenger-install-nginx-module</pre>
<p>Please don&#8217;t forget to copy &#038; paste the Apache/Nginx config snippet that the installer gives you.</p>
<h3>Via a native Linux package</h3>
<p>John Leach from <a href="http://www.brightbox.co.uk/">Brightbox</a> has kindly provided an Ubuntu 8.04 package for Phusion Passenger. The package is available from the Brightbox repository which you can find at:</p>
<pre>http://apt.brightbox.net</pre>
<p>Add the following line to the Third Party Software Sources:</p>
<pre>deb http://apt.brightbox.net hardy main</pre>
<p>(The simplest way to do that is to create a file in /etc/apt/sources.list.d/ containing the deb instruction, and then run &#8216;apt-get update&#8217;).</p>
<p>Once you’ve done this then you can install Phusion Passenger by running:</p>
<pre>sudo apt-get install libapache2-mod-passenger</pre>
<p>-or-</p>
<pre>sudo apt-get install nginx-brightbox</pre>
<p>(Note that John is currently packaging 2.2.9, so it might take a while before this release shows up in the apt repository.)</p>
<h2>Final</h2>
<p>Phusion Passenger is provided to the community for free. If you like Phusion Passenger, please consider sending us a <a href="http://www.modrails.com/enterprise.html">donation</a>. Thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2010/01/08/phusion-passenger-2-2-9-released/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 2.2.8 released</title>
		<link>http://blog.phusion.nl/2009/12/16/phusion-passenger-2-2-8-released/</link>
		<comments>http://blog.phusion.nl/2009/12/16/phusion-passenger-2-2-8-released/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 07:39:11 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=435</guid>
		<description><![CDATA[Phusion Passenger is an Apache and Nginx module for deploying Ruby on Rails web applications, and is mainly focused on ease of use and stability.
Recent changes
Phusion Passenger is under constant maintenance and development. We are pleased to announce Phusion Passenger version 2.2.8. This is a bug fix release.

[Nginx] Fixed some signal handling problems.
Restarting Nginx on [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.modrails.com/">Phusion Passenger</a> is an Apache and Nginx module for deploying Ruby on Rails web applications, and is mainly focused on ease of use and stability.</p>
<h2>Recent changes</h2>
<p>Phusion Passenger is under constant maintenance and development. We are pleased to announce Phusion Passenger version 2.2.8. This is a bug fix release.</p>
<dl>
<dt>[Nginx] Fixed some signal handling problems.</dt>
<dd>Restarting Nginx on OS X with SIGHUP can sometimes take a long time or even fail completely. This is because of some signal handling problems, which have now been fixed.</dd>
<dt>[Nginx] Added OpenSSL as dependency.</dt>
<dd>OpenSSL is required in order to install Nginx, but this was not checked by passenger-install-nginx-module. As a result, passenger-install-nginx-module fails on e.g. out-of-the-box Ubuntu installations until the user manually installs OpenSSL. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=422">Issue #422</a>.</dd>
<dt>[Nginx] Fixed support for internal redirects and subrequests.</dt>
<dd>It is now possible to, for example, point X-Accel-Redirects to Phusion Passenger-served URLs. Patch contributed by W. Andrew Loe III: <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=433">issue #433</a>.</dd>
<dt>[Apache] Fixed a GnuTLS compatibility issue</dt>
<dd>mod_gnutls can cause Phusion Passenger to crash because of an unchecked NULL pointer. This problem has now been fixed: <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=391">issue #391</a>.</dd>
<dt>Fixed thread creation issue on Intel Itanium platforms.</dt>
<dd>This fixes <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=427">issue #427</a>.</dd>
<dt>Fixed compilation problems on Linux running on the Renesas SH4 CPU.</dt>
<dd>Patch contributed by iwamatsu: <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=428">issue #428</a>.</dd>
<dt>The Rack library has been unvendored.</dt>
<dd>The original reason for vendoring was to work around broken Rails applications that explicitly specify Rack as a gem dependency. We&#8217;ve found a better workaround that does not require vendoring Rack. This also fixes a compatibility problem with Rails 3, because Rails 3 depends on a newer Rack version than the one we had vendored. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=432">Issue #432</a>.</dd>
<dt>Fixed compatibility with Ruby 1.9.1 patchlevel >= 152</dt>
<dd>
<p>Ruby 1.9.1 patchlevel &gt;= 152 has a bug in its tempfile library. If you&#8217;ve seen an error message along the lines of</p>
<blockquote><p>*** Exception IOError in Passenger RequestHandler (closed stream)</p></blockquote>
<p>then this is a Ruby bug at work. This bug has been fixed in Ruby 1.9.2, but Ruby 1.9.1 still contains this bug. We&#8217;ve added a workaround so that the bug is not triggered with this Ruby version. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=432">Issue #432</a>.</p>
</dd>
</dl>
<h2>How do I upgrade to 2.2.8?</h2>
<h3>Via a gem</h3>
<p>Please install it with the following command:</p>
<pre>gem install passenger</pre>
<p>Next, run:</p>
<pre>passenger-install-apache2-module</pre>
<p>Or, if you&#8217;re an Nginx user:</p>
<pre>passenger-install-nginx-module</pre>
<p>Please don&#8217;t forget to copy &#038; paste the Apache/Nginx config snippet that the installer gives you.</p>
<h3>Via a native Linux package</h3>
<p>John Leach from <a href="http://www.brightbox.co.uk/">Brightbox</a> has kindly provided an Ubuntu 8.04 package for Phusion Passenger. The package is available from the Brightbox repository which you can find at:</p>
<pre>http://apt.brightbox.net</pre>
<p>Add the following line to the Third Party Software Sources:</p>
<pre>deb http://apt.brightbox.net hardy main</pre>
<p>(The simplest way to do that is to create a file in /etc/apt/sources.list.d/ containing the deb instruction, and then run &#8216;apt-get update&#8217;).</p>
<p>Once you’ve done this then you can install Phusion Passenger by running:</p>
<pre>sudo apt-get install libapache2-mod-passenger</pre>
<p>-or-</p>
<pre>sudo apt-get install nginx-brightbox</pre>
<p>(Note that John is currently packaging 2.2.8, so it might take a while before this release shows up in the apt repository.)</p>
<h2>Final</h2>
<p>Phusion Passenger is provided to the community for free. If you like Phusion Passenger, please consider sending us a <a href="http://www.modrails.com/enterprise.html">donation</a>. Thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2009/12/16/phusion-passenger-2-2-8-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Google Tech Talk on Ruby Enterprise Edition</title>
		<link>http://blog.phusion.nl/2009/12/15/google-tech-talk-on-ruby-enterprise-edition/</link>
		<comments>http://blog.phusion.nl/2009/12/15/google-tech-talk-on-ruby-enterprise-edition/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 00:53:40 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Ruby Enterprise Edition]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=428</guid>
		<description><![CDATA[Last Friday we visited the awesome Googleplex and gave a tech talk there about Ruby Enterprise Edition. This talk elaborates a bit on how REE works under the hood. Many thanks to John Woodell for making this possible!

]]></description>
			<content:encoded><![CDATA[<p>Last Friday we visited the awesome Googleplex and gave a tech talk there about Ruby Enterprise Edition. This talk elaborates a bit on how REE works under the hood. Many thanks to John Woodell for making this possible!</p>
<p><a href="http://www.youtube.com/watch?v=ghLCtCwAKqQ"><img src="http://blog.phusion.nl/wp-content/uploads/2009/12/techtalk.jpg" alt="techtalk" title="techtalk" width="600" height="354" class="alignnone size-full wp-image-431" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2009/12/15/google-tech-talk-on-ruby-enterprise-edition/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 2.2.7 released</title>
		<link>http://blog.phusion.nl/2009/11/18/phusion-passenger-2-2-7-released/</link>
		<comments>http://blog.phusion.nl/2009/11/18/phusion-passenger-2-2-7-released/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 17:33:35 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=425</guid>
		<description><![CDATA[Sorry, I made a mistake while releasing 2.2.6. In the past few days we&#8217;ve closed about 30 issues in our issue tracker, but in the mids of it I forgot to remove a single line of debugging code in passenger-install-apache2-module, causing it not to compile the Apache module. I&#8217;ve just released 2.2.7 which fixes this [...]]]></description>
			<content:encoded><![CDATA[<p>Sorry, I made a mistake while releasing 2.2.6. In the past few days we&#8217;ve closed about 30 issues in our issue tracker, but in the mids of it I forgot to remove a single line of debugging code in passenger-install-apache2-module, causing it not to compile the Apache module. I&#8217;ve just released 2.2.7 which fixes this problem, and it should be indexed by RubyForge any time now. Our apologies again for the inconvenience.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2009/11/18/phusion-passenger-2-2-7-released/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Phusion Passenger 2.2.6 released</title>
		<link>http://blog.phusion.nl/2009/11/18/phusion-passenger-2-2-6-released/</link>
		<comments>http://blog.phusion.nl/2009/11/18/phusion-passenger-2-2-6-released/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 14:41:59 +0000</pubDate>
		<dc:creator>Hongli Lai</dc:creator>
				<category><![CDATA[Phusion Passenger]]></category>

		<guid isPermaLink="false">http://blog.phusion.nl/?p=417</guid>
		<description><![CDATA[Phusion Passenger is an Apache and Nginx module for deploying Ruby on Rails web applications, and is mainly focused on ease of use and stability. It is under constant maintenance and development. We are pleased to announce Phusion Passenger version 2.2.6. This is a bug fix release.
This will be one of the last 2.2.x releases. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.modrails.com/">Phusion Passenger</a> is an Apache and Nginx module for deploying Ruby on Rails web applications, and is mainly focused on ease of use and stability. It is under constant maintenance and development. We are pleased to announce Phusion Passenger version 2.2.6. This is a bug fix release.</p>
<p>This will be one of the last 2.2.x releases. Next in the pipeline is 3.0. We believe that all the upcoming changes will be well worth the version number bump. But more about this in a later blog post. <img src='http://blog.phusion.nl/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Anyway, the following things have changed since 2.2.5:</p>
<dl>
<dt>Fixed compatibility with /tmp cleaners such as tmpwatch</dt>
<dd>Some /tmp cleaner programs such as tmpwatch try to remove subdirectories in /tmp/passenger.xxx after a while because they think those subdirectories are unused. This could cause Phusion Passenger to malfunction, requiring a web server restart. Measures have now been taken to prevent those tmp cleaner programs from removing anything in /tmp/passenger.xxx. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=365">Issue #365</a>.</dd>
<dt>Autodetection now gives more priority to Rack than to Rails</dt>
<dd>When autodetecting the application type, Rack is now given more priority than Rails. This allows one to drop a config.ru file in a Rails directory and have it detected as a Rack application instead of a Rails application. Patch contributed by Sam Pohlenz: <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=338">issue #338</a>.</dd>
<dt>Increased default socket backlog</dt>
<dd>The default socket backlog has been increased from &#8216;SOMAXCONN&#8217; (which is 128 on most platforms) to 1024. This should fix most &#8216;helper_server.sock failed: Resource temporarily unavailable&#8217; errors.</dd>
<dt>Apache fixes</dt>
<dd>The location of the &#8216;apxs&#8217; and &#8216;apr-config&#8217; commands can now also be passed to the installer through the &#8211;apxs-path and &#8211;apr-config-path parameters, in addition to the $APXS2 and $APR_CONFIG environment variables. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=3">Issue #3</a>.</dd>
<dt>Nginx fixes and changes</dt>
<dd>Various problems that only occur on 64-bit platforms (such as Snow Leopard) have been fixed.</dd>
<dd>The installer now installs Nginx 0.7.64 by default.</dd>
<dt>Various other fixes</dt>
<dd>Fixed compilation problems on Solaris. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=369">Issue #369</a> and <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=379">issue #379</a>.</dd>
<dd>Fixed crashes on PowerPC.</dd>
<dd>Some Ruby 1.9 compatibility fixes. <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=398">Issue #398</a>.</dd>
<dd>The installer now displays correct dependency installation instructions for Mandriva Linux.</dd>
</dl>
<h2>How do I upgrade to 2.2.6?</h2>
<h3>Via a gem</h3>
<p>Please install it with the following command:</p>
<pre>gem install passenger</pre>
<p>Next, run:</p>
<pre>passenger-install-apache2-module</pre>
<p>Or, if you&#8217;re an Nginx user:</p>
<pre>passenger-install-nginx-module</pre>
<p>Please don&#8217;t forget to copy &#038; paste the Apache/Nginx config snippet that the installer gives you.</p>
<h3>Via a native Linux package</h3>
<p>John Leach from <a href="http://www.brightbox.co.uk/">Brightbox</a> has kindly provided an Ubuntu 8.04 package for Phusion Passenger. The package is available from the Brightbox repository which you can find at:</p>
<pre>http://apt.brightbox.net</pre>
<p>Add the following line to the Third Party Software Sources:</p>
<pre>deb http://apt.brightbox.net hardy main</pre>
<p>(The simplest way to do that is to create a file in /etc/apt/sources.list.d/ containing the deb instruction, and then run &#8216;apt-get update&#8217;).</p>
<p>Once you’ve done this then you can install Phusion Passenger by running:</p>
<pre>sudo apt-get install libapache2-mod-passenger</pre>
<p>-or-</p>
<pre>sudo apt-get install nginx-brightbox</pre>
<p>(Note that John is currently packaging 2.2.6, so it might take a while before this release shows up in the apt repository.)</p>
<h2>Final</h2>
<p>Phusion Passenger is provided to the community for free. If you like Phusion Passenger, please consider sending us a <a href="http://www.modrails.com/enterprise.html">donation</a>. Thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.phusion.nl/2009/11/18/phusion-passenger-2-2-6-released/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
