<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Kittensoft - home</title>
  <id>tag:journal.kittensoft.org,2008:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://journal.kittensoft.org/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://journal.kittensoft.org/" rel="alternate" type="text/html"/>
  <updated>2008-06-03T23:12:18Z</updated>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-06-03:932</id>
    <published>2008-06-03T23:10:00Z</published>
    <updated>2008-06-03T23:12:18Z</updated>
    <category term="mac"/>
    <category term="hardware"/>
    <category term="laptop"/>
    <category term="leopard"/>
    <category term="mac"/>
    <link href="http://journal.kittensoft.org/2008/6/3/advanced-screen-brightness-control-on-leopard" rel="alternate" type="text/html"/>
    <title>Advanced Screen Brightness Control on Leopard</title>
<content type="html">
            &lt;p&gt;Excellent preference pane app: http://www.charcoaldesign.co.uk/shades! Much better control over the brightness as well as choice of tint colour among other things. Especially important for me because the x61 does not allow changing the brightness otherwise.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-04-01:912</id>
    <published>2008-04-01T23:31:00Z</published>
    <updated>2008-04-02T00:17:58Z</updated>
    <category term="rubinius"/>
    <category term="compiler"/>
    <category term="macro"/>
    <category term="parser"/>
    <category term="programming"/>
    <category term="rubinius"/>
    <category term="ruby"/>
    <category term="vm"/>
    <link href="http://journal.kittensoft.org/2008/4/1/conditional-compilation-of-ruby-code" rel="alternate" type="text/html"/>
    <title>Conditional Compilation of Ruby Code</title>
<content type="html">
            &lt;p&gt;It was one of those silly ideas-nights and I decided to add the ability to have blocks of code that can be omitted from the bytecode depending on a condition as a proof-of-concept. Once the parser is in, we can start working on &#8216;real,&#8217; more generic sexp and &lt;span class=&quot;caps&quot;&gt;AST&lt;/span&gt; manipulators towards something approaching Lisp&#8217;s facilities.&lt;/p&gt;


I figured it would be a fairly short task and for a change I was correct&amp;emdash;and a good portion of the thanks goes to Rubinius&#8217; already-excellent facilities: I was able to modify the sexp with the full power of Ruby. It took me a bit to figure out the best way to set this up but in the end there are literally about 11 lines of implementation code plus the specs. The end result is a block construct for a special form that allows conditionalising. Currently I only set it up to process global variables but it is trivial to add support for the rest&#8212;what may not be trivial is for the user to get other types of conditions set up without confusion over compile-time versus runtime. The invocation is pretty simple:
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;co&quot;&gt;Rubinius&lt;/span&gt;.compile_if(&lt;span class=&quot;gv&quot;&gt;$DEBUG&lt;/span&gt;) { &lt;span class=&quot;co&quot;&gt;Logger&lt;/span&gt;.debug &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Blah blah: &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;some_variable&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; } &lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

If &lt;code&gt;$DEBUG&lt;/code&gt; is false at the time this section goes through the compiler, that entire line disappears from the first R to the last }. If it evaluates to true, the &lt;em&gt;block contents&lt;/em&gt; are  processed normally&amp;emdash;but we still remove the now-extra wrapper block around it both to avoid the overhead as well as ensure that the variable scope etc. are consistent.

	&lt;p&gt;This should be useful for at least removing those generally-unnecessary debug statements etc.; the &lt;code&gt;if $DEBUG&lt;/code&gt; does not cost much by itself but it adds up over time. The other easy target are platform/library/etc. specific sections that can be omitted in some cases. It &lt;em&gt;is&lt;/em&gt;  general-purpose in that the only limiting factor is the condition variable (or possibly expression in the future.)&lt;/p&gt;


	&lt;p&gt;The commit is &lt;a href=&quot;http://git.rubini.us/?p=code;a=commit;h=f58c67e33a99f751c3520ab65c96e28a91c45900&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-13:906</id>
    <published>2008-03-13T01:47:00Z</published>
    <updated>2008-03-13T01:56:32Z</updated>
    <category term="rubinius"/>
    <category term="distributed"/>
    <category term="git"/>
    <category term="rbx"/>
    <category term="rubinius"/>
    <category term="ruby"/>
    <category term="rubyspecs"/>
    <category term="spec"/>
    <category term="submodule"/>
    <link href="http://journal.kittensoft.org/2008/3/13/splitting-the-specs-to-a-separate-project-with-git-submodules" rel="alternate" type="text/html"/>
    <title>Splitting the Specs to a Separate Project with git Submodules?</title>
<content type="html">
            &lt;p&gt;If we have a separate RubySpec repository which is included to Rubinius
by means of git&#8217;s submodule support (mounted at spec/ruby/) there are
two types of committers: those who work with RubySpec only and those
who work with Rubinius only. The workflow for a RubySpec-only committer
is very simple:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Clone the main RubySpec to a local working copy.&lt;/li&gt;
		&lt;li&gt;Make changes.&lt;/li&gt;
		&lt;li&gt;Push changes to RubySpec mainline or make a patch if no commit bit.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;That is the end for that committer. Eventually one of the Rubinius
committers will pull in the changes to the Rubinius mainline. For
a Rubinius committer wanting to make a change to specs, the process
is a bit different. One note to make is that having RubySpecs as a
separate project imposes one extra step to the normal workflow even
if not making any changes to the specs. When first cloning the rbx
repo, one must run `git submodule init &#38;&#38; git submodule update` to
pull in the specs&#8212;which is obviously needed to just &lt;span class=&quot;caps&quot;&gt;RUN&lt;/span&gt; the specs.
Then, if a `git pull` contains submodule changes, another update is
usually required with `git submodule update`.&lt;/p&gt;


	&lt;h2&gt;Rubinius Committers&lt;/h2&gt;


	&lt;p&gt;If a person working with the Rubinius repo wants to make changes or
add a new spec or whatever, they can of course choose to just work
on a separate RubySpec checkout. If the committer does not have a
commit bit to RubySpecs, they &lt;span class=&quot;caps&quot;&gt;MUST&lt;/span&gt; use a separate repository. That
works exactly as described above.&lt;/p&gt;


	&lt;p&gt;If, on the other hand, we have an individual who is both a Rubinius
and RubySpecs committer and wants to work directly in the Rubinius
checkout, then the workflow looks like this:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;`cd spec/ruby`&lt;/li&gt;
		&lt;li&gt;`git checkout master`&lt;/li&gt;
		&lt;li&gt;Make and commit changes. (Use branches if you like but come back to master.)&lt;/li&gt;
		&lt;li&gt;Push changes to mainline RubySpecs (just `git push`.) &amp;lt;&#8212;&lt;span class=&quot;caps&quot;&gt;THIS IS IMPORTANT&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;`cd ../..`&lt;/li&gt;
		&lt;li&gt;`git add spec/ruby`  &amp;lt;&#8212;&lt;span class=&quot;caps&quot;&gt;NO TRAILING&lt;/span&gt; /, that overwrites the submodule&lt;/li&gt;
		&lt;li&gt;Commit.&lt;/li&gt;
		&lt;li&gt;Push to mainline Rubinius.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;At this point the updated submodule becomes available to others 
working with the Rubinius repo using `git pull &#38;&#38; git submodule update`.&lt;/p&gt;


	&lt;h2&gt;Full Example&lt;/h2&gt;


Here is a long example of the entire process, covering some ground
that &lt;span class=&quot;caps&quot;&gt;TFM&lt;/span&gt; did not seem to do. Please send in any corrections and/or
improvements.
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;65&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;66&lt;tt&gt;
&lt;/tt&gt;67&lt;tt&gt;
&lt;/tt&gt;68&lt;tt&gt;
&lt;/tt&gt;69&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;70&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;71&lt;tt&gt;
&lt;/tt&gt;72&lt;tt&gt;
&lt;/tt&gt;73&lt;tt&gt;
&lt;/tt&gt;74&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;75&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;76&lt;tt&gt;
&lt;/tt&gt;77&lt;tt&gt;
&lt;/tt&gt;78&lt;tt&gt;
&lt;/tt&gt;79&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;80&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;81&lt;tt&gt;
&lt;/tt&gt;82&lt;tt&gt;
&lt;/tt&gt;83&lt;tt&gt;
&lt;/tt&gt;84&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;85&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;86&lt;tt&gt;
&lt;/tt&gt;87&lt;tt&gt;
&lt;/tt&gt;88&lt;tt&gt;
&lt;/tt&gt;89&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;90&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;91&lt;tt&gt;
&lt;/tt&gt;92&lt;tt&gt;
&lt;/tt&gt;93&lt;tt&gt;
&lt;/tt&gt;94&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;95&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;96&lt;tt&gt;
&lt;/tt&gt;97&lt;tt&gt;
&lt;/tt&gt;98&lt;tt&gt;
&lt;/tt&gt;99&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;101&lt;tt&gt;
&lt;/tt&gt;102&lt;tt&gt;
&lt;/tt&gt;103&lt;tt&gt;
&lt;/tt&gt;104&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;105&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;106&lt;tt&gt;
&lt;/tt&gt;107&lt;tt&gt;
&lt;/tt&gt;108&lt;tt&gt;
&lt;/tt&gt;109&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;110&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;111&lt;tt&gt;
&lt;/tt&gt;112&lt;tt&gt;
&lt;/tt&gt;113&lt;tt&gt;
&lt;/tt&gt;114&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;115&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;116&lt;tt&gt;
&lt;/tt&gt;117&lt;tt&gt;
&lt;/tt&gt;118&lt;tt&gt;
&lt;/tt&gt;119&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;120&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;121&lt;tt&gt;
&lt;/tt&gt;122&lt;tt&gt;
&lt;/tt&gt;123&lt;tt&gt;
&lt;/tt&gt;124&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;125&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;126&lt;tt&gt;
&lt;/tt&gt;127&lt;tt&gt;
&lt;/tt&gt;128&lt;tt&gt;
&lt;/tt&gt;129&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;130&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;131&lt;tt&gt;
&lt;/tt&gt;132&lt;tt&gt;
&lt;/tt&gt;133&lt;tt&gt;
&lt;/tt&gt;134&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;135&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;136&lt;tt&gt;
&lt;/tt&gt;137&lt;tt&gt;
&lt;/tt&gt;138&lt;tt&gt;
&lt;/tt&gt;139&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;140&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;141&lt;tt&gt;
&lt;/tt&gt;142&lt;tt&gt;
&lt;/tt&gt;143&lt;tt&gt;
&lt;/tt&gt;144&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;145&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;146&lt;tt&gt;
&lt;/tt&gt;147&lt;tt&gt;
&lt;/tt&gt;148&lt;tt&gt;
&lt;/tt&gt;149&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;150&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;151&lt;tt&gt;
&lt;/tt&gt;152&lt;tt&gt;
&lt;/tt&gt;153&lt;tt&gt;
&lt;/tt&gt;154&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;155&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;156&lt;tt&gt;
&lt;/tt&gt;157&lt;tt&gt;
&lt;/tt&gt;158&lt;tt&gt;
&lt;/tt&gt;159&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;160&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;161&lt;tt&gt;
&lt;/tt&gt;162&lt;tt&gt;
&lt;/tt&gt;163&lt;tt&gt;
&lt;/tt&gt;164&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;165&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;166&lt;tt&gt;
&lt;/tt&gt;167&lt;tt&gt;
&lt;/tt&gt;168&lt;tt&gt;
&lt;/tt&gt;169&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;170&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;171&lt;tt&gt;
&lt;/tt&gt;172&lt;tt&gt;
&lt;/tt&gt;173&lt;tt&gt;
&lt;/tt&gt;174&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;175&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;176&lt;tt&gt;
&lt;/tt&gt;177&lt;tt&gt;
&lt;/tt&gt;178&lt;tt&gt;
&lt;/tt&gt;179&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;180&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;181&lt;tt&gt;
&lt;/tt&gt;182&lt;tt&gt;
&lt;/tt&gt;183&lt;tt&gt;
&lt;/tt&gt;184&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;185&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;186&lt;tt&gt;
&lt;/tt&gt;187&lt;tt&gt;
&lt;/tt&gt;188&lt;tt&gt;
&lt;/tt&gt;189&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;190&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;191&lt;tt&gt;
&lt;/tt&gt;192&lt;tt&gt;
&lt;/tt&gt;193&lt;tt&gt;
&lt;/tt&gt;194&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;195&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;196&lt;tt&gt;
&lt;/tt&gt;197&lt;tt&gt;
&lt;/tt&gt;198&lt;tt&gt;
&lt;/tt&gt;199&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;200&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;201&lt;tt&gt;
&lt;/tt&gt;202&lt;tt&gt;
&lt;/tt&gt;203&lt;tt&gt;
&lt;/tt&gt;204&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;205&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;206&lt;tt&gt;
&lt;/tt&gt;207&lt;tt&gt;
&lt;/tt&gt;208&lt;tt&gt;
&lt;/tt&gt;209&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;210&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;211&lt;tt&gt;
&lt;/tt&gt;212&lt;tt&gt;
&lt;/tt&gt;213&lt;tt&gt;
&lt;/tt&gt;214&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;215&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;216&lt;tt&gt;
&lt;/tt&gt;217&lt;tt&gt;
&lt;/tt&gt;218&lt;tt&gt;
&lt;/tt&gt;219&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;220&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;221&lt;tt&gt;
&lt;/tt&gt;222&lt;tt&gt;
&lt;/tt&gt;223&lt;tt&gt;
&lt;/tt&gt;224&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;225&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;226&lt;tt&gt;
&lt;/tt&gt;227&lt;tt&gt;
&lt;/tt&gt;228&lt;tt&gt;
&lt;/tt&gt;229&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;230&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;231&lt;tt&gt;
&lt;/tt&gt;232&lt;tt&gt;
&lt;/tt&gt;233&lt;tt&gt;
&lt;/tt&gt;234&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;235&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;236&lt;tt&gt;
&lt;/tt&gt;237&lt;tt&gt;
&lt;/tt&gt;238&lt;tt&gt;
&lt;/tt&gt;239&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;240&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;241&lt;tt&gt;
&lt;/tt&gt;242&lt;tt&gt;
&lt;/tt&gt;243&lt;tt&gt;
&lt;/tt&gt;244&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;245&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;246&lt;tt&gt;
&lt;/tt&gt;247&lt;tt&gt;
&lt;/tt&gt;248&lt;tt&gt;
&lt;/tt&gt;249&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;250&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;251&lt;tt&gt;
&lt;/tt&gt;252&lt;tt&gt;
&lt;/tt&gt;253&lt;tt&gt;
&lt;/tt&gt;254&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;255&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;256&lt;tt&gt;
&lt;/tt&gt;257&lt;tt&gt;
&lt;/tt&gt;258&lt;tt&gt;
&lt;/tt&gt;259&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;260&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;261&lt;tt&gt;
&lt;/tt&gt;262&lt;tt&gt;
&lt;/tt&gt;263&lt;tt&gt;
&lt;/tt&gt;264&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;265&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;266&lt;tt&gt;
&lt;/tt&gt;267&lt;tt&gt;
&lt;/tt&gt;268&lt;tt&gt;
&lt;/tt&gt;269&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;270&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;271&lt;tt&gt;
&lt;/tt&gt;272&lt;tt&gt;
&lt;/tt&gt;273&lt;tt&gt;
&lt;/tt&gt;274&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;275&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;276&lt;tt&gt;
&lt;/tt&gt;277&lt;tt&gt;
&lt;/tt&gt;278&lt;tt&gt;
&lt;/tt&gt;279&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;280&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;281&lt;tt&gt;
&lt;/tt&gt;282&lt;tt&gt;
&lt;/tt&gt;283&lt;tt&gt;
&lt;/tt&gt;284&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;285&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;286&lt;tt&gt;
&lt;/tt&gt;287&lt;tt&gt;
&lt;/tt&gt;288&lt;tt&gt;
&lt;/tt&gt;289&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;290&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;291&lt;tt&gt;
&lt;/tt&gt;292&lt;tt&gt;
&lt;/tt&gt;293&lt;tt&gt;
&lt;/tt&gt;294&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;295&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;296&lt;tt&gt;
&lt;/tt&gt;297&lt;tt&gt;
&lt;/tt&gt;298&lt;tt&gt;
&lt;/tt&gt;299&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;300&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;301&lt;tt&gt;
&lt;/tt&gt;302&lt;tt&gt;
&lt;/tt&gt;303&lt;tt&gt;
&lt;/tt&gt;304&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;305&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;306&lt;tt&gt;
&lt;/tt&gt;307&lt;tt&gt;
&lt;/tt&gt;308&lt;tt&gt;
&lt;/tt&gt;309&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;310&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;311&lt;tt&gt;
&lt;/tt&gt;312&lt;tt&gt;
&lt;/tt&gt;313&lt;tt&gt;
&lt;/tt&gt;314&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;315&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;316&lt;tt&gt;
&lt;/tt&gt;317&lt;tt&gt;
&lt;/tt&gt;318&lt;tt&gt;
&lt;/tt&gt;319&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;320&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;321&lt;tt&gt;
&lt;/tt&gt;322&lt;tt&gt;
&lt;/tt&gt;323&lt;tt&gt;
&lt;/tt&gt;324&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;325&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;326&lt;tt&gt;
&lt;/tt&gt;327&lt;tt&gt;
&lt;/tt&gt;328&lt;tt&gt;
&lt;/tt&gt;329&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;330&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;331&lt;tt&gt;
&lt;/tt&gt;332&lt;tt&gt;
&lt;/tt&gt;333&lt;tt&gt;
&lt;/tt&gt;334&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;335&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;336&lt;tt&gt;
&lt;/tt&gt;337&lt;tt&gt;
&lt;/tt&gt;338&lt;tt&gt;
&lt;/tt&gt;339&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;340&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;341&lt;tt&gt;
&lt;/tt&gt;342&lt;tt&gt;
&lt;/tt&gt;343&lt;tt&gt;
&lt;/tt&gt;344&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;345&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;346&lt;tt&gt;
&lt;/tt&gt;347&lt;tt&gt;
&lt;/tt&gt;348&lt;tt&gt;
&lt;/tt&gt;349&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;350&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;351&lt;tt&gt;
&lt;/tt&gt;352&lt;tt&gt;
&lt;/tt&gt;353&lt;tt&gt;
&lt;/tt&gt;354&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;355&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;356&lt;tt&gt;
&lt;/tt&gt;357&lt;tt&gt;
&lt;/tt&gt;358&lt;tt&gt;
&lt;/tt&gt;359&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;360&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;361&lt;tt&gt;
&lt;/tt&gt;362&lt;tt&gt;
&lt;/tt&gt;363&lt;tt&gt;
&lt;/tt&gt;364&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;365&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;366&lt;tt&gt;
&lt;/tt&gt;367&lt;tt&gt;
&lt;/tt&gt;368&lt;tt&gt;
&lt;/tt&gt;369&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;370&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;371&lt;tt&gt;
&lt;/tt&gt;372&lt;tt&gt;
&lt;/tt&gt;373&lt;tt&gt;
&lt;/tt&gt;374&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;375&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;376&lt;tt&gt;
&lt;/tt&gt;377&lt;tt&gt;
&lt;/tt&gt;378&lt;tt&gt;
&lt;/tt&gt;379&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;380&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;381&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  # We will work from scratch to illustrate the process&lt;tt&gt;
&lt;/tt&gt;  $ cd ~/code/tmp&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # OK, first set up our submodule&lt;tt&gt;
&lt;/tt&gt;  $ mkdir rubyspec&lt;tt&gt;
&lt;/tt&gt;  $ cd rubyspec&lt;tt&gt;
&lt;/tt&gt;  $ git init&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in .git/&lt;tt&gt;
&lt;/tt&gt;  $ echo 'rubyspec' &amp;gt; README&lt;tt&gt;
&lt;/tt&gt;  $ git add README&lt;tt&gt;
&lt;/tt&gt;  $ git commit -a -m 'Initial import of rubyspec'&lt;tt&gt;
&lt;/tt&gt;   Created initial commit 4c43e66: Initial import of rubyspec&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 0 deletions(-)&lt;tt&gt;
&lt;/tt&gt;    create mode 100644 README&lt;tt&gt;
&lt;/tt&gt;  $ cd ..&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # OK, now set up the 'public' rubyspec repo (rubyspec.com or whatever)&lt;tt&gt;
&lt;/tt&gt;  $ git clone --bare rubyspec rubyspec.git&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in /Users/user/code/tmp/rubyspec.git/&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Next, we create the superproject, obviously the public rbx repo&lt;tt&gt;
&lt;/tt&gt;  # already exists in reality.&lt;tt&gt;
&lt;/tt&gt;  $ mkdir rbx&lt;tt&gt;
&lt;/tt&gt;  $ cd rbx&lt;tt&gt;
&lt;/tt&gt;  $ git init&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in .git/&lt;tt&gt;
&lt;/tt&gt;  $ echo 'rbx' &amp;gt; README&lt;tt&gt;
&lt;/tt&gt;  $ git add README&lt;tt&gt;
&lt;/tt&gt;  $ git commit -a -m 'RBX import'&lt;tt&gt;
&lt;/tt&gt;   Created initial commit 43b9035: RBX import&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 0 deletions(-)&lt;tt&gt;
&lt;/tt&gt;    create mode 100644 README&lt;tt&gt;
&lt;/tt&gt;  $ cd ..&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # OK, same deal here, make a 'public' repo (git://git.rubini.us in reality)&lt;tt&gt;
&lt;/tt&gt;  $ git clone --bare rbx rbx.git&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in /Users/user/code/tmp/rbx.git/&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Now, let us get rid of the originals so we have a more realistic situation&lt;tt&gt;
&lt;/tt&gt;  $ rm -rf rbx rubyspec&lt;tt&gt;
&lt;/tt&gt;  $ ls&lt;tt&gt;
&lt;/tt&gt;   rbx.git            rubyspec.git&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Next we want to set up the submodule link, and we need a real rbx repo&lt;tt&gt;
&lt;/tt&gt;  $ git clone rbx.git my_rbx&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in /Users/user/code/tmp/my_rbx/.git/&lt;tt&gt;
&lt;/tt&gt;  $ cd my_rbx&lt;tt&gt;
&lt;/tt&gt;  $ ls&lt;tt&gt;
&lt;/tt&gt;   README&lt;tt&gt;
&lt;/tt&gt;  # Now we associate the submodule (in reality we would use the URI, not local path)&lt;tt&gt;
&lt;/tt&gt;  $ mkdir spec&lt;tt&gt;
&lt;/tt&gt;  # We can 'mount' the submodule anywhere in the repo, in this case it goes in spec/ruby/&lt;tt&gt;
&lt;/tt&gt;  $ git submodule add ~/code/tmp/rubyspec.git spec/ruby&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in /Users/user/code/tmp/my_rbx/spec/ruby/.git/&lt;tt&gt;
&lt;/tt&gt;  $ ls -la&lt;tt&gt;
&lt;/tt&gt;   total 16&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  4 user  group  204 Mar 12 19:39 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  238 Mar 12 19:37 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  374 Mar 12 19:39 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group   85 Mar 12 19:39 .gitmodules&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    4 Mar 12 19:37 README&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:39 spec&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # .gitmodules has the tracking info&lt;tt&gt;
&lt;/tt&gt;  $ cat .gitmodules&lt;tt&gt;
&lt;/tt&gt;   [submodule &amp;quot;spec/ruby&amp;quot;]&lt;tt&gt;
&lt;/tt&gt;           path = spec/ruby&lt;tt&gt;
&lt;/tt&gt;           url = /Users/user/code/tmp/rubyspec.git&lt;tt&gt;
&lt;/tt&gt;  # Our rubyspec repo should be in place now&lt;tt&gt;
&lt;/tt&gt;  $ ls -la spec/ruby&lt;tt&gt;
&lt;/tt&gt;   total 8&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  136 Mar 12 19:39 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:39 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  374 Mar 12 19:39 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:39 README&lt;tt&gt;
&lt;/tt&gt;  $ cat spec/ruby/README&lt;tt&gt;
&lt;/tt&gt;   rubyspec&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Now we need to record the submodule in the superproject&lt;tt&gt;
&lt;/tt&gt;  $ git status&lt;tt&gt;
&lt;/tt&gt;   On branch master&lt;tt&gt;
&lt;/tt&gt;   Changes to be committed:&lt;tt&gt;
&lt;/tt&gt;     (use &amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot; to unstage)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;         new file:   .gitmodules&lt;tt&gt;
&lt;/tt&gt;         new file:   spec/ruby&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  $ git commit -m 'Imported rubyspec submodule'&lt;tt&gt;
&lt;/tt&gt;   Created commit 0ae5cd3: Imported rubyspec submodule&lt;tt&gt;
&lt;/tt&gt;    2 files changed, 4 insertions(+), 0 deletions(-)&lt;tt&gt;
&lt;/tt&gt;    create mode 100644 .gitmodules&lt;tt&gt;
&lt;/tt&gt;    create mode 160000 spec/ruby&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # And then record this over at the mainline&lt;tt&gt;
&lt;/tt&gt;  $ git push&lt;tt&gt;
&lt;/tt&gt;   Counting objects: 5, done.&lt;tt&gt;
&lt;/tt&gt;   Compressing objects: 100% (3/3), done.&lt;tt&gt;
&lt;/tt&gt;   Writing objects: 100% (4/4), 439 bytes, done.&lt;tt&gt;
&lt;/tt&gt;   Total 4 (delta 0), reused 0 (delta 0)&lt;tt&gt;
&lt;/tt&gt;   Unpacking objects: 100% (4/4), done.&lt;tt&gt;
&lt;/tt&gt;   To /Users/user/code/tmp/rbx.git&lt;tt&gt;
&lt;/tt&gt;      43b9035..0ae5cd3  master -&amp;gt; master&lt;tt&gt;
&lt;/tt&gt;  $ cd ..&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Alright. Now, our test situation is that Joe just hacks on rubyspec and&lt;tt&gt;
&lt;/tt&gt;  # Bob hacks on rubyspec as a part of rbx!&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Let us create Bob's repo quick first:&lt;tt&gt;
&lt;/tt&gt;  $ git clone rbx.git bobs_rbx&lt;tt&gt;
&lt;/tt&gt;  $ cd bobs_rbx&lt;tt&gt;
&lt;/tt&gt;  $ ls -la&lt;tt&gt;
&lt;/tt&gt;   total 8&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  4 user  group  204 Mar 12 19:47 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  9 user  group  306 Mar 12 19:44 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  374 Mar 12 19:44 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group   85 Mar 12 19:44 .gitmodules&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    0 Mar 12 19:45 README&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:44 spec&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Now, as you can see, a pristine checkout of a superproject will not actually contain the submodule code&lt;tt&gt;
&lt;/tt&gt;  $ ls -la spec/ruby&lt;tt&gt;
&lt;/tt&gt;   total 0&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  2 user  group   68 Mar 12 19:44 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:44 ..&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # We need to first init to properly link the modules and then update to pull the data in&lt;tt&gt;
&lt;/tt&gt;  $ git submodule init&lt;tt&gt;
&lt;/tt&gt;   Submodule 'spec/ruby' (/Users/user/code/tmp/rubyspec.git) registered for path 'spec/ruby'&lt;tt&gt;
&lt;/tt&gt;  $ git submodule update&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in /Users/user/code/tmp/bobs_rbx/spec/ruby/.git/&lt;tt&gt;
&lt;/tt&gt;   Submodule path 'spec/ruby': checked out '4c43e665381054478aa7c82da1d1d63b5c258e4b'&lt;tt&gt;
&lt;/tt&gt;  $ ls -la spec/ruby&lt;tt&gt;
&lt;/tt&gt;   total 8&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  136 Mar 12 19:48 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:48 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  408 Mar 12 19:48 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:48 README&lt;tt&gt;
&lt;/tt&gt;  # OK, now it is there. Let us hop out of here for a bit.&lt;tt&gt;
&lt;/tt&gt;  $ cd ..&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Now, Joe is doing some work on his repo which is JUST the rubyspec submodule&lt;tt&gt;
&lt;/tt&gt;  $ git clone rubyspec.git joes_spec&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in /Users/user/code/tmp/joes_spec/.git/&lt;tt&gt;
&lt;/tt&gt;  $ cd joes_spec&lt;tt&gt;
&lt;/tt&gt;  $ ls&lt;tt&gt;
&lt;/tt&gt;   README&lt;tt&gt;
&lt;/tt&gt;  # OK, Joe makes a change&lt;tt&gt;
&lt;/tt&gt;  $ echo 'new spec' &amp;gt; spec.rb&lt;tt&gt;
&lt;/tt&gt;  $ git add spec.rb&lt;tt&gt;
&lt;/tt&gt;  $ git commit -m 'Added spec.rb'&lt;tt&gt;
&lt;/tt&gt;   Created commit f380258: Added spec.rb&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 0 deletions(-)&lt;tt&gt;
&lt;/tt&gt;    create mode 100644 spec.rb&lt;tt&gt;
&lt;/tt&gt;  # Joe pushes to mainline of rubyspec&lt;tt&gt;
&lt;/tt&gt;  $ git push&lt;tt&gt;
&lt;/tt&gt;   Counting objects: 4, done.&lt;tt&gt;
&lt;/tt&gt;   Compressing objects: 100% (2/2), done.&lt;tt&gt;
&lt;/tt&gt;   Writing objects: 100% (3/3), 290 bytes, done.&lt;tt&gt;
&lt;/tt&gt;   Total 3 (delta 0), reused 0 (delta 0)&lt;tt&gt;
&lt;/tt&gt;   Unpacking objects: 100% (3/3), done.&lt;tt&gt;
&lt;/tt&gt;   To /Users/user/code/tmp/rubyspec.git&lt;tt&gt;
&lt;/tt&gt;      4c43e66..f380258  master -&amp;gt; master&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Now, let us check in with Bob who has his clone of the rbx repo&lt;tt&gt;
&lt;/tt&gt;  $ cd bobs_rbx&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Bob does not have Joe's spec yet&lt;tt&gt;
&lt;/tt&gt;  $ ls -la spec/ruby/&lt;tt&gt;
&lt;/tt&gt;   total 8&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  136 Mar 12 19:48 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:48 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  408 Mar 12 19:48 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:48 README&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Updating does not seem to work either!&lt;tt&gt;
&lt;/tt&gt;  $ git submodule update&lt;tt&gt;
&lt;/tt&gt;  $ ls -la spec/ruby/&lt;tt&gt;
&lt;/tt&gt;   total 8&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  136 Mar 12 19:48 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:48 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  408 Mar 12 19:48 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:48 README&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Did Joe's change get registered? Let us check..&lt;tt&gt;
&lt;/tt&gt;  $ cd ..&lt;tt&gt;
&lt;/tt&gt;  $ git clone rubyspec.git check_joes_change&lt;tt&gt;
&lt;/tt&gt;   Initialized empty Git repository in /Users/user/code/tmp/check_joes_change/.git/&lt;tt&gt;
&lt;/tt&gt;  $ ls check_joes_change/&lt;tt&gt;
&lt;/tt&gt;   README  spec.rb&lt;tt&gt;
&lt;/tt&gt;  # Yep, it is there! So what is going on?&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Right, we need to update the mainline rbx. Technically Bob could actually do this&lt;tt&gt;
&lt;/tt&gt;  # too but for now, let us pretend that some access control allows only me to make&lt;tt&gt;
&lt;/tt&gt;  # that update. So back to my repo.&lt;tt&gt;
&lt;/tt&gt;  $ cd my_rbx/&lt;tt&gt;
&lt;/tt&gt;  $&lt;tt&gt;
&lt;/tt&gt;  # Now, we need to grab the change first&lt;tt&gt;
&lt;/tt&gt;  $ cd spec/ruby/&lt;tt&gt;
&lt;/tt&gt;  $ ls&lt;tt&gt;
&lt;/tt&gt;   README&lt;tt&gt;
&lt;/tt&gt;  $ git status&lt;tt&gt;
&lt;/tt&gt;   On branch master&lt;tt&gt;
&lt;/tt&gt;   nothing to commit (working directory clean)&lt;tt&gt;
&lt;/tt&gt;  $ git pull&lt;tt&gt;
&lt;/tt&gt;   remote: Counting objects: 4, done.&lt;tt&gt;
&lt;/tt&gt;   remote: Compressing objects: 100% (2/2)remote: , done.&lt;tt&gt;
&lt;/tt&gt;   remote: Total 3 (delta 0), reused 0 (delta 0)&lt;tt&gt;
&lt;/tt&gt;   Unpacking objects: 100% (3/3), done.&lt;tt&gt;
&lt;/tt&gt;   From /Users/user/code/tmp/rubyspec&lt;tt&gt;
&lt;/tt&gt;      4c43e66..f380258  master     -&amp;gt; origin/master&lt;tt&gt;
&lt;/tt&gt;   Updating 4c43e66..f380258&lt;tt&gt;
&lt;/tt&gt;   Fast forward&lt;tt&gt;
&lt;/tt&gt;    spec.rb |    1 +&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 0 deletions(-)&lt;tt&gt;
&lt;/tt&gt;    create mode 100644 spec.rb&lt;tt&gt;
&lt;/tt&gt;  $ ls -la&lt;tt&gt;
&lt;/tt&gt;   total 16&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  170 Mar 12 19:54 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:39 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  442 Mar 12 19:54 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:39 README&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:54 spec.rb&lt;tt&gt;
&lt;/tt&gt;  # OK, there it is!&lt;tt&gt;
&lt;/tt&gt;  $ cd ../../&lt;tt&gt;
&lt;/tt&gt;  # So, need to record this update in the superproject&lt;tt&gt;
&lt;/tt&gt;  $ git status&lt;tt&gt;
&lt;/tt&gt;   On branch master&lt;tt&gt;
&lt;/tt&gt;   Changed but not updated:&lt;tt&gt;
&lt;/tt&gt;     (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;         modified:   spec/ruby&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;   no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)&lt;tt&gt;
&lt;/tt&gt;  $ git add spec/ruby&lt;tt&gt;
&lt;/tt&gt;  $ git commit -m 'Updated our rubyspec checkout to newest version'&lt;tt&gt;
&lt;/tt&gt;   Created commit 0d96517: Updated our rubyspec checkout to newest version&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 1 deletions(-)&lt;tt&gt;
&lt;/tt&gt;  # And then push this change to mainline&lt;tt&gt;
&lt;/tt&gt;  $ git push&lt;tt&gt;
&lt;/tt&gt;   Counting objects: 5, done.&lt;tt&gt;
&lt;/tt&gt;   Compressing objects: 100% (2/2), done.&lt;tt&gt;
&lt;/tt&gt;   Writing objects: 100% (3/3), 319 bytes, done.&lt;tt&gt;
&lt;/tt&gt;   Total 3 (delta 1), reused 0 (delta 0)&lt;tt&gt;
&lt;/tt&gt;   Unpacking objects: 100% (3/3), done.&lt;tt&gt;
&lt;/tt&gt;   To /Users/user/code/tmp/rbx.git&lt;tt&gt;
&lt;/tt&gt;      0ae5cd3..0d96517  master -&amp;gt; master&lt;tt&gt;
&lt;/tt&gt;  $ cd ..&lt;tt&gt;
&lt;/tt&gt;  $ cd bobs_rbx/&lt;tt&gt;
&lt;/tt&gt;  # NOW Bob should be able to access it&lt;tt&gt;
&lt;/tt&gt;  $ git submodule update&lt;tt&gt;
&lt;/tt&gt;  # No? How about this:&lt;tt&gt;
&lt;/tt&gt;  $ git pull&lt;tt&gt;
&lt;/tt&gt;   remote: Counting objects: 5, done.&lt;tt&gt;
&lt;/tt&gt;   remote: Compressing objects: 100% (2/2), done.&lt;tt&gt;
&lt;/tt&gt;   remote: Total 3 (delta 1), reused 0 (delta 0)&lt;tt&gt;
&lt;/tt&gt;   Unpacking objects: 100% (3/3), done.&lt;tt&gt;
&lt;/tt&gt;   From /Users/user/code/tmp/rbx&lt;tt&gt;
&lt;/tt&gt;      0ae5cd3..0d96517  master     -&amp;gt; origin/master&lt;tt&gt;
&lt;/tt&gt;   Updating 0ae5cd3..0d96517&lt;tt&gt;
&lt;/tt&gt;   README: needs update&lt;tt&gt;
&lt;/tt&gt;   Fast forward&lt;tt&gt;
&lt;/tt&gt;    spec/ruby |    2 +-&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 1 deletions(-)&lt;tt&gt;
&lt;/tt&gt;  # That by itself does not update yet&lt;tt&gt;
&lt;/tt&gt;  $ ls -la spec/ruby&lt;tt&gt;
&lt;/tt&gt;   total 8&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  136 Mar 12 19:48 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:48 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  408 Mar 12 19:48 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:48 README&lt;tt&gt;
&lt;/tt&gt;  # Now we must update&lt;tt&gt;
&lt;/tt&gt;  $ git submodule update&lt;tt&gt;
&lt;/tt&gt;   Submodule path 'spec/ruby': checked out 'f38025812763dd8ee44beebcc0c8a3997c9aac0f'&lt;tt&gt;
&lt;/tt&gt;  # And now it is there&lt;tt&gt;
&lt;/tt&gt;  $ ls -la spec/ruby&lt;tt&gt;
&lt;/tt&gt;   total 16&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  170 Mar 12 19:57 .&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  3 user  group  102 Mar 12 19:48 ..&lt;tt&gt;
&lt;/tt&gt;   drwxr-xr-x  7 user  group  408 Mar 12 19:57 .git&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:48 README&lt;tt&gt;
&lt;/tt&gt;   -rw-r--r--  1 user  group    9 Mar 12 19:57 spec.rb&lt;tt&gt;
&lt;/tt&gt;  # And there we go, properly updated now&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Of course, Bob can make a few changes now too. Here is the only potential problem.&lt;tt&gt;
&lt;/tt&gt;  # First, change something in rbx.&lt;tt&gt;
&lt;/tt&gt;  $ echo 'RTFM' &amp;gt; INSTALL&lt;tt&gt;
&lt;/tt&gt;  $ git add INSTALL&lt;tt&gt;
&lt;/tt&gt;  $ git commit -m 'Installation instructions'&lt;tt&gt;
&lt;/tt&gt;   Created commit c0e6667: Installation instructions&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 0 deletions(-)&lt;tt&gt;
&lt;/tt&gt;    create mode 100644 INSTALL&lt;tt&gt;
&lt;/tt&gt;  $ git push&lt;tt&gt;
&lt;/tt&gt;   Counting objects: 4, done.&lt;tt&gt;
&lt;/tt&gt;   Compressing objects: 100% (2/2), done.&lt;tt&gt;
&lt;/tt&gt;   Writing objects: 100% (3/3), 361 bytes, done.&lt;tt&gt;
&lt;/tt&gt;   Total 3 (delta 0), reused 0 (delta 0)&lt;tt&gt;
&lt;/tt&gt;   Unpacking objects: 100% (3/3), done.&lt;tt&gt;
&lt;/tt&gt;   To /Users/user/code/tmp/rbx.git&lt;tt&gt;
&lt;/tt&gt;      0d96517..c0e6667  master -&amp;gt; master&lt;tt&gt;
&lt;/tt&gt;  # That was normal. Now, what if Bob wants to make changes to rubyspec?&lt;tt&gt;
&lt;/tt&gt;  # He can make the changes normally. If he has commit access, he can&lt;tt&gt;
&lt;/tt&gt;  # just hop over and do so.&lt;tt&gt;
&lt;/tt&gt;  $ cd spec/ruby&lt;tt&gt;
&lt;/tt&gt;  $ ls&lt;tt&gt;
&lt;/tt&gt;   README  spec.rb&lt;tt&gt;
&lt;/tt&gt;  # One notable thing is that this is a detached by default to avoid some problems, so&lt;tt&gt;
&lt;/tt&gt;  # Bob must go to a real branch.&lt;tt&gt;
&lt;/tt&gt;  $ git status&lt;tt&gt;
&lt;/tt&gt;   Not currently on any branch.&lt;tt&gt;
&lt;/tt&gt;   nothing to commit (working directory clean)&lt;tt&gt;
&lt;/tt&gt;  $ git checkout master&lt;tt&gt;
&lt;/tt&gt;   Previous HEAD position was b292add... Added a spec&lt;tt&gt;
&lt;/tt&gt;   Switched to branch &amp;quot;master&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  $ echo 'my spec' &amp;gt; spec2.rb&lt;tt&gt;
&lt;/tt&gt;  $ git add spec2.rb&lt;tt&gt;
&lt;/tt&gt;  $ git commit -m 'Added a spec'&lt;tt&gt;
&lt;/tt&gt;   Created commit b1e7bdb: Added a spec&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 0 deletions(-)&lt;tt&gt;
&lt;/tt&gt;    create mode 100644 spec2.rb&lt;tt&gt;
&lt;/tt&gt;  # Now Bob can just push it if he has access&lt;tt&gt;
&lt;/tt&gt;  $ git push&lt;tt&gt;
&lt;/tt&gt;   Counting objects: 4, done.&lt;tt&gt;
&lt;/tt&gt;   Compressing objects: 100% (2/2), done.&lt;tt&gt;
&lt;/tt&gt;   Writing objects: 100% (3/3), 313 bytes, done.&lt;tt&gt;
&lt;/tt&gt;   Total 3 (delta 0), reused 0 (delta 0)&lt;tt&gt;
&lt;/tt&gt;   Unpacking objects: 100% (3/3), done.&lt;tt&gt;
&lt;/tt&gt;   To /Users/user/code/tmp/rubyspec.git&lt;tt&gt;
&lt;/tt&gt;      f380258..b1e7bdb  master -&amp;gt; master&lt;tt&gt;
&lt;/tt&gt;  # As the data shows, we directly updated the rubyspec project&lt;tt&gt;
&lt;/tt&gt;  $&lt;tt&gt;
&lt;/tt&gt;  # Obviously, if Bob did not have commit rights, he would do the normal git-format-patch dance instead&lt;tt&gt;
&lt;/tt&gt;  $&lt;tt&gt;
&lt;/tt&gt;  # Now, the problem&lt;tt&gt;
&lt;/tt&gt;  $ cd ../..&lt;tt&gt;
&lt;/tt&gt;  $ git status&lt;tt&gt;
&lt;/tt&gt;   On branch master&lt;tt&gt;
&lt;/tt&gt;   Changed but not updated:&lt;tt&gt;
&lt;/tt&gt;     (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;         modified:   spec/ruby&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;   no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)&lt;tt&gt;
&lt;/tt&gt;  # This shows the change we made--and adding it is perfectly safe so long&lt;tt&gt;
&lt;/tt&gt;  # as we do it correctly. This is incorrect:&lt;tt&gt;
&lt;/tt&gt;  $ git add spec/ruby/&lt;tt&gt;
&lt;/tt&gt;  $ git status&lt;tt&gt;
&lt;/tt&gt;   On branch master&lt;tt&gt;
&lt;/tt&gt;   Changes to be committed:&lt;tt&gt;
&lt;/tt&gt;     (use &amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot; to unstage)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;         deleted:    spec/ruby&lt;tt&gt;
&lt;/tt&gt;         new file:   spec/ruby/README&lt;tt&gt;
&lt;/tt&gt;         new file:   spec/ruby/spec.rb&lt;tt&gt;
&lt;/tt&gt;         new file:   spec/ruby/spec2.rb&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  $ git reset --hard HEAD&lt;tt&gt;
&lt;/tt&gt;   HEAD is now at c0e6667... Installation instructions&lt;tt&gt;
&lt;/tt&gt;  # OK, so that is not good. The trailing / has git thinking this is a new&lt;tt&gt;
&lt;/tt&gt;  # path which overwrites the submodule. So, without:&lt;tt&gt;
&lt;/tt&gt;  $ git add spec/ruby&lt;tt&gt;
&lt;/tt&gt;  $ git status&lt;tt&gt;
&lt;/tt&gt;   On branch master&lt;tt&gt;
&lt;/tt&gt;   Changes to be committed:&lt;tt&gt;
&lt;/tt&gt;     (use &amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot; to unstage)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;         modified:   spec/ruby&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # So that worked fine. Now we can update mainline normally&lt;tt&gt;
&lt;/tt&gt;  $ git commit -m 'New spec in rubyspec, updated here and pushed to rubyspec mainline'&lt;tt&gt;
&lt;/tt&gt;   Created commit 3749f4b: New spec in rubyspec, updated here and pushed to rubyspec mainline&lt;tt&gt;
&lt;/tt&gt;    1 files changed, 1 insertions(+), 1 deletions(-)&lt;tt&gt;
&lt;/tt&gt;  $ git push&lt;tt&gt;
&lt;/tt&gt;   Counting objects: 5, done.&lt;tt&gt;
&lt;/tt&gt;   Compressing objects: 100% (2/2), done.&lt;tt&gt;
&lt;/tt&gt;   Writing objects: 100% (3/3), 331 bytes, done.&lt;tt&gt;
&lt;/tt&gt;   Total 3 (delta 1), reused 0 (delta 0)&lt;tt&gt;
&lt;/tt&gt;   Unpacking objects: 100% (3/3), done.&lt;tt&gt;
&lt;/tt&gt;   To /Users/user/code/tmp/rbx.git&lt;tt&gt;
&lt;/tt&gt;      c0e6667..3749f4b  master -&amp;gt; master&lt;tt&gt;
&lt;/tt&gt;  $&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-12:905</id>
    <published>2008-03-12T05:08:00Z</published>
    <updated>2008-03-12T05:25:45Z</updated>
    <category term="code"/>
    <category term="mod_rubinius"/>
    <category term="rubinius"/>
    <category term="ruby"/>
    <link href="http://journal.kittensoft.org/2008/3/12/mod_rubinius-update" rel="alternate" type="text/html"/>
    <title>mod_rubinius Update</title>
<content type="html">
            &lt;p&gt;I have gotten underway with the actual coding part of mod_rubinius: as expected, quite a bit of brainpower went into trying to figure out the (hopefully) best design possible. The main focus is still ease of deployment, support for shared hosting and, of course, performance. At the simplest, `rake install` and adding the location mapping to httpd.conf followed by a restart should be sufficient to get up and running but there will be quite a few options that &lt;strong&gt;can&lt;/strong&gt; be used to achieve everything we want.&lt;/p&gt;


	&lt;p&gt;One thing of note is that I will not make any attempt to integrate with &lt;a href=&quot;http://ruby-lang.org&quot;&gt;MatzRuby&lt;/a&gt;, &lt;a href=&quot;http://jruby.org&quot;&gt;JRuby&lt;/a&gt; or any of the other implementations. We believe &lt;a href=&quot;http://rubini.us&quot;&gt;Rubinius&lt;/a&gt; has some unique features that we can take advantage of (although the first draft will certainly do so to its fullest.) The current design is founded on this premise and, as things stand, it will be impossible to use the meat of mod_rubinius with any other implementation&#8212;some parts may be useful for others too.&lt;/p&gt;


	&lt;p&gt;But that is all for now. Once I have something publishable, I will open the development process up.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-12:904</id>
    <published>2008-03-12T04:46:00Z</published>
    <updated>2008-03-12T05:08:01Z</updated>
    <category term="mac"/>
    <category term="applescript"/>
    <category term="command line"/>
    <category term="iterm"/>
    <category term="mac"/>
    <category term="ruby"/>
    <category term="scripting"/>
    <category term="security"/>
    <category term="ssh"/>
    <category term="su"/>
    <category term="sudo"/>
    <link href="http://journal.kittensoft.org/2008/3/12/scripting-iterm-with-applescript" rel="alternate" type="text/html"/>
    <title>Scripting iTerm with AppleScript</title>
<content type="html">
            &lt;p&gt;After a short embarrassment with &lt;span class=&quot;caps&quot;&gt;SSH I&lt;/span&gt; decided I needed a bit of &lt;a href=&quot;http://www.thrysoee.dk/xtermcontrol/'s&quot;&gt;xtermcontrol&lt;/a&gt; functionality. On the rest of my machines, I use it to automatically switch to a green background when in an &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt; session among other things.&lt;/p&gt;


	&lt;p&gt;As a complete newb, &lt;a href=&quot;http://www.apple.com/applescript&quot;&gt;AppleScript&lt;/a&gt; syntax is a bit confusing. The idea is clear, the implementation seems somewhat awkward (particularly since I saw no way to dynamically determine properties.) So I chose to use the &lt;a href=&quot;http://rb-appscript.rubyforge.org&quot;&gt;rb-appscript&lt;/a&gt; abstraction, installed through Gems. It enables accessing a high-level AppleScript-equivalent in Ruby. With this, I created the initial frail and simple draft:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# ~/Scripts/iterm.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;rubygems&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;appscript&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;include &lt;span class=&quot;co&quot;&gt;Appscript&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# Map some values or just pass-through&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;expand&lt;/span&gt;(property)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;case&lt;/span&gt; property&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;bg&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;background_color&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    property&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;include &lt;span class=&quot;co&quot;&gt;Appscript&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;app(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;iTerm&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).current_terminal.current_session.send(expand(&lt;span class=&quot;pc&quot;&gt;ARGV&lt;/span&gt;.first)).set(&lt;span class=&quot;pc&quot;&gt;ARGV&lt;/span&gt;.last)&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This allows, for example, changing the background color with `ruby ~/Scripts/iterm.rb bg blue` etc.&lt;/p&gt;


	&lt;p&gt;To hook it up, I set up a function in my ~/.bashrc.osx (which is sourced in ~/.bashrc obviously):&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  ssh() {&lt;tt&gt;
&lt;/tt&gt;    ruby ~/Scripts/iterm.rb bg blue&lt;tt&gt;
&lt;/tt&gt;    command ssh &amp;quot;$@&amp;quot;&lt;tt&gt;
&lt;/tt&gt;    ruby ~/Scripts/iterm.rb bg black&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Obviously a lot of room for improvement but it just wraps any &lt;code&gt;ssh&lt;/code&gt; invocation by first changing the bg, then launching &lt;code&gt;ssh&lt;/code&gt; itself with whatever arguments were given and then switching back when &lt;code&gt;ssh&lt;/code&gt; exits (whether requested or through an error.)&lt;/p&gt;


	&lt;p&gt;Gives me a nice blue background to easily distinguish &lt;code&gt;ssh&lt;/code&gt; sessions among my terminals. This is exceptionally handy to use for &lt;code&gt;su&lt;/code&gt; sessions if you use those. It is much harder to accidentally leave a bright red terminal session running than a regular-looking one. (I always only use &lt;code&gt;sudo&lt;/code&gt; anyway, but not everyone does.)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-12:903</id>
    <published>2008-03-12T04:41:00Z</published>
    <updated>2008-03-12T04:45:51Z</updated>
    <category term="mac"/>
    <category term="bsd"/>
    <category term="cli"/>
    <category term="dvorak"/>
    <category term="gui"/>
    <category term="keyboard"/>
    <category term="linux"/>
    <category term="mac"/>
    <category term="spaces"/>
    <category term="unix"/>
    <link href="http://journal.kittensoft.org/2008/3/12/spaces-keyboard-shortcuts" rel="alternate" type="text/html"/>
    <title>Spaces Keyboard Shortcuts</title>
<content type="html">
            &lt;p&gt;Spaces is nice to have on &lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt;&#8212;it is just the concept of workspaces moved to Aqua. The only problem with it is that it relies heavily on the mouse/GUI side of things. You can switch workspaces easily enough with Cmd + number but moving windows around is a bit trickier. The least inconvenient way of doing this is to click on the desired window and while keeping the mouse button pressed, use the Cmd + number for the desired workspace. Hopefully next update will allow something like Shift + Cmd + number to move the currently focused window.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-09:902</id>
    <published>2008-03-09T11:43:00Z</published>
    <updated>2008-03-09T12:03:09Z</updated>
    <category term="mac"/>
    <category term="bsd"/>
    <category term="commandline"/>
    <category term="gui"/>
    <category term="ifconfig"/>
    <category term="ip"/>
    <category term="mac"/>
    <category term="networking"/>
    <link href="http://journal.kittensoft.org/2008/3/9/setting-an-ip-alias-on-os-x-leopard" rel="alternate" type="text/html"/>
    <title>Setting an IP Alias on OS X Leopard</title>
<content type="html">
            &lt;p&gt;If you need to add a secondary IP or an IP alias to a network interface on Mac, you are in the same situation I was just a moment ago. In the interest of posterity, I am documenting my exploration of Macistan when I encounter something that seems interesting or divergent.&lt;/p&gt;


	&lt;p&gt;Note that if you are setting up something using a second network interface, this does not apply. You can just set it up normally.  My network is rather strange: I have it set up so that the normal operation is through an &#8220;intranet&#8221; &lt;span class=&quot;caps&quot;&gt;LAN&lt;/span&gt; connecting through a router/DNS and firewall but there is also the option of connecting directly using &lt;span class=&quot;caps&quot;&gt;ISP DHCP&lt;/span&gt;&#8212;still passing through the firewall of course. Because I want to have the internal IP available regardless of external mode, it is set as an alias on each interface for the latter times.&lt;/p&gt;


	&lt;p&gt;All respectable people would of course first want to just use `ifconfig` to accomplish aliasing but since on a Mac it is more of a wrapper, this task is best done through System Preferences&#8217; Networking pane.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Unlock and authenticate. (You never leave those little locks open, do you?)&lt;/li&gt;
		&lt;li&gt;Select the current connection you want the alias for&lt;/li&gt;
		&lt;li&gt;Click the cogwheel and Duplicate Service&lt;/li&gt;
		&lt;li&gt;Give it a sensible name such as &#8220;Intranet IP (&amp;lt;interface&gt;)&#8221; &lt;/li&gt;
		&lt;li&gt;Set Configure to Manual&lt;/li&gt;
		&lt;li&gt;Input the proper values for your setup (only the IP and Subnet Mask are really necessary)&lt;/li&gt;
		&lt;li&gt;Lock the pane&lt;/li&gt;
	&lt;/ol&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-06:901</id>
    <published>2008-03-06T07:33:00Z</published>
    <updated>2008-03-07T15:55:07Z</updated>
    <category term="lenovo"/>
    <category term="mac"/>
    <category term="notebook"/>
    <category term="os x"/>
    <category term="x61"/>
    <link href="http://journal.kittensoft.org/2008/3/6/os-x-on-thinkpad-x61" rel="alternate" type="text/html"/>
    <title>OS X on ThinkPad x61</title>
<content type="html">
            &lt;p&gt;Hurray!&lt;/p&gt;


	&lt;p&gt;I managed to install &lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt; on my new ThinkPad x61! Full 10.5.2, I do need to install a couple other packages to get full power management and ethernet still, though, but that is a job for tomorrow.&lt;/p&gt;


	&lt;p&gt;Poor-quality pics: &lt;a href=&quot;http://files.kittensoft.org/public/legit.jpg&quot;&gt;outside&lt;/a&gt; and &lt;a href=&quot;http://files.kittensoft.org/public/osx_x61.jpg&quot;&gt;with its big brother&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I have like, totally &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; added my notes about the installation to &lt;a href=&quot;http://forum.insanelymac.com/index.php?showtopic=87574&quot;&gt;this excellent thread that got me started&lt;/a&gt;. So if you are planning something like this, you should probably not look there.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-03:899</id>
    <published>2008-03-03T01:35:00Z</published>
    <updated>2008-03-03T01:37:14Z</updated>
    <category term="hardware"/>
    <category term="mac"/>
    <category term="thinkpad"/>
    <category term="x61"/>
    <link href="http://journal.kittensoft.org/2008/3/3/external-dvd-readers" rel="alternate" type="text/html"/>
    <title>External DVD Readers</title>
<content type="html">
            &lt;p&gt;Anyone?&lt;/p&gt;


	&lt;p&gt;Seriously, anyone?&lt;/p&gt;


	&lt;p&gt;I can find &lt;strong&gt;internal&lt;/strong&gt; DVD readers and external CD readers and external &lt;span class=&quot;caps&quot;&gt;DVD&lt;/span&gt;/CD read/writers but not plain external &lt;span class=&quot;caps&quot;&gt;DVD&lt;/span&gt; readers. It boggles the mind.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-03:898</id>
    <published>2008-03-03T01:00:00Z</published>
    <updated>2008-03-03T01:28:18Z</updated>
    <category term="mac"/>
    <category term="jdk"/>
    <category term="jruby"/>
    <category term="jvm"/>
    <category term="mac"/>
    <category term="programming"/>
    <category term="ruby"/>
    <link href="http://journal.kittensoft.org/2008/3/3/installing-jruby-on-os-x-using-the-soylatte-java-6-jdk" rel="alternate" type="text/html"/>
    <title>Installing JRuby on OS X Using the SoyLatte Java 6 JDK</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://headius.com/blog&quot;&gt;headius&lt;/a&gt; often kindly tries to get me to actually overcome my lingering Java allergies to try to run &lt;a href=&quot;http://jruby.codehaus.org&quot;&gt;JRuby&lt;/a&gt; and now my excuse of FreeBSD amd64 not being Java-friendly has been stripped away.&lt;/p&gt;


	&lt;p&gt;In reality JRuby of course is a great project running a pretty impressive platform, the &lt;span class=&quot;caps&quot;&gt;JVM&lt;/span&gt;, so this should be an interesting experiment. headius suggested using the &lt;a href=&quot;http://landonf.bikemonkey.org/static/soylatte/&quot;&gt;SoyLatte&lt;/a&gt; version of &lt;span class=&quot;caps&quot;&gt;JDK&lt;/span&gt;/JRE and looks like not without cause. It is an implementation of Java 6 based off the &lt;span class=&quot;caps&quot;&gt;BSD&lt;/span&gt; port. So, steps taken:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Java
	&lt;ol&gt;
	&lt;li&gt;Downloaded the &lt;a href=&quot;http://hg.bikemonkey.org/archive/javasrc_1_6_jrl_darwin/soylatte16-amd64-1.0.2.tar.bz2&quot;&gt;amd64 binary&lt;/a&gt; from the Soylatte site (Intel Core 2 Duo is, oddly enough, kind_of? amd64&#8212;EM64T to be precise)&lt;/li&gt;
		&lt;li&gt;The directory needs to be extracted somewhere, I chose &lt;code&gt;/opt/local&lt;/code&gt;
	&lt;ol&gt;
	&lt;li&gt;`&lt;code&gt;cd /opt/local&lt;/code&gt;`&lt;/li&gt;
		&lt;li&gt;`&lt;code&gt;sudo tar xjvpf /path/to/tar.bz2&lt;/code&gt;`&lt;/li&gt;
		&lt;li&gt;`&lt;code&gt;sudo mv long_name soylatte16&lt;/code&gt;` &lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Set the Java environment variables (these go in my &lt;code&gt;~/.bashrc&lt;/code&gt;)
	&lt;ol&gt;
	&lt;li&gt;&lt;code&gt;export JAVA_HOME=/opt/local/soylatte16&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;export PATH=/opt/local/soylatte16/bin:$PATH&lt;/code&gt; (front to make sure it overrides system JREs)&lt;/li&gt;
		&lt;li&gt;I wanted to try NetBeans which expects certain paths: `&lt;code&gt;ln -s /opt/local/soylatte16 /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home&lt;/code&gt;`&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;JRuby
	&lt;ol&gt;
	&lt;li&gt;Downloaded the &lt;a href=&quot;http://dist.codehaus.org/jruby/jruby-bin-1.1b1.tar.gz&quot;&gt;1.1b binary package&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Extracted in &lt;code&gt;/opt/local&lt;/code&gt; again
	&lt;ol&gt;
	&lt;li&gt;`&lt;code&gt;cd /opt/local&lt;/code&gt;`&lt;/li&gt;
		&lt;li&gt;`&lt;code&gt;sudo tar xzvpf /path/to/tar.gz&lt;/code&gt;`&lt;/li&gt;
		&lt;li&gt;`&lt;code&gt;sudo mv long_name jruby&lt;/code&gt;`&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;`&lt;code&gt;export PATH=$PATH:/opt/local/jruby/bin&lt;/code&gt;` to make it visible, &lt;code&gt;~/.bashrc&lt;/code&gt; again&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Pick up the new envs: `&lt;code&gt;source ~/.bashrc&lt;/code&gt;`&lt;/li&gt;
		&lt;li&gt;Test: `&lt;code&gt;jruby -v&lt;/code&gt;`&lt;/li&gt;
		&lt;li&gt;Hooray!&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Now to see if I can come up with something sensible to use this for.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-02:897</id>
    <published>2008-03-02T05:34:00Z</published>
    <updated>2008-03-02T05:40:05Z</updated>
    <category term="mac"/>
    <category term="mac"/>
    <category term="networking"/>
    <category term="osx"/>
    <category term="os x"/>
    <link href="http://journal.kittensoft.org/2008/3/2/hostname-on-os-x" rel="alternate" type="text/html"/>
    <title>Hostname on OS X</title>
<content type="html">
            &lt;p&gt;Looks like this may change in the future, but for now setting your hostname on Leopard is easiest with these two steps:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;`sudo vim /etc/hostconfig`
	&lt;ol&gt;
	&lt;li&gt;Add @HOSTNAME=&#8221;machine.domain.tld&#8221; somewhere&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;`sudo hostname machine.domain.tld` sets it for the current session so you do not need to restart etc.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;The System Preferences &amp;gt; Sharing and Network have some options but I got tired of twiddling with them.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-03-02:896</id>
    <published>2008-03-02T02:32:00Z</published>
    <updated>2008-03-07T17:19:13Z</updated>
    <category term="mac"/>
    <category term="mac"/>
    <category term="osx"/>
    <category term="security"/>
    <category term="sudo"/>
    <link href="http://journal.kittensoft.org/2008/3/2/administrator-root-and-sudo-on-mac-os-x" rel="alternate" type="text/html"/>
    <title>Administrator, root and `sudo` on Mac OS X</title>
<content type="html">
            &lt;p&gt;Colour me paranoid; at least based on my web searches &lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt; users do not seem to suffer from the same aversion to always running under the Administrator account. The first thing I did when I realised that this was in fact the case was to create myself a new Standard account and then assign a better password to the Administrator account that was so helpfully created for me.&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt; does a good job facilitating running as Standard to a point: any time I need admin privileges, I am asked to authenticate as any of the local Administrator users which works pretty well in the &lt;span class=&quot;caps&quot;&gt;GUI&lt;/span&gt;. However, I cannot &lt;code&gt;sudo&lt;/code&gt; at the terminal as a Standard user so I needed to fix that. By default, the &lt;code&gt;root&lt;/code&gt; account is disabled which is frankly a rather silly precaution since any Administrator can use sudo anyway (at least it was not made &lt;code&gt;NOPASSWD&lt;/code&gt;.)  Here are the steps:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Enable &lt;code&gt;root&lt;/code&gt;
	&lt;ol&gt;
	&lt;li&gt;Run &lt;code&gt;Directory Utility&lt;/code&gt; in &lt;code&gt;/Applications/Utilities/&lt;/code&gt; (or through &lt;code&gt;Finder&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;Click the lock and authenticate if necessary&lt;/li&gt;
		&lt;li&gt;Menu, Edit &amp;gt; Enable Root User&lt;/li&gt;
		&lt;li&gt;Menu, Edit &amp;gt; Change Root Password (make this something long and different from your Administrator password)&lt;/li&gt;
		&lt;li&gt;Click the lock to relinquish privileges&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Configure &lt;code&gt;sudo&lt;/code&gt;
	&lt;ol&gt;
	&lt;li&gt;Open up a terminal session&lt;/li&gt;
		&lt;li&gt;Switch to your Administrator account: &lt;code&gt;login &amp;lt;admin unix name&amp;gt;&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;To edit the &lt;code&gt;sudoers&lt;/code&gt; configuration file, use &lt;code&gt;visudo&lt;/code&gt; (despite the name, it does respect &lt;code&gt;EDITOR&lt;/code&gt;): &lt;code&gt;sudo visudo&lt;/code&gt;. You will already have a default file in place with commented sections.&lt;/li&gt;
		&lt;li&gt;Look for the Defaults section and add yourself a few options by inserting a line like this (substitute &#8216;joe&#8217; with your username): &lt;code&gt;Defaults:joe  runaspw, passwd_tries=3, timestamp_timeout=3&lt;/code&gt;. The first part specifies that the default only applies to that user (there are group etc. versions too), &lt;code&gt;runaspw&lt;/code&gt; means whoever invokes &lt;code&gt;sudo&lt;/code&gt; must enter the password for the user account being accessed (you could make this &lt;code&gt;rootpw&lt;/code&gt; instead if you prefer) and the rest means that 3 invalid attempts terminate the sudo attempt and that any successful sudo@ authentication persists for 3 minutes without having to re-enter the password. Use the latter ones with normal caution and not at all on publically accessible machines.&lt;/li&gt;
		&lt;li&gt;Under User Privileges (you already see &lt;code&gt;root&lt;/code&gt; and &lt;code&gt;%admin&lt;/code&gt; there), add a line for yourself: &lt;code&gt;joe  ALL=(ALL) ALL. The syntax may look a bit cryptic but the first ALL designates machine IPs this applies to, the (ALL) specifies the user the command can be run as (given with the &lt;/code&gt;-u@ flag or guessed) and the last &lt;span class=&quot;caps&quot;&gt;ALL&lt;/span&gt; is the set of commands that the user can run with this particular privilege setting. If you are adding programs explicitly instead of giving the &lt;span class=&quot;caps&quot;&gt;ALL&lt;/span&gt; privilege, make sure to use full paths to avoid using a fake location.&lt;/li&gt;
		&lt;li&gt;Look at &lt;code&gt;man sudoers&lt;/code&gt; for further details.&lt;/li&gt;
		&lt;li&gt;Save and quit&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Disable root login
	&lt;ol&gt;
	&lt;li&gt;&lt;code&gt;login &amp;lt;admin unix name&amp;gt;&lt;/code&gt; if you closed the session&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;su&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;chpass&lt;/code&gt; (Leopard correctly updates DirectoryService with &lt;code&gt;chpass&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Caution&lt;/strong&gt;: double-check the paths before entering
	&lt;ol&gt;
	&lt;li&gt;Change Home Directory to &lt;code&gt;/var/empty&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Change Shell to &lt;code&gt;/sbin/nologin&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Save and quit&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;^D&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;In your &lt;code&gt;sshd_config&lt;/code&gt;, &lt;code&gt;PermitRootLogin no&lt;/code&gt;. Also consider &lt;a href=&quot;http://sial.org/howto/openssh/publickey-auth/&quot;&gt;just using key-based authentication&lt;/a&gt;&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;^D&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Test it: &lt;code&gt;sudo echo 'hi'&lt;/code&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;If you ever should need to enable root logins, you &lt;strong&gt;can&lt;/strong&gt; still do &lt;code&gt;sudo chpass&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;That should be all! Now you do not need to separately &lt;code&gt;su&lt;/code&gt; or rely on the &lt;code&gt;sudo&lt;/code&gt; capabilities of your Administrator user.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-02-15:893</id>
    <published>2008-02-15T04:49:00Z</published>
    <updated>2008-02-15T06:30:47Z</updated>
    <category term="rubinius"/>
    <category term="algorithms"/>
    <category term="data structures"/>
    <category term="performance"/>
    <category term="rubinius"/>
    <category term="ruby"/>
    <link href="http://journal.kittensoft.org/2008/2/15/reinventing-the-which-wheel-comes-first" rel="alternate" type="text/html"/>
    <title>Reinventing the Which Wheel Comes First</title>
<content type="html">
            &lt;p&gt;Aside from research, the past few days I have been putzing with reimplementing Rubinius' &lt;code&gt;Array#sort&lt;/code&gt; and &lt;code&gt;Array#sort!&lt;/code&gt; because, well, they sucked. The implementation is an iterative three-way partitioning &lt;a href=&quot;http://en.wikipedia.org/wiki/Quicksort&quot;&gt;Quicksort&lt;/a&gt; that drops down to &lt;a href=&quot;http://en.wikipedia.org/wiki/Insertion_sort&quot;&gt;Insertion Sort&lt;/a&gt; for small &lt;code&gt;Array&lt;/code&gt;s or subpartitions. Two observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The new implementation is at least one order of magnitude faster in all areas compared to the old one.    Pathological cases are much improved from this, even, three orders of magnitude usually. &lt;code&gt;String&lt;/code&gt; &lt;code&gt;Array&lt;/code&gt;s are about two orders of magnitude faster on small-medium &lt;code&gt;Arrays&lt;/code&gt; and perform at the same scale with (theoretically) infinitely large ones. The old version ran out of stack space around 2000 or so.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MatzRuby is typically still far faster, but particularly the block forms are actually fairly close, in some cases actually within the same order of magnitude (albeit slower.) And the new version is pure Ruby all the way.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some benchmarking figures. Note the disparity between the &lt;code&gt;Array&lt;/code&gt; sizes.
&lt;code&gt;&lt;pre&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;For MatzRuby and new Rubinius:
    Numeric, 1000 elements, 100 loops
    146233 strings, each with 20 characters

For old Rubinius:
    Numeric, 100 elements, 100 loops
    1462 strings, each with 20 characters


#sort            MatzRuby     OLD*     NEW 
-----------------------------------------------
sorted           0.007812   2.581782   0.602038
sorted block     0.195312   4.064099   1.782695
reversed         0.007812   4.423980   8.090656
reversed block   0.195312   4.909585  26.117707
random           0.023438   0.920588   1.643777
random block     1.914062   0.967784   3.984373
same             0.007812   0.062574   0.462366
same block       1.906250   0.915978   4.052798
two              0.007812   0.099981   0.426605
two block        1.898438   0.902365   3.756180
three            0.000000   0.118842   0.500360
three block      1.898438   0.907539   4.471767
mixed            0.015625   0.635714   1.161138
mixed block      1.859375   0.809821   3.037062
strings          0.015625   5.512026   3.742163
strings block    0.304688  10.301844   7.038649
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next mini-project will be converting &lt;code&gt;Array&lt;/code&gt; to use a more efficient storage mechanism. That should be fun.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-02-13:891</id>
    <published>2008-02-13T03:25:00Z</published>
    <updated>2008-02-13T04:52:05Z</updated>
    <category term="rubinius"/>
    <category term="ffi"/>
    <category term="platform"/>
    <category term="rubinius"/>
    <category term="ruby"/>
    <link href="http://journal.kittensoft.org/2008/2/13/platform-abstraction-musings" rel="alternate" type="text/html"/>
    <title>Platform Abstraction Musings</title>
<content type="html">
            &lt;p&gt;The current platform abstraction in Rubinius is a bit hodgepodge--it works, but the responsibilities and hierarchies are not defined in any predictable manner. What I have been thinking about is a basic idea of a simple hierarchical model where each platform is resolved to a class that provides a complete implementation for it by inheriting and selectively overriding the specifications from its superclasses. &lt;/p&gt;

&lt;h1&gt;General idea&lt;/h1&gt;

&lt;p&gt;So, we take &lt;code&gt;POSIX&lt;/code&gt; to be one of the top-level implementations (others could be &lt;code&gt;WinNT&lt;/code&gt; etc.) &lt;code&gt;POSIX&lt;/code&gt; implements the default platform that could run any theoretical operating system that did not deviate from or extend the standard in any (meaningful for us) way. Then, &lt;code&gt;POSIX&lt;/code&gt; can be subclassed for example as &lt;code&gt;Linux&lt;/code&gt;, which allows us to override the parts of &lt;code&gt;POSIX&lt;/code&gt; where a Linux machine will differ or provide extra functionality. This can further be subclassed as &lt;code&gt;Debian &amp;lt; Linux&lt;/code&gt;, for example, if anything like that is needed. Furthermore, we can use Ruby modules to represent cross-cutting concerns. So while we could split &lt;code&gt;Linux&lt;/code&gt; into &lt;code&gt;Linux32&lt;/code&gt; and &lt;code&gt;Linux64&lt;/code&gt;, it may be simpler to just implement &lt;code&gt;Linux&lt;/code&gt; as a 32-bit and provide &lt;code&gt;Linux64&lt;/code&gt; (or even just a &lt;code&gt;Generic64&lt;/code&gt; for some things) as a module that can be inserted anywhere it is needed. Further, we can even divide to OS versions.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;# A 64-bit MonkeyLinux 1.8 could look like this&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;co&quot;&gt;POSIX&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          ^&lt;tt&gt;
&lt;/tt&gt;          |&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;co&quot;&gt;Linux&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          ^&lt;tt&gt;
&lt;/tt&gt;          |&lt;tt&gt;
&lt;/tt&gt;     &lt;span class=&quot;co&quot;&gt;MonkeyLinux&lt;/span&gt; &amp;lt;&amp;lt;&amp;lt; &lt;span class=&quot;co&quot;&gt;Linux64&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          ^&lt;tt&gt;
&lt;/tt&gt;          |&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;MonkeyLinux&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;V18&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The beauty of it is, of course, that it is not necessary to go that deep. If Linux Distro X does not need to specify any behaviour deviating from the base &lt;code&gt;Linux&lt;/code&gt; provided, then that is what is used.&lt;/p&gt;

&lt;h1&gt;Config vs. Runtime&lt;/h1&gt;

&lt;p&gt;This scheme needs to be split into two components: the build-time config such as struct and constant definitions and the runtime that &lt;em&gt;uses&lt;/em&gt; those definitions where needed, uses FFI to attach functions etc. Ideally we would implement both of these in the same class/module hierarchy thereby reducing any mismatch problems but parallel hierarchies work too if they turn out to be considerably easier to implement.&lt;/p&gt;

&lt;p&gt;Either way, the first step would be the build-time setup of creating platform.conf, types.conf and so on. This is already done with the tools we have (&lt;code&gt;StructGenerator&lt;/code&gt; et al.) but we can make it easier to manage by splitting it up into the above-described hierarchy. When the time comes to build, we just resolve the correct class to use (more about this further down) and ask it to generate the config information or provide the data to do so--not sure what will turn out to be easier here yet. It would also probably be a good idea to codify the exact platform class used here so that it does not need to be re-resolved when the runtime starts. The runtime side of course largely corresponds to what you can see in &lt;code&gt;kernel/platform&lt;/code&gt; now, with the exception that, for example, the &lt;code&gt;.attach_method&lt;/code&gt; call that ultimately gets run is possibly the result of overrides in the descent through the class hierarchy instead of a hardcoded guess.&lt;/p&gt;

&lt;h1&gt;Resolving the Correct Platform&lt;/h1&gt;

&lt;p&gt;The only obvious problem remaining is the actual method of determining which path should be taken in the platform implementation hierarchy. Broadly, two methods can be used: registration or resolution. The former keeps some type of a matching table that selects the correct class based on the key (platform info) given. The latter, which at this point seems favourable, would instead take the approach of testing the platform info against its children's filters/resolvers and passing it further down as necessary. In this scheme, let us say that 'amd64-freebsd6.2' is passed in. The top-level &lt;code&gt;Platform&lt;/code&gt; uses &lt;code&gt;POSIX.resolve&lt;/code&gt; to determine it is a POSIX platform (initially this 'check' is probably &lt;code&gt;platform !~ /winnt/i&lt;/code&gt; or something) and then &lt;code&gt;POSIX&lt;/code&gt; peddles it to its subclasses until possibly &lt;code&gt;BSD.resolve&lt;/code&gt; accepts it and so on until no subclass can further resolve it. Modules, of course, are taken into account in this whenever inserted.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://journal.kittensoft.org/">
    <author>
      <name>rue</name>
    </author>
    <id>tag:journal.kittensoft.org,2008-02-11:889</id>
    <published>2008-02-11T00:50:00Z</published>
    <updated>2008-02-12T01:19:56Z</updated>
    <category term="rubinius"/>
    <category term="mod_rubinius"/>
    <category term="personal"/>
    <category term="rubinius"/>
    <category term="web"/>
    <category term="work"/>
    <link href="http://journal.kittensoft.org/2008/2/11/all-rubinius-all-the-time" rel="alternate" type="text/html"/>
    <title>All Rubinius All the Time</title>
<content type="html">
            &lt;p&gt;The cat is &lt;a href=&quot;http://brainspl.at/articles/2008/02/12/what-do-you-want-to-see-in-mod_rubinius&quot;&gt;out of the bag&lt;/a&gt;, so I can finally publically express a huge &lt;em&gt;&quot;YAY&quot;&lt;/em&gt; for the opportunity to work full-time on Rubinius, courtesy of &lt;a href=&quot;http://www.engineyard.com&quot;&gt;Engine Yard&lt;/a&gt;. I will specifically be architecting and implementing the mod_rubinius approach to simplifying Ruby web application deployment while keeping it as (or more) performant (mainly Rails, obviously, but others will benefit equally.)&lt;/p&gt;

&lt;p&gt;I will still have plenty of time to do what I have been doing thus far with Rubinius, too. Might even have time to regularly publish the Newsletter again! After all, everything up to now has been on my spare time and I am just trading 10 hours of wasted time at my previous job and commute for 9-10 hours of mod_rubinius work--and I still have the same amount of free time to work on the project as I have had before! I think I need to come up with a way to get out of the house for a bit every day, though, to avoid cabin fever.&lt;/p&gt;

&lt;p&gt;The mod_rubinius work itself will of course necessarily involve a lot of Rubinius work, initially at least in the realm of multi-VM (Rubinius can run completely separate interpreters one per native thread), Rubinius' own C interface (as opposed to Subtend) and the basic I/O layer.&lt;/p&gt;

&lt;p&gt;You have a say in what happens with mod_rubinius, too! Hop over to &lt;a href=&quot;http://brainspl.at/articles/2008/02/12/what-do-you-want-to-see-in-mod_rubinius&quot;&gt;Ezra's post&lt;/a&gt; to tell us exactly how you deploy your Merb/Ramaze/Rails/Nitro/IOWA/plain CGI/whatever applications in your wildest dreams.&lt;/p&gt;

&lt;p&gt;Lastly, a &lt;em&gt;huge&lt;/em&gt; thanks to &lt;a href=&quot;http://www.engineyard.com&quot;&gt;Engine Yard&lt;/a&gt; for letting me invest my full energy in this! I cannot overstate how great everyone at EY has been throughout my transition,  and honestly I do not think I could hope to do better than to be able to make a living from what started as a hobby.&lt;/p&gt;
          </content>  </entry>
</feed>
