<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>rfwatson.net</title>
	<atom:link href="http://rfwatson.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://rfwatson.wordpress.com</link>
	<description>audio hacking, electronic music, web development</description>
	<lastBuildDate>Mon, 15 Jun 2009 10:45:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='rfwatson.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>rfwatson.net</title>
		<link>http://rfwatson.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://rfwatson.wordpress.com/osd.xml" title="rfwatson.net" />
	<atom:link rel='hub' href='http://rfwatson.wordpress.com/?pushpress=hub'/>
		<item>
		<title>My response to Seth&#8217;s textbook rant</title>
		<link>http://rfwatson.wordpress.com/2009/06/15/my-response-to-seths-textbook-rant/</link>
		<comments>http://rfwatson.wordpress.com/2009/06/15/my-response-to-seths-textbook-rant/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 10:45:51 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.rfwatson.net/?p=235</guid>
		<description><![CDATA[I am left with more questions than answers after reading Seth Godin&#8217;s rant about academic textbooks. First, Godin claims that &#8220;textbooks don&#8217;t make change&#8221;. It is difficult to be sure exactly what this means, but here is my interpretation. Textbooks are written for undergraduate students &#8212; typically 18-20 year olds who are taking their first [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=235&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I am left with more questions than answers after reading Seth Godin&#8217;s <a href="http://sethgodin.typepad.com/seths_blog/2009/06/textbook-rant.html">rant</a> about academic textbooks.</p>
<p>First, Godin claims that <em>&#8220;textbooks don&#8217;t make change&#8221;</em>. It is difficult to be sure exactly what this means, but here is my interpretation. Textbooks are written for undergraduate students &#8212; typically 18-20 year olds who are taking their first look at the subject in question.</p>
<p>&#8220;Making change&#8221; is not the job of the textbook &#8212; rather it is to teach the fundamentals in a sound fashion. So if the hippest textbook that Godin could find makes no mention of Google, Twitter, or Godin&#8217;s own permission marketing, then perhaps it is a <em>good</em> sign. A textbook should be looking beyond the latest implementations, and instead explaining the core concepts in depth. Marketing might be a fast moving area, but I don&#8217;t believe that its very essence requires re-writing every three years. And if it does, then perhaps marketing is not a topic that&#8217;s suited to academia in any case.</p>
<p>Secondly, Godin claims that textbooks <em>&#8220;don&#8217;t sell the topic&#8221;</em>. The truth is that that&#8217;s not the job of the textbook, and every textbook author knows it &#8212; especially since their target audience have already committed to 3+ years studying the topic in depth. Perhaps Godin means that they don&#8217;t make it sexy enough, but most of the process of learning <em>any</em> topic in depth is not even remotely sexy. It&#8217;s about getting your head down and learning the details, studying the history and considering how it can be applied in the world you. I dare say that this even applies to marketing as well.</p>
<p>Want sexy? Why not talk to your professor, who probably wrote the textbook anyway, in person. Or read the papers published by the research students in your department. Or failing that, read Seth Godin&#8217;s <a href="http://sethgodin.typepad.com">blog</a>. Either way, you&#8217;ll surely be getting the freshest  cuts. Textbooks are for teaching the basics, not learning about the cutting-edge.</p>
<p>Thirdly, <em>are textbooks really as expensive</em> as Godin claims? Not in my experience. A typical undergraduate textbook ranges from £20 ($33) at the low-end, to £50 ($80) at the <a href="http://www.amazon.co.uk/Artificial-Intelligence-Modern-Approach-International/dp/0130803022/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1245055568&amp;sr=1-1">high-end</a>. (<em>Disclosure: </em>I know little about marketing, and am not from America).</p>
<p>Godin claims that an author in Toronto made $20m from a calculus textbook. Assuming this book cost  $75, and the author made a generous 15%, or $11.25, per sale, this adds up to sales figures of 1.75m copies. Reliable sales figures for books aren&#8217;t easy to come by, but Stephen Hawking&#8217;s worldwide bestseller &#8220;A Brief History Of Time&#8221; is thought to have <a href="http://en.wikipedia.org/wiki/List_of_best-selling_books">sold 10m copies</a>. Clearly, whichever way you look at it, <strong>making $20m from an undergraduate textbook is the exception &#8212; and not the norm.</strong></p>
<p>So to move on to Seth&#8217;s solution. Academics should freely publish their findings online &#8212; because that&#8217;s their job. But hang on &#8211; <a href="http://scholar.google.co.uk/">isn&#8217;t that what they do already</a>?</p>
<p>The post was accurately labelled &#8212; it was a rant &#8212; but it didn&#8217;t do what a good rant should do. It didn&#8217;t strike a nerve in me even remotely, even though I&#8217;ve been a long-time reader (and purchaser) of academic books. Perhaps I&#8217;ve been lucky to avoid the worst, or maybe marketing is particularly afflicted with dross books. But either way, I don&#8217;t agree with Seth&#8217;s conclusions.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/235/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/235/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/235/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=235&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2009/06/15/my-response-to-seths-textbook-rant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
		<item>
		<title>Automatic version numbering using Git</title>
		<link>http://rfwatson.wordpress.com/2009/06/03/automatic-version-numbering-using-git/</link>
		<comments>http://rfwatson.wordpress.com/2009/06/03/automatic-version-numbering-using-git/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 13:57:11 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.rfwatson.net/?p=223</guid>
		<description><![CDATA[One of the differences between Git and Subversion is the absence of linear revision numbers. When working on an existing project which has recently migrated from SVN &#8212; as Andy White and myself have recently been doing &#8212; it is sometimes necessary to maintain the existing versioning system, and recreate a linear versioning system. This [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=223&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the differences between Git and Subversion is the absence of linear revision numbers. When working on an existing project which has recently migrated from SVN &#8212; as Andy White and myself have recently been doing &#8212; it is sometimes necessary to maintain the existing versioning system, and recreate a linear versioning system.</p>
<p>This could be done manually, but it&#8217;s a huge timewaster, if it gets done at all. Implementing it automatically, however, is complicated because of the inherent un-linearity of Git. Our first attempt was to use the <a href="http://github.com/defunkt/grit/tree/master">Grit</a> library to count the number of commits that had been made, and generate a version number from this. It fails because different versions of the repository, on different development machines, contain different numbers of commits. For example, some experimental branches are never pushed to the staging or production machines, or even shared between developers.</p>
<p>This means that the version number changes, dependent on whose machine the application is running on. This is confusing for clients and developers alike, and quite frankly pretty useless.</p>
<p>It became pretty clear that a version number would have to be explicitly stored in some place, and updated. The next question was, when to update it? Incrementing once per commit, a la subversion, seemed like the obvious answer (and Git offers the use of <a href="http://benjamin-meyer.blogspot.com/2008/10/git-hooks.html">hooks</a> to perform arbitrary callbacks on post-commit, and other events). But upon deeper thought, it is obvious that this problem suffers from the same faults as the first attempt, because committing on experimental branches will still increment the total.</p>
<p>The solution, so far, is to reject the idea of basing the version number on the number of <em>commits</em> altogether, and instead base it on the number of <em>deployments</em>. This makes a lot more sense, because it hooks into the visible product actually changing: when a deploy is carried out, one can reasonably expect the finished product to have changed in some significant way. During this time, any number of commits could have been made or reverted, or branches created or destroyed; but the version number will still only increase by one.</p>
<p>The code to do this is pretty simple. Since our project uses Capistrano for deployment, it is easy to create a task in the deploy file like this:</p>
<p><pre class="brush: ruby;">
task :after_deploy, :roles =&gt; :app do
  run &quot;cd #{shared_path} &amp;&amp; ruby increment_release.rb&quot;
  run &quot;ln -s #{shared_path}/RELEASE #{release_path}/RELEASE&quot;
end
</pre></p>
<p>Then save the following file as <code>increment_release.rb</code> in the <code>shared</code> directory on your deployment server.</p>
<p><pre class="brush: ruby;">
fname = File.expand_path(File.dirname(__FILE__) + '/RELEASE')
curr  = File.read(fname).to_i rescue 0
f=File.open(fname, 'w')
f &lt;&lt; (curr + 1)
f.close
</pre></p>
<p>The version number increments once per deployment, per environment, and being symlinked into your <code>current</code> directory, it can be accessed from your Rails app with something like:</p>
<p><pre class="brush: ruby;">
current_revision = File.read(RAILS_ROOT + '/RELEASE').to_i
</pre></p>
<p>Does a web service already exist that could be hit as part of a Capistrano deployment, and keep track of your release number remotely?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/223/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/223/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=223&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2009/06/03/automatic-version-numbering-using-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
		<item>
		<title>Building Cocoa extensions for SuperCollider</title>
		<link>http://rfwatson.wordpress.com/2009/03/11/building-cocoa-extensions-for-supercollider/</link>
		<comments>http://rfwatson.wordpress.com/2009/03/11/building-cocoa-extensions-for-supercollider/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 17:09:49 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[SuperCollider]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://rfwatson.wordpress.com/?p=55</guid>
		<description><![CDATA[This is a how-to for extending SuperCollider with custom Cocoa NSView elements. It is based on the experience of a day&#8217;s hacking, rather than a deep understanding of SC&#8217;s internals (best not try this at home then). I ended up with intuitive and easy to use dial controls, in a Logic Pro/Ableton style, courtesy of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=55&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is a how-to for extending <a href="http://supercollider.sourceforge.net">SuperCollider</a> with custom Cocoa NSView elements. It is based on the experience of a day&#8217;s hacking, rather than a deep understanding of SC&#8217;s internals (best not try this at home then).</p>
<p>I ended up with intuitive and easy to use dial controls, in a Logic Pro/Ableton style, courtesy of Matt Mower&#8217;s <a href="http://github.com/mmower/lmdial/tree/master">LMDial</a> NSView subclasses. They&#8217;re perfect to use in a musical environment &#8211; clearly laid out, easy to operate and consistent in their behaviour.</p>
<p>They can improve the usability of any music-oriented SuperCollider GUI.</p>
<p>Here&#8217;s the finished result running in SuperCollider.</p>
<div class='embed-vimeo' style='text-align:center;'><iframe src='http://player.vimeo.com/video/3574546' width='400' height='300' frameborder='0'></iframe></div>
<p>This how-to involves getting your hands dirty, and assumes you can already successfully build SuperCollider in Xcode [<a href="http://sourceforge.net/scm/?type=svn&amp;group_id=54622">download source code</a>], as well as a basic understanding of both Cocoa&#8217;s <code>NSView</code> class, and SuperCollider&#8217;s own GUI system.</p>
<p>The altered SuperCollider source files <code>SCView.M</code>, <code>SCCocoaView.h</code> and <code>SCCocoaView.M</code>, containing the changes described below, can be downloaded <a href="http://rfwatson.github.com/scdialview_files.tar.gz">here</a>. Matt Mower&#8217;s LMDial framework is <a href="http://github.com/mmower/lmdial/tree/master">here</a>.</p>
<h3>1. Import NSView classes</h3>
<p>I imported the NSView classes into the SuperCollider Language Xcode project.</p>
<p>Matt&#8217;s LMDial controls are conveniently packaged as a framework, so it was a simple task of dragging the framework into the Xcode project. To link the framework, it also needed dragging under the &#8220;Link binary with libraries&#8221; build phase, and I also had to create a &#8220;copy files&#8221; build phase to copy the classes into the Frameworks directory of the compiled application.</p>
<p><img class="alignnone size-medium wp-image-65" title="Frameworks group in Xcode" src="http://rfwatson.files.wordpress.com/2009/03/xcodescreensnapz001.jpg?w=300" alt="Frameworks group in Xcode" /></p>
<p>You can safely skip this step if you&#8217;re using classes which are part of the standard Cocoa/OSX distribution.</p>
<h3>2. Work out what the hell to do with them</h3>
<p>I had really had no clue how to incorporate these controls into SuperCollider. Without any better ideas, I decided to emulate the changes in Scott Wilson&#8217;s recent <a href="http://supercollider.svn.sourceforge.net/viewvc/supercollider?view=rev&amp;revision=8565"> SCLevelIndicator</a> commit, which also added another custom NSView control to SC. This turned out to be a wise move.</p>
<p><code>SCLevelIndicator</code> was a pretty similar addition to the one I was trying to make. By following the same conventions myself, I was confident that I would end up with some stable code at the end.</p>
<p>Some careful examination of Scott&#8217;s code showed that adding Cocoa elements to SuperCollider involves the definition of both an Objective-C class &#8211; which subclasses the NSView class we are importing &#8211; and a C++ class which slots into SuperCollider&#8217;s wider (cross-platform) GUI and messaging system.</p>
<p>Now I could proceed to define the headers and implementations for both of these classes.</p>
<h3>3. Defining the Objective-C class</h3>
<p>In <code>Headers/app/SCCocoaView.h</code>, I defined an Objective-C interface <code>SCLMDialView</code>, which subclasses <code>LMDialView</code>. This is itself a subclass of <code>NSView</code>.</p>
<p>I placed the corresponding implementation in <code>Source/app/SCCocoaView.M</code>. Only a handful of methods were required: in particular, I needed to implement <code>(void)mouseDragged:(NSEvent *)</code>, which <code>LMDialView</code> relies upon to update itself.</p>
<p><pre class="brush: cpp;">
@implementation SCLMDialView

- (void)mouseDragged:(NSEvent *)theEvent
{
    int oldValue = value;
    [super mouseDragged:theEvent];

    if(value != oldValue) {
        mSCViewObject-&gt;setValue(value, true);
    }
}

- (void)setSCView: (struct SCDialView*)inObject
{
	mSCViewObject = inObject;
}

- (void) mouseDown: (NSEvent*) event
{
    [self setFocusRingType:NSFocusRingTypeNone];
}

- (struct PyrObject*)getSCObject
{
	return mSCViewObject-&gt;GetSCObj();
}

- (void)setFrame:(NSRect)frameRect
{
	[super setFrame:frameRect];
	[self setNeedsDisplay:YES];
}

@end

</pre></p>
<h3>4. Define the C++ class</h3>
<p>The C++ class is where the main action is. This class subclasses <code>SCView</code>, which is an internal SuperCollider C++ class but directly reflects the SuperCollider class of the same name. I followed the naming conventions set by the other classes in <code>SCCocoaView.h/.M</code>, and named the class <code>SCDialView</code>. The implementation is too long to post in it&#8217;s entirety here, but the header declaration is shown below.</p>
<p><pre class="brush: cpp;">

class SCDialView : public SCView
{
public:
    SCDialView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
    virtual ~SCDialView();
    virtual void setBounds(SCRect inBounds);
    virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot);
    virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot);
    virtual void setVisibleFromParent();
    double value() { return mValue; }
    bool setValue(double inValue, bool send);
    virtual NSView* focusResponder() { return mDialView; }
protected:
    SCLMDialView *mDialView;
    double mValue;
    int mMinimum, mMaximum, mStep;
};
</pre></p>
<p>This class deals with a number of important functions.</p>
<ul>
<li>The constructor is called when a SuperCollider user creates a new <code>SCDialView</code>. It creates a new instance of our Objective-C class <code>SCLMDialView</code> and adds it as a subview to the parent view.</li>
<li>The <code>setValue</code> method is called when a user sends a <code>value_</code> message to the SuperCollider object. It clips the value to a minimum and maximum and updates the <code>NSView</code> object. If necessary, it also sends a message <strong>back</strong> to the SuperCollider object &#8211; which is acted upon by any actions associated with it.</li>
<li>The <code>setProperty</code> method receives any requests to change attributes of the GUI element &#8211; background colour or font face, perhaps. In my case I had to deal with a long list of possible attributes here, but all had the same basic structure: check the value the user is presenting, and if it is valid then update our <code>SCLMDialView</code> object. If the attribute is not one we are interested in, we call the superclass method and pass it up the hierarchy of GUI elements.</li>
<li>The corresponding <code>getProperty</code> method is much simpler, simply returning any requested attribute to the user.</li>
</ul>
<p></p>
<h3>5. Write the SuperCollider class file.</h3>
<p>In <code>scdialview.sc</code>, I wrote a SuperCollider class <code>SCDialView</code>. It subclasses <code>SCView</code> and simply defines a list of attribute getters and setters which allow the user to control the look, feel and position of the dial.</p>
<p><pre class="brush: jscript;">

SCDialView : SCView {
  value {
    ^this.getProperty(\value)
  }

  value_ { arg val;
    this.setProperty(\value, val);
  }     

  valueAction_ { arg val;
    this.setPropertyWithAction(\value, val);
  }     

  minimum_ { arg val;
    this.setProperty(\minimum, val);
  }

  etc

}

</pre></p>
<h3>6. The final hurdle</h3>
<p>I spent several hours trying to work out why the SC crashed every time I tried to create an instance of my new GUI element. I eventually discovered that the new classes must be registered in <code>Source/app/SCView.M</code>.</p>
<p><pre class="brush: cpp;">
extern SCView* NewSCDialView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds);
...
void registerSCViewClasses()
{
  ...
  new SCViewMaker(&quot;SCDialView&quot;, NewSCDialView);
}

</pre></p>
<p>And it finally worked!</p>
<h3>Conclusions</h3>
<p>This process was a real mission, but I learnt a lot about Objective-C and SuperCollider&#8217;s inner workings. And I&#8217;ve got some seriously cool GUI dials.</p>
<p>Don&#8217;t forget you can download the altered SuperCollider source files <a href="http://rfwatson.github.com/scdialview_files.tar.gz">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/55/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=55&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2009/03/11/building-cocoa-extensions-for-supercollider/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>

		<media:content url="http://rfwatson.files.wordpress.com/2009/03/xcodescreensnapz001.jpg?w=300" medium="image">
			<media:title type="html">Frameworks group in Xcode</media:title>
		</media:content>
	</item>
		<item>
		<title>How to reclaim the development log window in mod_rails</title>
		<link>http://rfwatson.wordpress.com/2008/07/11/how-to-reclaim-the-development-log-window-in-mod_rails/</link>
		<comments>http://rfwatson.wordpress.com/2008/07/11/how-to-reclaim-the-development-log-window-in-mod_rails/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 09:51:23 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.trapdoor1.net/?p=59</guid>
		<description><![CDATA[Using Phusion Passenger, aka mod_rails, in development mode is pretty neat, but you do lose the instant feedback of the mongrel log window. I haven&#8217;t worked out how to get it back into the normal shell window just yet, but using xterm does basically the same job here&#8217;s the shell command. tail -f log/development.log<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=48&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Using <a href="http://www.modrails.com">Phusion Passenger</a>, aka <strong>mod_rails</strong>, in <a href="http://www.fngtps.com/2008/04/using-passenger-on-osx-for-rails-development">development mode</a> is pretty neat, but you do lose the instant feedback of the mongrel log window.</p>
<p><span style="text-decoration:line-through;">I haven&#8217;t worked out how to get it back into the normal shell window just yet, but using <strong>xterm</strong> does basically the same job</span> here&#8217;s the shell command.</p>
<pre class="code">tail -f log/development.log</pre>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rfwatson.wordpress.com/48/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rfwatson.wordpress.com/48/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/48/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=48&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2008/07/11/how-to-reclaim-the-development-log-window-in-mod_rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
		<item>
		<title>Quick testing of ActiveRecord validations in RSpec</title>
		<link>http://rfwatson.wordpress.com/2008/07/09/quick-testing-of-activerecord-validations-in-rspec/</link>
		<comments>http://rfwatson.wordpress.com/2008/07/09/quick-testing-of-activerecord-validations-in-rspec/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 09:57:05 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[RSpec]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[custom matcher]]></category>
		<category><![CDATA[validations]]></category>

		<guid isPermaLink="false">http://blog.trapdoor1.net/?p=54</guid>
		<description><![CDATA[ActiveRecord&#8217;s validations are a convenient way to test and control the state of objects before they hit the database. Validations are themselves a presumably well-tested part of Ruby on Rails, but their usage in an application significantly changes the behaviour of your objects. This means their usage should be spec&#8217;d like anything else. Spec&#8217;ing out [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=46&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>ActiveRecord&#8217;s validations are a convenient way to test and control the state of objects before they hit the database.</p>
<p>Validations are themselves a presumably well-tested part of Ruby on Rails, but their usage in an application significantly changes the behaviour of your objects.</p>
<p>This means their usage should be spec&#8217;d like anything else.</p>
<p>Spec&#8217;ing out every single attribute on every single model is pretty repetitive though. So I rolled my own custom matcher to speed this up. It takes advantage of the fact that I follow the convention of using a <code>valid_attributes</code> method somewhere in my model&#8217;s spec, which I use to create a basic object for testing. For example:<br />
<pre class="brush: ruby;">describe &quot;Comment&quot; do
  def valid_attributes
    {
      :commentable_type =&gt; 'Item',
      :commentable_id =&gt; 1,
      :content =&gt; &quot;This is a comment!&quot;,
      :user_id =&gt; 1
    }
  end

  before(:each) do
    @comment = Comment.new(valid_attributes)
  end

  it &quot;should ...&quot;
end
</pre><br />
The new matcher allows me to add a single spec which ensures that the comment validates with exactly these attributes &#8211; and no less.<br />
<pre class="brush: ruby;">it &quot;should validate with exactly the specified attributes&quot; do
    @comment.should validate_with_exactly(valid_attributes)
  end</pre><br />
The spec will fail &#8211; with an readable error message &#8211; if <strong>either</strong>:</p>
<ul>
<li>The object is <strong>invalid</strong> with all the specified attribues</li>
<li><strong>Any one</strong> of the attributes is missing and the object is <strong>valid</strong></li>
</ul>
<p>The spec code is available at <a href="http://pastie.org/230565">http://pastie.org/230565</a> &#8211; pastie it into your <code>spec_helper.rb</code>.</p>
<p>This is still so hot off the press it&#8217;s positively steaming. Do you have any comments, bug reports or suggestions?</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rfwatson.wordpress.com/46/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rfwatson.wordpress.com/46/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/46/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=46&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2008/07/09/quick-testing-of-activerecord-validations-in-rspec/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
		<item>
		<title>Rubinius&#8217; lurking presence continues to be felt</title>
		<link>http://rfwatson.wordpress.com/2008/05/11/rubinius-lurking-presence-continues-to-be-felt/</link>
		<comments>http://rfwatson.wordpress.com/2008/05/11/rubinius-lurking-presence-continues-to-be-felt/#comments</comments>
		<pubDate>Sun, 11 May 2008 20:08:35 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[rubinius]]></category>

		<guid isPermaLink="false">http://blog.trapdoor1.net/?p=41</guid>
		<description><![CDATA[Merb now seems to be tentatively running on Rubinius, the fledgling Ruby virtual machine. I&#8217;m watching both of these projects with real interest, although I have nowhere near enough free time to put either through their paces just yet (neither are close to production levels of usability at this point in any case). It&#8217;s good [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=38&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://merbivore.com/">Merb</a> now seems to be <a href="http://metaclass.org/2008/5/10/merb-on-rubinius">tentatively running</a> on <a href="http://rubini.us/">Rubinius</a>, the fledgling Ruby virtual machine. I&#8217;m watching both of these projects with real interest, although I have nowhere near enough free time to put either through their paces just yet (neither are close to production levels of usability at this point in any case).</p>
<p>It&#8217;s good to see Ruby&#8217;s boundaries being pushed, though. And there&#8217;s a reasonable chance that one or both of these projects could be the future.</p>
<p>And of course, <strong>Rubinius on Rails.</strong>..</p>
<p>That will really be interesting.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rfwatson.wordpress.com/38/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rfwatson.wordpress.com/38/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/38/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=38&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2008/05/11/rubinius-lurking-presence-continues-to-be-felt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
		<item>
		<title>Why I am switching to test-driven development</title>
		<link>http://rfwatson.wordpress.com/2008/05/10/why-i-am-switching-to-test-driven-development/</link>
		<comments>http://rfwatson.wordpress.com/2008/05/10/why-i-am-switching-to-test-driven-development/#comments</comments>
		<pubDate>Sat, 10 May 2008 22:49:54 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[RSpec]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.trapdoor1.net/?p=38</guid>
		<description><![CDATA[I am going to change the way I code. My working pattern is, roughly, as follows: Sketch a basic method implementation Test it manually Fine tune the code, improve implementation Further manual testing, fix a few bugs Write a test Done! Make a cup of coffee. Is there anything so bad about this process? I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=37&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I am going to change the way I code.</p>
<p>My working pattern is, roughly, as follows:</p>
<ol>
<li> Sketch a basic method implementation</li>
<li>Test it manually</li>
<li>Fine tune the code, improve implementation</li>
<li>Further manual testing, fix a few bugs</li>
<li>Write a test</li>
<li>Done! Make a cup of coffee.</li>
</ol>
<p>Is there anything so bad about this process? I write a test, so I get one gold-star. And there&#8217;s nothing wrong with the end results: I write good code, which usually works. But I think I could work better. Every time I&#8217;ve written a model or controller for as long as I can remember, a little voice in my head asks: &#8220;<strong>Why haven&#8217;t you written the test first&#8230;?</strong>&#8220;</p>
<p>Anybody else get the same little voice? I suspect there&#8217;s a few of you out there.</p>
<p>The more I&#8217;ve learnt about TDD, the more I&#8217;ve wanted to practice it. At first, it just seemed like a way of ensuring thorough test coverage, but that is actually just a sweet, sweet bonus. For me, TDD is more about changing my entire mindset when it comes to coding. The benefits promise to run deeper than may first appear obvious.</p>
<p>Sure, testing first will remind me to focus on what I want my code to do, <em>before</em> I start coding. This is valuable, yes &#8211; and I can see it helping me avoid a few refactoring/start-from-scratch sessions when my brain hasn&#8217;t quite been in gear &#8211; but I don&#8217;t believe that it will much improve my resulting finished code, so much as make the process of getting there a more efficient.</p>
<p>The more precious benefit, is that the pre-written tests will tell me exactly when to <em>stop</em> &#8211; and that&#8217;s a time when it&#8217;s a lot easier to trip up. Especially a day later, or a month later. The habit of testing first will prompt me to keep my methods small and manageable. Small and manageable in the short-term, equates to easy-to-maintain and stable in the long-term. A method of working which virtually <em>obliges</em> me to create manageable, bug-free code? <em>And</em> as good as guarantees a working stack of tests across my application?</p>
<p>There&#8217;s a whole host of other good reasons too, some of which I am perhaps yet to fully appreciate, but enough already. I am convinced.</p>
<p>So, why aren&#8217;t I doing it? My only problem is <strong>discipline</strong>. That&#8217;s going to change.</p>
<h3>Test-unit Zappa</h3>
<p>How will I switch to TDD? Firstly, I will drop <a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html">Test::Unit</a> and make the switch to <a href="http://rspec.info/">RSpec</a>.</p>
<p>Why switch? After all, the Test::Unit framework is a proven system in itself. It&#8217;s been shown to be more than capable of providing in-depth test coverage in complex applications, and is also usable within a strictly test-driven environment. What&#8217;s more, it&#8217;s true to say that there&#8217;s little testing that can be done with RSpec, that can&#8217;t already be done, one way or the other, using Test::Unit.</p>
<p>Isn&#8217;t switching from a system I am already well familiar with, simply going to be a short-term hindance &#8211; and offer questionable benefits in the long-term?</p>
<p>There are two stand-out reasons. Firstly, working with a different testing framework will force me to throw out my old habits, and hopefully help me to break my old routines and shake up my testing in the way that I want. Old habits die hard, and sometimes need a little persuasion.</p>
<p>Secondly &#8211; and perhaps even more importantly &#8211; it&#8217;s about changing the the language in which I write tests. RSpec&#8217;s descriptive idioms &#8211; typically written as <code>something.<em>should</em>_have</code> &#8211; are forward-looking, and cry out to be written and defined <em>before</em> the method they test. This is quite different to Test::Unit, which really encourages working the other way around.</p>
<p>As Josh Stephenson highlights <a href="http://fr.ivolo.us/posts/rspec-tutorial-part-1">here</a>:</p>
<blockquote><p>Just as sociologists have postulated that the language we use to express the world around us directly affects the way we interpret it, the language we use to test applications directly affects the way we develop them.</p></blockquote>
<p>So RSpec will force me to throw out both my testing routines, and my vocabulary. I can&#8217;t do much more to create a catalyst for change.</p>
<p>Of course, I will be monitoring my work-flow, productivity and the resulting code carefully. If, after a reasonable period it is clear to me that TDD is not working &#8211; back I can go. But a decent spell of practicing TDD, a good level of familiarity &#8211; a fair test, so to speak &#8211; is going to be needed before I can conquer that little voice in my head, one way or the other.</p>
<p>In due course, I will post my progress here.</p>
<h4>References/Further reading</h4>
<p><a href="http://www.oreillynet.com/pub/a/ruby/2007/08/09/behavior-driven-development-using-ruby-part-1.html?page=1">http://www.oreillynet.com/pub/a/ruby/2007/08/09/behavior-driven-development-using-ruby-part-1.html?page=1</a></p>
<p><a href="http://www.agiledata.org/essays/tdd.html">http://www.agiledata.org/essays/tdd.html</a></p>
<p><a href="http://blog.daveastels.com/files/BDD_Intro.pdf">http://blog.daveastels.com/files/BDD_Intro.pdf</a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rfwatson.wordpress.com/37/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rfwatson.wordpress.com/37/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/37/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=37&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2008/05/10/why-i-am-switching-to-test-driven-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
		<item>
		<title>Ruby, from the perspective of SuperCollider</title>
		<link>http://rfwatson.wordpress.com/2008/05/07/ruby-from-the-perspective-of-supercollider/</link>
		<comments>http://rfwatson.wordpress.com/2008/05/07/ruby-from-the-perspective-of-supercollider/#comments</comments>
		<pubDate>Wed, 07 May 2008 19:35:53 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[SuperCollider]]></category>
		<category><![CDATA[five things]]></category>

		<guid isPermaLink="false">http://blog.trapdoor1.net/?p=33</guid>
		<description><![CDATA[SuperCollider? It&#8217;s a programming environment designed for live digital signal processing, audio manipulation and algorithmic composition &#8211; making music, in other words. It is also contains a fully-fledged, dynamic, object-oriented language strongly influenced by both Smalltalk and functional programming, and as such it has a fair bit in common with Ruby. There&#8217;s nothing like using [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=36&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>SuperCollider? It&#8217;s a programming environment designed for live digital signal processing, audio manipulation and algorithmic composition &#8211; making music, in other words. It is also contains a fully-fledged, dynamic, object-oriented language strongly influenced by both Smalltalk and functional programming, and as such it has a fair bit in common with Ruby.</p>
<p>There&#8217;s nothing like using two languages a lot (which I do) to get you comparing their finer details. Here&#8217;s what I have come to see differently about Ruby from coding in SC, and a few things I miss in Ruby that are present in SC. Maybe I&#8217;ll follow it up in the future, and do it the other way round.</p>
<h3>Punctuation <em>can</em> be beautiful after all</h3>
<p>Amongst a beginning Ruby programmer&#8217;s first acts, still flushed with the excitement of escaping from Java or PHP, will be to quite consciously <em>throw away </em>the habit of finishing each line of code with a semi-colon. And why not? They bugged me for years too, being obviously unnecessary in 99% of cases, cluttering up the page and and causing countless exceptions and failed builds when misplaced. And basically, for no good reason.</p>
<p>How many semi-colons do you see in Ruby code? Not a whole lot, in my experience. It&#8217;s almost like they&#8217;re omitted in order to somehow <em>punish</em> Java, perhaps deservedly.</p>
<p>SuperCollider requires the semi-colon at the end of (most) lines, and I used to feel it a bit of a pain. But semi-colons have kind of grown on me. Perhaps it&#8217;s because of SC&#8217;s strong functional programming paradigms, which means that it&#8217;s easier to chain multiple messages together than Ruby, even while splitting them across multiple lines.<br />
<pre class="brush: jscript;">SCWindow.new(&quot;A window!&quot;, Rect(20, 20, 300, 300))
    .alwaysOnTop_( true )
    .onClose_{ &quot;Goodbye!&quot;.postln }
    .userCanClose_( false )
    .front

</pre></p>
<p>Most people seem to hide the semi-colon away. I prefer to give it pride of place, hanging it off the end of the indentation like a tear-drop.</p>
<p>The semi-colon is dead&#8230; Long live the semi-colon.</p>
<h3>Syntactic sugar, SC style</h3>
<p>Assuming iteration over a list &#8211; or range &#8211; makes a lot of sense. Actually, this isn&#8217;t syntactic sugar at all &#8211; just sensible proxying of messages &#8211; but it certainly feels like it.</p>
<h5>Ruby:</h5>
<p><pre class="brush: jscript;">(1..10).to_a.collect{ |num| num.squared }
# Ruby version &gt;= 1.9
(1..10).to_a.collect(&amp;:squared)

#=&gt; [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ]

</pre></p>
<h5>SuperCollider:</h5>
<p><pre class="brush: jscript;">(1..10).squared

#=&gt; [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ]

</pre></p>
<p>Also worth a mention is SC&#8217;s ! notation, as an alternative to Object#dup. This can often be used to fill an array.</p>
<h5>Ruby</h5>
<p><pre class="brush: jscript;">Array.new(10){ rand(10) }</pre></p>
<h5>SuperCollider</h5>
<p><pre class="brush: jscript;">{ 10.rand } ! 10</pre></p>
<h3>Partial application</h3>
<p>Partial application allows the creation of functions from implicit input data &#8211; that is, call a method sending less than the required number of arguments. This is a trick picked up from functional languages such as Haskell. There, however, it&#8217;s better known as currying.</p>
<p>It can be (vaguely) comparable, in effect, to <code>Symbol#to_proc</code> in Rails (and Ruby 1.9), but is endlessly more flexible and powerful.</p>
<p>Each pair of lines are equivalent:</p>
<p><pre class="brush: jscript;">

(1..10).collect{ |number| number.postln };
(1..10).collect(_.postln);

(1..10).collect {|x| Polar(x, pi) };
(1..10).collect(Polar(_, pi));

</pre><br />
There are ways to <a href="http://moonbase.rydia.net/mental/blog/programming/currying-in-ruby">approximate this kind of thing</a> in Ruby, but none which look (to me) remotely as elegant.</p>
<p>Currying is cool.</p>
<h3>Instant API</h3>
<p>Why does coding in SC seem so quick and easy?</p>
<p>Maybe, its partly down to the speed of access to  the language documentation. And it really is quick. Not sure how to scan each item of array? Just type <code>Array</code>, select it and hit CMD-D &#8211; up pops the SC documentation for Array class. Unsure of where a method you are calling is implemented in the class hierarchy? Select it and hit CMD-Y, and up pops a list of classes where the method is implemented, including extensions and plugins.</p>
<p>And best of all, select the name of any class and hit CMD-J. There in front of you is the source code for that actual class.</p>
<p>Now, it would be unfair to use this as a criticism of Ruby, as SC has an integrated editing environment which makes this sort of thing possible to build in as standard. But anybody who created a Ruby version of this system, perhaps as a plugin for TextMate, would be an instant superstar in my eyes, and I would think a good few others too.</p>
<h3>My conclusions&#8230;</h3>
<p>I am increasingly aware of how much Smalltalk is responsible for, and more and more interested in getting to know it a bit better in itself. Learning a new language never did anybody any harm.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rfwatson.wordpress.com/36/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rfwatson.wordpress.com/36/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/36/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=36&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2008/05/07/ruby-from-the-perspective-of-supercollider/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
		<item>
		<title>Under the hood: Ruby&#8217;s global variables</title>
		<link>http://rfwatson.wordpress.com/2008/05/04/under-the-hood-rubys-global-variables/</link>
		<comments>http://rfwatson.wordpress.com/2008/05/04/under-the-hood-rubys-global-variables/#comments</comments>
		<pubDate>Sun, 04 May 2008 20:18:52 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[global variables]]></category>

		<guid isPermaLink="false">http://blog.trapdoor1.net/?p=31</guid>
		<description><![CDATA[Tinkering in irb earlier, I ran this line of code. global_variables.each{ &#124;var&#124; puts var + ": " + eval(var).inspect } Ruby&#8217;s global variables &#8211; I have long been aware of their existence in the background, but I hadn&#8217;t realised quite how many are initialized by default. What are they all for &#8211; and what cool [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=35&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Tinkering in <code>irb</code> earlier, I ran this line of code.</p>
<pre class="ruby">
global_variables.each{ |var| puts var + ": " + eval(var).inspect }
</pre>
<p>Ruby&#8217;s global variables &#8211; I have long been aware of their existence in the background, but I hadn&#8217;t realised quite how many are initialized by default. What are they all for &#8211; and what cool metaprogramming tricks can I use them for?</p>
<p>I actually use one of these variables very often, and it deserves a special mention. <code>$!</code> points to the most recently raised exception, and is a useful shortcut in many contexts. A lot of the others promise to be most useful in a shell/CGI script environment &#8211; but it&#8217;s good to know they&#8217;re there, and a little peek under the hood of Ruby usually proves instructional.</p>
<p>Here&#8217;s the global variables initialized by default on my system (Ruby 1.8.6 on OSX 10.5) &#8211; where I have some idea what they refer to, I&#8217;ve added that too.</p>
<table class="tabbed" style="height:24px;" border="0" width="589">
<tbody>
<tr>
<th>Variable name</th>
<th>Value (on my machine)</th>
<th>Purpose?</th>
</tr>
<tr>
<td>$0</td>
<td>&#8220;irb&#8221;</td>
<td>Name of current script executing</td>
</tr>
<tr>
<td>$&#8221;</td>
<td>["e2mmap.rb", "irb/init.rb", "irb/workspace.rb", "irb/context.rb", "irb/extend-command.rb", "irb/output-method.rb", "irb/notifier.rb", "irb/slex.rb", "irb/ruby-token.rb", "irb/ruby-lex.rb", "readline.bundle", "irb/input-method.rb", "irb/locale.rb", "irb.rb"]</td>
<td>Alias for $LOADED_FEATURES</td>
</tr>
<tr>
<td>$$</td>
<td>6100</td>
<td>Ruby interpreter process ID</td>
</tr>
<tr>
<td>$&lt;</td>
<td>ARGF</td>
<td>Points to ARGF (user input)</td>
</tr>
<tr>
<td>$_</td>
<td>nil</td>
<td>Last string read by &#8216;gets&#8217;</td>
</tr>
<tr>
<td>$-K</td>
<td>&#8220;NONE&#8221;</td>
<td>$KCODE option passed via command line</td>
</tr>
<tr>
<td>$DEBUG</td>
<td>false</td>
<td>Can be set to true with ruby &#8211;debug myscript.rb. Just for program use I think?</td>
</tr>
<tr>
<td>$-i</td>
<td>nil</td>
<td>See ruby command line options: in-place-edit mode</td>
</tr>
<tr>
<td>$deferr</td>
<td>#</td>
<td>Usually points to $stderr</td>
</tr>
<tr>
<td>$/</td>
<td>&#8220;\n&#8221;</td>
<td>Input record separator</td>
</tr>
<tr>
<td>$&#8217;</td>
<td>nil</td>
<td>Text after regexp match</td>
</tr>
<tr>
<td>$stdout</td>
<td>#</td>
<td>Standard output (eg, the console usually)</td>
</tr>
<tr>
<td>$-l</td>
<td>false</td>
<td>See ruby command line options: automatic line-ending processing</td>
</tr>
<tr>
<td>$LOAD_PATH</td>
<td>["/usr/local/lib/ruby/site_ruby/1.8", "/usr/local/lib/ruby/site_ruby/1.8/i686-darwin9.0.0", "/usr/local/lib/ruby/site_ruby", "/usr/local/lib/ruby/1.8", "/usr/local/lib/ruby/1.8/i686-darwin9.0.0", "."]</td>
<td></td>
</tr>
<tr>
<td>$.</td>
<td>184</td>
<td>Last line of script read by interpreter</td>
</tr>
<tr>
<td>$KCODE</td>
<td>&#8220;NONE&#8221;</td>
<td><em>Kanji</em>CODE &#8211; determines how Ruby handles characters</td>
</tr>
<tr>
<td>$-w</td>
<td>false</td>
<td>See Ruby intepreter command line options &#8211; sets $VERBOSE to true</td>
</tr>
<tr>
<td>$FILENAME</td>
<td>&#8220;-&#8221;</td>
<td>?</td>
</tr>
<tr>
<td>$defout</td>
<td>#</td>
<td>Usually points to $stdout</td>
</tr>
<tr>
<td>$,</td>
<td>nil</td>
<td>?</td>
</tr>
<tr>
<td>$`</td>
<td>nil</td>
<td>Text before regexp match</td>
</tr>
<tr>
<td>$*</td>
<td>[]</td>
<td>Command line arguments passed to current script</td>
</tr>
<tr>
<td>$stdin</td>
<td>#</td>
<td>Standard user input (usually, console)</td>
</tr>
<tr>
<td>$-F</td>
<td>nil</td>
<td>Field separator passed via command line</td>
</tr>
<tr>
<td>$-p</td>
<td>false</td>
<td>Used for command line file processing/looping (See also: -n)</td>
</tr>
<tr>
<td>$-I</td>
<td>["/usr/local/lib/ruby/site_ruby/1.8", "/usr/local/lib/ruby/site_ruby/1.8/i686-darwin9.0.0", "/usr/local/lib/ruby/site_ruby", "/usr/local/lib/ruby/1.8", "/usr/local/lib/ruby/1.8/i686-darwin9.0.0", "."]</td>
<td>Library script path (passed via command line option -I)</td>
</tr>
<tr>
<td>$\</td>
<td>nil</td>
<td>Output record separator</td>
</tr>
<tr>
<td>$=</td>
<td>false</td>
<td>Was last regular expression match case-sensitive?</td>
</tr>
<tr>
<td>$binding</td>
<td>nil</td>
<td>?</td>
</tr>
<tr>
<td>$-v</td>
<td>false</td>
<td>Alias for &#8211;verbose command line option</td>
</tr>
<tr>
<td>$&gt;</td>
<td>#</td>
<td>Points to standard output</td>
</tr>
<tr>
<td>$&amp;</td>
<td>nil</td>
<td>Last matched regular expression (also $1, $2, etc)</td>
</tr>
<tr>
<td>$!</td>
<td>nil</td>
<td>Last raised exception</td>
</tr>
<tr>
<td>$PROGRAM_NAME</td>
<td>&#8220;irb&#8221;</td>
<td>Alias for $0</td>
</tr>
<tr>
<td>$LOADED_FEATURES</td>
<td>["e2mmap.rb", "irb/init.rb", "irb/workspace.rb", "irb/context.rb", "irb/extend-command.rb", "irb/output-method.rb", "irb/notifier.rb", "irb/slex.rb", "irb/ruby-token.rb", "irb/ruby-lex.rb", "readline.bundle", "irb/input-method.rb", "irb/locale.rb", "irb.rb"]</td>
<td>Alias for $&#8221;</td>
</tr>
<tr>
<td>$?</td>
<td>nil</td>
<td>Status of last executed child process (useful with Kernel#system and similar)</td>
</tr>
<tr>
<td>$;</td>
<td>nil</td>
<td>Input field separator</td>
</tr>
<tr>
<td>$SAFE</td>
<td>0</td>
<td>Ruby safe mode</td>
</tr>
<tr>
<td>$-d</td>
<td>false</td>
<td>Command line option &#8211;debug</td>
</tr>
<tr>
<td>$:</td>
<td>["/usr/local/lib/ruby/site_ruby/1.8", "/usr/local/lib/ruby/site_ruby/1.8/i686-darwin9.0.0", "/usr/local/lib/ruby/site_ruby", "/usr/local/lib/ruby/1.8", "/usr/local/lib/ruby/1.8/i686-darwin9.0.0", "."]</td>
<td>Alias for library path(?)</td>
</tr>
<tr>
<td>$-0</td>
<td>&#8220;\n&#8221;</td>
<td>Separator character(?)</td>
</tr>
<tr>
<td>$+</td>
<td>nil</td>
<td>?</td>
</tr>
<tr>
<td>$-a</td>
<td>false</td>
<td>Ruby command line options: auto-split mode</td>
</tr>
<tr>
<td>$VERBOSE</td>
<td>false</td>
<td>Ruby command line options: &#8211;verbose (some methods print extra information if this is on)</td>
</tr>
<tr>
<td>$stderr</td>
<td>#</td>
<td>Standard error destination</td>
</tr>
<tr>
<td>$~</td>
<td>nil</td>
<td>Last matched regular expression data (instance of MatchData)</td>
</tr>
<tr>
<td>$@</td>
<td>nil</td>
<td>Position of an error occurence</td>
</tr>
</tbody>
</table>
<p>
<b>References</b></p>
<p>
<a href="http://www.ruby-doc.org/docs/UsersGuide/rg/globalvars.html">http://www.ruby-doc.org/docs/UsersGuide/rg/globalvars.html</a><br />
<a href="http://phrogz.net/programmingruby/rubyworld.html">http://cbcg.net/talks/rubyidioms/index.html</a><br />
<a href="http://www.math.hokudai.ac.jp/~gotoken/ruby/ruby-uguide/uguide20.html">http://www.math.hokudai.ac.jp/~gotoken/ruby/ruby-uguide/uguide20.html</a><br />
Hal Fulton: The Ruby Way (2nd Edition), Addison Wesley</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rfwatson.wordpress.com/35/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rfwatson.wordpress.com/35/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/35/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=35&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2008/05/04/under-the-hood-rubys-global-variables/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
		<item>
		<title>AJAX performance trickery</title>
		<link>http://rfwatson.wordpress.com/2008/05/03/ajax-performance-trickery/</link>
		<comments>http://rfwatson.wordpress.com/2008/05/03/ajax-performance-trickery/#comments</comments>
		<pubDate>Sat, 03 May 2008 22:28:09 +0000</pubDate>
		<dc:creator>rfwatson</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[yslow]]></category>

		<guid isPermaLink="false">http://blog.trapdoor1.net/?p=29</guid>
		<description><![CDATA[This is a comprehensive guide to improving AJAX performance, including a guide to a Firefox plugin I hadn&#8217;t come across before &#8211; YSlow. To me, AJAX performance isn&#8217;t so much a scalability issue, as a user interface one. The slicker and more responsive the interface, the better the user experience. And so a deeper understanding [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=34&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ibm.com/developerworks/web/library/wa-aj-perform/?ca=dgr-lnxw01FasterAjax">This</a> is a comprehensive guide to improving AJAX performance, including a guide to a Firefox plugin I hadn&#8217;t come across before &#8211; <a href="http://developer.yahoo.com/yslow/">YSlow</a>.</p>
<p>To me, AJAX performance isn&#8217;t so much a scalability issue, as a user interface one. The slicker and more responsive the interface, the better the user experience. And so a deeper understanding of the AJAX protocol has got to be a good thing.</p>
<p><a href="http://www.ibm.com/developerworks/web/library/wa-aj-perform/?ca=dgr-lnxw01FasterAjax">http://www.ibm.com/developerworks/web/library/wa-aj-perform/?ca=dgr-lnxw01FasterAjax</a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rfwatson.wordpress.com/34/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rfwatson.wordpress.com/34/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rfwatson.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rfwatson.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rfwatson.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rfwatson.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rfwatson.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rfwatson.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rfwatson.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rfwatson.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rfwatson.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rfwatson.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rfwatson.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rfwatson.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rfwatson.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rfwatson.wordpress.com/34/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rfwatson.wordpress.com&amp;blog=6337301&amp;post=34&amp;subd=rfwatson&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rfwatson.wordpress.com/2008/05/03/ajax-performance-trickery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f58b71b68bce781157d573e739cea22a?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=R" medium="image">
			<media:title type="html">rfwatson</media:title>
		</media:content>
	</item>
	</channel>
</rss>
