<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"> 
<channel> 
	<title>Rob Rix.org</title> 
	<link>http://robrix.org/code</link> 
	<description>RSS feed for robrix.org</description> 
	<language>en</language> 
	<atom:link href="http://robrix.org/code" rel="self" type="application/rss+xml" />
	

<item> 
	<title>Focus</title> 
	<description><![CDATA[]]></description>  
	<pubDate>Mon, 24 Nov 2008 03:38:47 -0500</pubDate>
	<guid isPermaLink="true">http://robrix.orgcode/focus</guid>
</item>


<item> 
	<title>forall Macro</title> 
	<description><![CDATA[<h1><code>forall</code> Macro</h1>

<p>Obsolete as of Leopard and Objective-C 2.0, this macro by <a href="http://macromates.com/">Allan Odgaard</a>:</p>

<pre><code>#ifndef forall
#define forall(collection, element) \
  for( \
    id _enumerator = [collection objectEnumerator], \
    element; \
    element = [_enumerator nextObject];)
#endif</code></pre>

<p>lets you quickly enumerate any Cocoa collection that responds to <code>-objectEnumerator</code> with a simple <code>forall(collection, element) { … }</code> statement.</p>

<p>Nowadays you should be using Objective-C 2.0’s fast enumeration instead.</p>]]></description>  
	<pubDate>Mon, 24 Nov 2008 03:38:47 -0500</pubDate>
	<guid isPermaLink="true">http://robrix.orgcode/forall</guid>
</item>


<item> 
	<title>Hammer</title> 
	<description><![CDATA[<h1>Hammer</h1>

<p>(…everything looks like a nail.)</p>

<p>Hammer is a context-free parser generator framework written in ObjC (with ports in mind to Ruby and, c/o Joe Osborn, Erlang).</p>

<p>It’s currently runtime-only, although you can certainly archive the parsers it makes and load them, but the intent is to compile them using llvm.</p>

<p>It doesn’t use a lexer, and it’s surprisingly featureful. Lazy rules are coming, as is n-token lookahead, just as soon as I sort out the model in my head and get time to write it!</p>

<p>More thorough description coming soon, <a href="mailto:rix.rob@gmail.com">email me</a> if you want to know more <em>now</em>.</p>]]></description>  
	<pubDate>Mon, 24 Nov 2008 03:38:47 -0500</pubDate>
	<guid isPermaLink="true">http://robrix.orgcode/hammer</guid>
</item>


<item> 
	<title>Locus</title> 
	<description><![CDATA[<h1>Locus</h1>

<p>Locus is a language built and designed to interoperate with Objective-C. Its native types are Objective-C types; at its very lightest, it serves as a definition syntax for <code>NSArray</code>, <code>NSDictionary</code>, and <code>NSString</code> instances.</p>

<p>This article assumes familiarity with Objective-C, and, to some degree, the Foundation framework in Cocoa. Locus can be used in isolation, but it shines best with Objective-C.</p>


<h2>Literals</h2>

<p>Locus’ syntax is designed to be simple and clear, and as such it borrows a lot from JavaScript, especially <a href="http://json.org/">JSON</a>. Arrays, dictionaries, and strings are taken outright from it:</p>

<pre><code>[1, 2, 3]
{ one: 1, two: 2 }
"stringy!"</code></pre>

<p>Dictionary literals also provide the basis of Locus’ object-orientation; as in JavaScript, dictionaries double as objects, and methods assigned to slots in the dictionary can be called via messages.</p>


<h2>Methods</h2>

<p>To that end, methods are defined with a vaguely Ruby-ish syntax:</p>

<pre><code>method = { x: 1, y |
   x * y
}</code></pre>

<p>Here <code>x</code> has a default value, 1, but y is unspecified. You would call it like this:</p>

<pre><code>method(y: 2)
method(x: 2, y: 3)
method(2, 3) # same as x: 2, y: 3
method(2) # same as y: 2</code></pre>


<h2>Objects</h2>

<p>As discussed, putting methods into dictionaries gives you object-orientation. You could do that like this:</p>

<pre><code>Rectangle = {
   width: 1,
   height: 1,
   area = {
      width * height
   }
}</code></pre>

<p>As well as giving an example of argument-less methods, this also shows encapsulation—these methods have access to slots bound in their context, in this case <code>width</code> and <code>height</code>.</p>

<p>After Rectangle has been defined, if you wanted to add a perimeter calculation to it, you could do so easily like so:</p>

<pre><code>Rectangle perimeter = {
   2 * width + 2 * height
}</code></pre>

<p>Locus respects the order of operations.</p>


<h2>Messages</h2>

<p>Dictionary/object access is done by chaining symbols together separated by spaces. So if you had a <code>Rectangle</code> instance named <code>rect</code> you would get its perimeter like so:</p>

<pre><code>rect perimeter()</code></pre>

<p>If a method takes a single argument, you can call that method with a literal (not a variable) argument omitting the parentheses that would normally wrap its argument list. This is done for pure prettiness; compare the following two equivalent method calls:</p>

<pre><code>foo([1, 2, 3])
foo [1, 2, 3]</code></pre>

<p>The leading space in the second example can be omitted, which can make methods seem like they’re taking a subscript operator (as in C). This allows the syntax to represent both methods taking e.g. arrays and methods that take an index into their objects with the same syntax. Compare:</p>

<pre><code>sum [1, 2, 3]
matrix at[1, 2]</code></pre>

<p>The same syntax is used, with the same meaning to the language, but the latter looks a lot like indexes in C. This flexibility also applies to other literals:</p>

<pre><code>[1, "two"] collect { each |
   each description()
}
print "I am a banana!"
sin 3.1415</code></pre>

<p>Unlike in Ruby, however, if there are multiple arguments, the parentheses are required.</p>


<h2>Expressions</h2>

<p>Expressions can be separated either by newlines (and other optional whitespace) or by semicolons or both:</p>

<pre><code>1
2</code></pre>

<p>is equivalent to:</p>

<pre><code>1 ; 2</code></pre>

<p>As you may have noticed before, methods do not use an explicit return statement; instead, the value of a set of expressions in a block is the value of the last expression.</p>

<p>Further, expressions can be extended across multiple lines by using the \ character at the end of the line, as in C macros and bash scripts, making these equivalent:</p>

<pre><code>NSAutoreleasePool alloc \
   init
NSAutoreleasePool alloc init</code></pre>]]></description>  
	<pubDate>Mon, 24 Nov 2008 03:38:47 -0500</pubDate>
	<guid isPermaLink="true">http://robrix.orgcode/locus</guid>
</item>


<item> 
	<title>RXObjectBinder</title> 
	<description><![CDATA[
<img src="/images/ObjectBinder.png" title="Why a hypercube? It's a cube within a cube! Sorta." class="right">

<div style="position: absolute; right: 4in; text-align: center; width: 385px;">
	<img src="/images/ObjectBinderAttributes.png" title="1. List the keys you want to bind.">
	<img src="/images/ObjectBinderBindings.png" title="2. Bind them.">
	<img src="/images/ObjectBinderMain.png" title="So much better than glue code.">
</div>

<h1>RXObjectBinder</h1>

<p>(Kiss some glue code goodbye!)</p>

<p>Ever since I started using bindings, and especially since their momentum has kept growing, I've wanted something like an <code>NSObjectController</code> turned backwards. How so?</p>

<p><code>NSObjectController</code> instances let you bind to their target object's properties. For example, if you have an instance of a custom class, controls can bind to an <code>NSObjectController</code> instance representing it, and thus display (and control) specifics of its state without writing glue code.</p>

<p>What if your custom class is a view class, though? What if you have a view in a collection view that you want to make represent the individual items that the collection view is displaying? You can't bind your view's properties as-is, because it isn't instantiated by Interface Builder (and thus its <code>-exposedBindings</code> method won't be called). What do you do?</p>

<p>You either</p>

<ul>
	<li>manually bind the view to the collection view item in your window controller (or some other responsible controller class), presumably adding outlets and a few lines to your <code>-awakeFromNib</code> implementation, or</li>
	<li>hack up an IB3 plugin to instantiate your view and its bindings</li>
</ul>

<p>I want this sort of thing all the time. It drives me nuts that <code>NSObjectController</code> won't let me do it. So I wrote <code>RXObjectBinder</code>, which will. Here's how it works:</p>

<ol>
	<li>Instantiate <code>RXObjectBinder</code> (it's the red hypercube seen up top)</li>
	<li>Connect its <code>representedObject</code> outlet to the appropriate object (probably most frequently a view)</li>
	<li>On its Attributes inspector, add the keys that you'd like to bind.</li>
	<li>On its Bindings inspector, bind them.</li>
</ol>

<p>You'll obviously also have to either link against <code>RXObjectBinderFramework</code> (annoying) or just compile the <code>RXObjectBinder</code> class in (not as annoying). I'd recommend the latter.</p>

<p>At runtime, the bindings are forwarded directly to the <code>representedObject</code>, so there shouldn't be any bizarre proxying screw-ups here (10.4-era <code>NSTreeController</code>, anyone?). In practice I'm finding this to be very pleasant, and not nearly as much of an unholy hack as I feared it would be. It's entirely documented-API, blessed-methods-of-<code>InterfaceBuilderKit</code>—kosher, in fact—and quite minimalistic.</p>

<p>In short, I like it, and I hope you will too. <a href="ObjectBinder.zip">Download away</a>, or if you have git feel free to get the source directly:</p>

<p><code>git clone git://github.com/robrix/objectbinder.git</code></p>

<p>Feel free to <a href="mailto:rix.rob@gmail.com">submit patches to me</a>.</p>

<p>It's BSD licensed, natch, and your nibs should deploy just fine to both 10.4 and 10.5. (Only 10.5 has been tested so far.) If you want to edit your RXObjectBinder-bearing nibs under 10.4/IB2 then I can't help you—perhaps no one can.</p>
]]></description>  
	<pubDate>Tue, 31 Mar 2009 13:06:54 -0400</pubDate>
	<guid isPermaLink="true">http://robrix.orgcode/object-binder</guid>
</item>


<item> 
	<title>Select In Finder</title> 
	<description><![CDATA[<h1><code>select_in_finder</code></h1>

<p>I love <code>find</code> almost as much as I love <a href="http://decimus.net/dterm.php">DTerm</a> (full disclosure: I work for Decimus Software), but, being a Mac user, sometimes I want to handle my files with the Finder, too.</p>

<p>Unfortunately, combining the shell with the Finder requires AppleScript, which is really painful when all you want to do is select some files. However, with <a href="http://appscript.sourceforge.net/rb-appscript/">rb-appscript</a> things are somewhat better—we can trade the painful AppleScript for some (slightly ugly, if you ask me, but <a href="http://rubyosa.rubyforge.org/">RubyOSA</a> wasn’t working for me) Ruby.</p>

<p>As an example of its use, the command:</p>

<pre><code>find . -name '*.jpg'
</code></pre>

<p>will return the paths of all the jpgs in the working directory (and recursively, in fact). Selecting them in the Finder would be useful if we wanted to email them to someone, so wouldn’t it be nice to just write something like:</p>

<pre><code>find . -name '*.jpg' |
   select_in_finder</code></pre>

<p>and drag them over to Mail?</p>

<p>That was the idea behind this script.</p>

<pre><code>#!/usr/bin/env ruby -rubygems 
require "appscript"
Appscript::app('Finder').
   selection.
   set(STDIN.
      readlines.
      collect do |line|
         MacTypes::FileURL.
         path(line.strip).to_alias
      end)
</code></pre>

<p>It doesn't do any error checking, and you should bear in mind that the Finder will simply ignore any files that aren't in its displayed folder when in column mode; in list mode it is able to select divergent paths correctly.</p>

<p>But when all’s said and done, it's pretty sweet to be able to, say, select all the unknown screenshots in the current folder's git repository:</p>

<pre><code>git status |
   grep modified |
   awk '{print $3}' |
   select_in_finder</code></pre>

<p><a href="/code/select_in_finder.zip">Download select_in_finder</a>, put it somewhere in your <code>$PATH</code>, and enjoy. Don't forget to <a href="mailto:rix.rob@gmail.com">email me your comments, suggestions, and adulation</a>!</p>]]></description>  
	<pubDate>Mon, 24 Nov 2008 03:38:48 -0500</pubDate>
	<guid isPermaLink="true">http://robrix.orgcode/select-in-finder</guid>
</item>
</channel> 
</rss>