Kittensoft - rubiniustag:journal.kittensoft.org,2008:mephisto/rubiniusMephisto Drax2008-11-20T05:10:38Zruetag:journal.kittensoft.org,2008-11-20:9952008-11-20T04:41:00Z2008-11-20T05:10:38ZPhase Three
<p>Evan <a href="http://blog.fallingsnow.net/2008/11/18/a-sad-day/">broke the news earlier</a> about <a href="http://engineyard.com">Engine Yard</a> reducing funding for <a href="http://github.com/evanphx/rubinius">Rubinius</a> with the unfortunate effect that four of the original six, myself included, will no longer be employed there. My three truly excellent colleagues will have absolutely no problems finding employment, nor do I foresee any stalling for Rubinius—I will most certainly continue work at the usual pace after taking a couple days to arrange some things on my end.</p>
<p>And, really, the story is that <strong>Engine Yard continues to sponsor Rubinius development</strong>, even in the current climate. I cannot but be glad that they gave this level of support for any period of time, let alone a full year. It has been a superb opportunity.</p>
<p>I must also express my gratitude to the community for the frankly astounding wave of support in the last couple days. You all rock.</p>
<p>This leaves me looking for new challenges too, if you will. A few offers have come in, but if you have interesting work for me, please write me under “projects” in the base domain here. (Either the U.S. or Finland—or telecommuting anywhere, naturally.)</p>
ruetag:journal.kittensoft.org,2008-09-24:9692008-09-24T23:39:00Z2008-09-24T23:43:17ZGuy Decoux Dies
<p><a href="http://www.rubyfrance.org/articles/2008/09/25/disparition-de-guy-decoux">Jean-François Trân informed Ruby-Core that ‘ts’, Guy Decoux, has died.</a></p>
<p>Extremely sad :/</p>
ruetag:journal.kittensoft.org,2008-09-12:9672008-09-12T09:57:00Z2008-09-12T19:50:58ZDefensive Programming
<p>In the process of studying the current codebase, I ran into some functions whose existence I knew about: <code>as()</code> and <code>try_as()</code>. Both are essentially cast functions, explicit in the spirit of <code>static_cast()</code> but slightly tailored for our purposes (in the VM, each class contains its type as data explicitly, e.g. ArrayType and so on.) All Ruby classes are subclasses of <code>Object</code>, and the instances are passed around as <code>Object*</code>; the functions take the type to attempt to cast into and the object. <code>as()</code> will raise a <code>TypeError</code> if the cast is not possible, i.e. the real type of the object is not <code>kind_of?</code> the target type. <code>try_as()</code> is meant to be used in conditions and returns <code>NULL</code> for an invalid cast for those cases where the object's type is not always clear. Sounds good, right?</p>
<p>Well, one thing caught my attention. Both of the functions were treating the object <em>already</em> being <code>NULL</code> as a normal, ignorable case. I thought about it for a moment, and could not come up with any valid situation where one would have an <em>unknown</em> completely uninitialised object. In some cases a local object pointer might be <code>NULL</code> until it gets initialised (to <code>Qnil</code> or <code>Qundef</code> if nothing else), but in those cases you also know what the type is already. So this seemed like something that could mask problems.. I asked for opinions on #rubinius, since it is always possible I was just not understanding the valid use case, but no-one else could think of any either so I changed both functions to raise an <code>Assertion</code> if given a <code>NULL</code>.</p>
<p>Aside from fixing some shortcuts in the tests exposed by this, I did actually find a fairly nifty bug! <code>LookupTable</code>, which is used as an extra-lightweight hash, was raising <code>Assertions</code> left and right. Somehow <code>NULL</code>s were getting in the hash buckets. After some research, it turned out that the offender was this line in <code>LookupTable::remove</code> (pseudo for clarity):</p>
<pre><code>link = try_as<Tuple>(bucket.value_or_another_hash_bucket);
</code></pre>
<p>The intention is to check if the bucket has a link to another one and (later) recurse further into it if so. The problem is that if the element was <em>not</em> another bucket, i.e. of type <code>Tuple</code>, the link became <code>NULL</code> instead of the value object contained in this bucket. The rest of the code incorrectly assumed that link would always be the <code>Tuple</code> or the value so it was storing the <code>NULL</code>s. A quick fix to correctly handle the value, too, made sure we were not going to lose methods or instance variables and such.</p>
<p>Lesson in this? 1. I should really condense my writing; but also 2. <em>always</em> be as strict as possible. It helps to ensure you weed out stuff that you had not considered when writing the code, whether it turns out to be correct or incorrect behaviour.</p>
ruetag:journal.kittensoft.org,2008-09-11:9662008-09-11T11:44:00Z2008-09-11T12:03:59ZThe Return of the Son of the Thing from Planet Rubinius' Mother III
<p>I am currently working directly with Rubinius with the rest of the guys, getting the C++ rewrite flying: the milestone is set at being able to run mspec and the spec suite again. Specifically, I am reimplementing the C extension API from Shotgun called Subtend (though I hope we can just call it RNI..) and in the process I have had to familiarise myself with the new codebase, since I sadly did not have the time to do that earlier.</p>
<p>It is nice. Really nice. The OO aspect has made it a virtual pleasure to read. The logic is clearer and responsibilities are separated much better. There certainly is room for improvement, but then there always is. Granted, it _is_ still a VM implementation, but it is far more approachable than it was before. I will try to do my part to make sure there is enough documentation for the tricky and overarching parts: so far I have written a description of the method dispatch system (which is ultimately fairly simple, but being the central function of the VM it involves most of the codebase in one way or another) and just added class and method documentations in the headers in (doxygen)[http://doxygen.org] syntax so you might actually see the generated API docs online at some point too.</p>
ruetag:journal.kittensoft.org,2008-09-08:9652008-09-08T22:20:00Z2008-09-08T22:41:44Zucontext Broken on OS X 10.5 Leopard
<p>Apparently due to an issue between headers and the libc implementation on Leopard, <code>ucontext_t</code> are not allocated enough space which will cause bus errors or segmentation faults, typically when returning from the function to which the execution has <code>setcontext()</code> -ed to a context previously grabbed using <code>getcontext()</code> . This affects both x86 and PPC, and a bug has been filed although not addressed yet.</p>
<p>The workaround is to manually size the types correctly. So if you have, say, a struct like this:</p>
<pre><code>#include <ucontext.h>
struct thready {
:
ucontext_t some_context;
ucontext_t some_other_context;
:
};
</code></pre>
<p>The fixed version inserts the padding:</p>
<pre><code>#include <ucontext.h>
#define HAS_UCONTEXT // Or something
struct thready {
:
#if defined(__APPLE__) && defined(HAS_UCONTEXT)
ucontext_t some_context;
_STRUCT_MCONTEXT __some_context_mc;
ucontext_t some_other_context;
_STRUCT_MCONTEXT __some_other_context_mc;
#else
ucontext_t some_context;
ucontext_t some_other_context;
#endif
};
</code></pre>
<p>Naturally, you can also use the conditional separately for each <code>ucontext_t</code> if it is easier or more logical in your case and/or refine the conditional itself.</p>
<p>I had a terrible time trying to search for information, and most stuff I found seemed to indicate PPC issues only. In the interest of hopefully making the search shorter for someone else, I will gratuitously list the terms I was looking for: ucontext, ucontext_t, getcontext, setcontext, makecontext, swapcontext, segfault, sigbus, bus error, stack corruption, returning from, os x, 10.5, leopard, x86, ppc.</p>
<p>Hopefully they will get it fixed soon!</p>
ruetag:journal.kittensoft.org,2008-04-01:9122008-04-01T23:31:00Z2008-04-02T00:17:58ZConditional Compilation of Ruby Code
<p>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 ‘real,’ more generic sexp and <span class="caps">AST</span> manipulators towards something approaching Lisp’s facilities.</p>
I figured it would be a fairly short task and for a change I was correct&emdash;and a good portion of the thanks goes to Rubinius’ 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—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:
<table class="CodeRay"><tr>
<td title="click to toggle" class="line_numbers"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt></pre></td>
<td class="code"><pre><tt>
</tt> <span class="c"># ...</span><tt>
</tt><tt>
</tt> <span class="co">Rubinius</span>.compile_if(<span class="gv">$DEBUG</span>) { <span class="co">Logger</span>.debug <span class="s"><span class="dl">"</span><span class="k">Blah blah: </span><span class="il"><span class="dl">#{</span>some_variable<span class="dl">}</span></span><span class="dl">"</span></span> } <tt>
</tt><tt>
</tt> <span class="c"># ...</span><tt>
</tt></pre></td>
</tr></table>
If <code>$DEBUG</code> 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 <em>block contents</em> are processed normally&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.
<p>This should be useful for at least removing those generally-unnecessary debug statements etc.; the <code>if $DEBUG</code> 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 <em>is</em> general-purpose in that the only limiting factor is the condition variable (or possibly expression in the future.)</p>
<p>The commit is <a href="http://git.rubini.us/?p=code;a=commit;h=f58c67e33a99f751c3520ab65c96e28a91c45900">here</a>.</p>
ruetag:journal.kittensoft.org,2008-03-13:9062008-03-13T01:47:00Z2008-03-13T01:56:32ZSplitting the Specs to a Separate Project with git Submodules?
<p>If we have a separate RubySpec repository which is included to Rubinius
by means of git’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:</p>
<ol>
<li>Clone the main RubySpec to a local working copy.</li>
<li>Make changes.</li>
<li>Push changes to RubySpec mainline or make a patch if no commit bit.</li>
</ol>
<p>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 && git submodule update` to
pull in the specs—which is obviously needed to just <span class="caps">RUN</span> the specs.
Then, if a `git pull` contains submodule changes, another update is
usually required with `git submodule update`.</p>
<h2>Rubinius Committers</h2>
<p>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 <span class="caps">MUST</span> use a separate repository. That
works exactly as described above.</p>
<p>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:</p>
<ol>
<li>`cd spec/ruby`</li>
<li>`git checkout master`</li>
<li>Make and commit changes. (Use branches if you like but come back to master.)</li>
<li>Push changes to mainline RubySpecs (just `git push`.) <—<span class="caps">THIS IS IMPORTANT</span></li>
<li>`cd ../..`</li>
<li>`git add spec/ruby` <—<span class="caps">NO TRAILING</span> /, that overwrites the submodule</li>
<li>Commit.</li>
<li>Push to mainline Rubinius.</li>
</ol>
<p>At this point the updated submodule becomes available to others
working with the Rubinius repo using `git pull && git submodule update`.</p>
<h2>Full Example</h2>
Here is a long example of the entire process, covering some ground
that <span class="caps">TFM</span> did not seem to do. Please send in any corrections and/or
improvements.
<table class="CodeRay"><tr>
<td title="click to toggle" class="line_numbers"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt><strong>15</strong><tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt><strong>25</strong><tt>
</tt>26<tt>
</tt>27<tt>
</tt>28<tt>
</tt>29<tt>
</tt><strong>30</strong><tt>
</tt>31<tt>
</tt>32<tt>
</tt>33<tt>
</tt>34<tt>
</tt><strong>35</strong><tt>
</tt>36<tt>
</tt>37<tt>
</tt>38<tt>
</tt>39<tt>
</tt><strong>40</strong><tt>
</tt>41<tt>
</tt>42<tt>
</tt>43<tt>
</tt>44<tt>
</tt><strong>45</strong><tt>
</tt>46<tt>
</tt>47<tt>
</tt>48<tt>
</tt>49<tt>
</tt><strong>50</strong><tt>
</tt>51<tt>
</tt>52<tt>
</tt>53<tt>
</tt>54<tt>
</tt><strong>55</strong><tt>
</tt>56<tt>
</tt>57<tt>
</tt>58<tt>
</tt>59<tt>
</tt><strong>60</strong><tt>
</tt>61<tt>
</tt>62<tt>
</tt>63<tt>
</tt>64<tt>
</tt><strong>65</strong><tt>
</tt>66<tt>
</tt>67<tt>
</tt>68<tt>
</tt>69<tt>
</tt><strong>70</strong><tt>
</tt>71<tt>
</tt>72<tt>
</tt>73<tt>
</tt>74<tt>
</tt><strong>75</strong><tt>
</tt>76<tt>
</tt>77<tt>
</tt>78<tt>
</tt>79<tt>
</tt><strong>80</strong><tt>
</tt>81<tt>
</tt>82<tt>
</tt>83<tt>
</tt>84<tt>
</tt><strong>85</strong><tt>
</tt>86<tt>
</tt>87<tt>
</tt>88<tt>
</tt>89<tt>
</tt><strong>90</strong><tt>
</tt>91<tt>
</tt>92<tt>
</tt>93<tt>
</tt>94<tt>
</tt><strong>95</strong><tt>
</tt>96<tt>
</tt>97<tt>
</tt>98<tt>
</tt>99<tt>
</tt><strong>100</strong><tt>
</tt>101<tt>
</tt>102<tt>
</tt>103<tt>
</tt>104<tt>
</tt><strong>105</strong><tt>
</tt>106<tt>
</tt>107<tt>
</tt>108<tt>
</tt>109<tt>
</tt><strong>110</strong><tt>
</tt>111<tt>
</tt>112<tt>
</tt>113<tt>
</tt>114<tt>
</tt><strong>115</strong><tt>
</tt>116<tt>
</tt>117<tt>
</tt>118<tt>
</tt>119<tt>
</tt><strong>120</strong><tt>
</tt>121<tt>
</tt>122<tt>
</tt>123<tt>
</tt>124<tt>
</tt><strong>125</strong><tt>
</tt>126<tt>
</tt>127<tt>
</tt>128<tt>
</tt>129<tt>
</tt><strong>130</strong><tt>
</tt>131<tt>
</tt>132<tt>
</tt>133<tt>
</tt>134<tt>
</tt><strong>135</strong><tt>
</tt>136<tt>
</tt>137<tt>
</tt>138<tt>
</tt>139<tt>
</tt><strong>140</strong><tt>
</tt>141<tt>
</tt>142<tt>
</tt>143<tt>
</tt>144<tt>
</tt><strong>145</strong><tt>
</tt>146<tt>
</tt>147<tt>
</tt>148<tt>
</tt>149<tt>
</tt><strong>150</strong><tt>
</tt>151<tt>
</tt>152<tt>
</tt>153<tt>
</tt>154<tt>
</tt><strong>155</strong><tt>
</tt>156<tt>
</tt>157<tt>
</tt>158<tt>
</tt>159<tt>
</tt><strong>160</strong><tt>
</tt>161<tt>
</tt>162<tt>
</tt>163<tt>
</tt>164<tt>
</tt><strong>165</strong><tt>
</tt>166<tt>
</tt>167<tt>
</tt>168<tt>
</tt>169<tt>
</tt><strong>170</strong><tt>
</tt>171<tt>
</tt>172<tt>
</tt>173<tt>
</tt>174<tt>
</tt><strong>175</strong><tt>
</tt>176<tt>
</tt>177<tt>
</tt>178<tt>
</tt>179<tt>
</tt><strong>180</strong><tt>
</tt>181<tt>
</tt>182<tt>
</tt>183<tt>
</tt>184<tt>
</tt><strong>185</strong><tt>
</tt>186<tt>
</tt>187<tt>
</tt>188<tt>
</tt>189<tt>
</tt><strong>190</strong><tt>
</tt>191<tt>
</tt>192<tt>
</tt>193<tt>
</tt>194<tt>
</tt><strong>195</strong><tt>
</tt>196<tt>
</tt>197<tt>
</tt>198<tt>
</tt>199<tt>
</tt><strong>200</strong><tt>
</tt>201<tt>
</tt>202<tt>
</tt>203<tt>
</tt>204<tt>
</tt><strong>205</strong><tt>
</tt>206<tt>
</tt>207<tt>
</tt>208<tt>
</tt>209<tt>
</tt><strong>210</strong><tt>
</tt>211<tt>
</tt>212<tt>
</tt>213<tt>
</tt>214<tt>
</tt><strong>215</strong><tt>
</tt>216<tt>
</tt>217<tt>
</tt>218<tt>
</tt>219<tt>
</tt><strong>220</strong><tt>
</tt>221<tt>
</tt>222<tt>
</tt>223<tt>
</tt>224<tt>
</tt><strong>225</strong><tt>
</tt>226<tt>
</tt>227<tt>
</tt>228<tt>
</tt>229<tt>
</tt><strong>230</strong><tt>
</tt>231<tt>
</tt>232<tt>
</tt>233<tt>
</tt>234<tt>
</tt><strong>235</strong><tt>
</tt>236<tt>
</tt>237<tt>
</tt>238<tt>
</tt>239<tt>
</tt><strong>240</strong><tt>
</tt>241<tt>
</tt>242<tt>
</tt>243<tt>
</tt>244<tt>
</tt><strong>245</strong><tt>
</tt>246<tt>
</tt>247<tt>
</tt>248<tt>
</tt>249<tt>
</tt><strong>250</strong><tt>
</tt>251<tt>
</tt>252<tt>
</tt>253<tt>
</tt>254<tt>
</tt><strong>255</strong><tt>
</tt>256<tt>
</tt>257<tt>
</tt>258<tt>
</tt>259<tt>
</tt><strong>260</strong><tt>
</tt>261<tt>
</tt>262<tt>
</tt>263<tt>
</tt>264<tt>
</tt><strong>265</strong><tt>
</tt>266<tt>
</tt>267<tt>
</tt>268<tt>
</tt>269<tt>
</tt><strong>270</strong><tt>
</tt>271<tt>
</tt>272<tt>
</tt>273<tt>
</tt>274<tt>
</tt><strong>275</strong><tt>
</tt>276<tt>
</tt>277<tt>
</tt>278<tt>
</tt>279<tt>
</tt><strong>280</strong><tt>
</tt>281<tt>
</tt>282<tt>
</tt>283<tt>
</tt>284<tt>
</tt><strong>285</strong><tt>
</tt>286<tt>
</tt>287<tt>
</tt>288<tt>
</tt>289<tt>
</tt><strong>290</strong><tt>
</tt>291<tt>
</tt>292<tt>
</tt>293<tt>
</tt>294<tt>
</tt><strong>295</strong><tt>
</tt>296<tt>
</tt>297<tt>
</tt>298<tt>
</tt>299<tt>
</tt><strong>300</strong><tt>
</tt>301<tt>
</tt>302<tt>
</tt>303<tt>
</tt>304<tt>
</tt><strong>305</strong><tt>
</tt>306<tt>
</tt>307<tt>
</tt>308<tt>
</tt>309<tt>
</tt><strong>310</strong><tt>
</tt>311<tt>
</tt>312<tt>
</tt>313<tt>
</tt>314<tt>
</tt><strong>315</strong><tt>
</tt>316<tt>
</tt>317<tt>
</tt>318<tt>
</tt>319<tt>
</tt><strong>320</strong><tt>
</tt>321<tt>
</tt>322<tt>
</tt>323<tt>
</tt>324<tt>
</tt><strong>325</strong><tt>
</tt>326<tt>
</tt>327<tt>
</tt>328<tt>
</tt>329<tt>
</tt><strong>330</strong><tt>
</tt>331<tt>
</tt>332<tt>
</tt>333<tt>
</tt>334<tt>
</tt><strong>335</strong><tt>
</tt>336<tt>
</tt>337<tt>
</tt>338<tt>
</tt>339<tt>
</tt><strong>340</strong><tt>
</tt>341<tt>
</tt>342<tt>
</tt>343<tt>
</tt>344<tt>
</tt><strong>345</strong><tt>
</tt>346<tt>
</tt>347<tt>
</tt>348<tt>
</tt>349<tt>
</tt><strong>350</strong><tt>
</tt>351<tt>
</tt>352<tt>
</tt>353<tt>
</tt>354<tt>
</tt><strong>355</strong><tt>
</tt>356<tt>
</tt>357<tt>
</tt>358<tt>
</tt>359<tt>
</tt><strong>360</strong><tt>
</tt>361<tt>
</tt>362<tt>
</tt>363<tt>
</tt>364<tt>
</tt><strong>365</strong><tt>
</tt>366<tt>
</tt>367<tt>
</tt>368<tt>
</tt>369<tt>
</tt><strong>370</strong><tt>
</tt>371<tt>
</tt>372<tt>
</tt>373<tt>
</tt>374<tt>
</tt><strong>375</strong><tt>
</tt>376<tt>
</tt>377<tt>
</tt>378<tt>
</tt>379<tt>
</tt><strong>380</strong><tt>
</tt>381<tt>
</tt></pre></td>
<td class="code"><pre><tt>
</tt> # We will work from scratch to illustrate the process<tt>
</tt> $ cd ~/code/tmp<tt>
</tt><tt>
</tt> # OK, first set up our submodule<tt>
</tt> $ mkdir rubyspec<tt>
</tt> $ cd rubyspec<tt>
</tt> $ git init<tt>
</tt> Initialized empty Git repository in .git/<tt>
</tt> $ echo 'rubyspec' > README<tt>
</tt> $ git add README<tt>
</tt> $ git commit -a -m 'Initial import of rubyspec'<tt>
</tt> Created initial commit 4c43e66: Initial import of rubyspec<tt>
</tt> 1 files changed, 1 insertions(+), 0 deletions(-)<tt>
</tt> create mode 100644 README<tt>
</tt> $ cd ..<tt>
</tt><tt>
</tt> # OK, now set up the 'public' rubyspec repo (rubyspec.com or whatever)<tt>
</tt> $ git clone --bare rubyspec rubyspec.git<tt>
</tt> Initialized empty Git repository in /Users/user/code/tmp/rubyspec.git/<tt>
</tt><tt>
</tt> # Next, we create the superproject, obviously the public rbx repo<tt>
</tt> # already exists in reality.<tt>
</tt> $ mkdir rbx<tt>
</tt> $ cd rbx<tt>
</tt> $ git init<tt>
</tt> Initialized empty Git repository in .git/<tt>
</tt> $ echo 'rbx' > README<tt>
</tt> $ git add README<tt>
</tt> $ git commit -a -m 'RBX import'<tt>
</tt> Created initial commit 43b9035: RBX import<tt>
</tt> 1 files changed, 1 insertions(+), 0 deletions(-)<tt>
</tt> create mode 100644 README<tt>
</tt> $ cd ..<tt>
</tt><tt>
</tt> # OK, same deal here, make a 'public' repo (git://git.rubini.us in reality)<tt>
</tt> $ git clone --bare rbx rbx.git<tt>
</tt> Initialized empty Git repository in /Users/user/code/tmp/rbx.git/<tt>
</tt><tt>
</tt> # Now, let us get rid of the originals so we have a more realistic situation<tt>
</tt> $ rm -rf rbx rubyspec<tt>
</tt> $ ls<tt>
</tt> rbx.git rubyspec.git<tt>
</tt><tt>
</tt> # Next we want to set up the submodule link, and we need a real rbx repo<tt>
</tt> $ git clone rbx.git my_rbx<tt>
</tt> Initialized empty Git repository in /Users/user/code/tmp/my_rbx/.git/<tt>
</tt> $ cd my_rbx<tt>
</tt> $ ls<tt>
</tt> README<tt>
</tt> # Now we associate the submodule (in reality we would use the URI, not local path)<tt>
</tt> $ mkdir spec<tt>
</tt> # We can 'mount' the submodule anywhere in the repo, in this case it goes in spec/ruby/<tt>
</tt> $ git submodule add ~/code/tmp/rubyspec.git spec/ruby<tt>
</tt> Initialized empty Git repository in /Users/user/code/tmp/my_rbx/spec/ruby/.git/<tt>
</tt> $ ls -la<tt>
</tt> total 16<tt>
</tt> drwxr-xr-x 4 user group 204 Mar 12 19:39 .<tt>
</tt> drwxr-xr-x 7 user group 238 Mar 12 19:37 ..<tt>
</tt> drwxr-xr-x 7 user group 374 Mar 12 19:39 .git<tt>
</tt> -rw-r--r-- 1 user group 85 Mar 12 19:39 .gitmodules<tt>
</tt> -rw-r--r-- 1 user group 4 Mar 12 19:37 README<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:39 spec<tt>
</tt><tt>
</tt> # .gitmodules has the tracking info<tt>
</tt> $ cat .gitmodules<tt>
</tt> [submodule "spec/ruby"]<tt>
</tt> path = spec/ruby<tt>
</tt> url = /Users/user/code/tmp/rubyspec.git<tt>
</tt> # Our rubyspec repo should be in place now<tt>
</tt> $ ls -la spec/ruby<tt>
</tt> total 8<tt>
</tt> drwxr-xr-x 3 user group 136 Mar 12 19:39 .<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:39 ..<tt>
</tt> drwxr-xr-x 7 user group 374 Mar 12 19:39 .git<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:39 README<tt>
</tt> $ cat spec/ruby/README<tt>
</tt> rubyspec<tt>
</tt><tt>
</tt> # Now we need to record the submodule in the superproject<tt>
</tt> $ git status<tt>
</tt> On branch master<tt>
</tt> Changes to be committed:<tt>
</tt> (use "git reset HEAD <file>..." to unstage)<tt>
</tt><tt>
</tt> new file: .gitmodules<tt>
</tt> new file: spec/ruby<tt>
</tt><tt>
</tt> $ git commit -m 'Imported rubyspec submodule'<tt>
</tt> Created commit 0ae5cd3: Imported rubyspec submodule<tt>
</tt> 2 files changed, 4 insertions(+), 0 deletions(-)<tt>
</tt> create mode 100644 .gitmodules<tt>
</tt> create mode 160000 spec/ruby<tt>
</tt><tt>
</tt> # And then record this over at the mainline<tt>
</tt> $ git push<tt>
</tt> Counting objects: 5, done.<tt>
</tt> Compressing objects: 100% (3/3), done.<tt>
</tt> Writing objects: 100% (4/4), 439 bytes, done.<tt>
</tt> Total 4 (delta 0), reused 0 (delta 0)<tt>
</tt> Unpacking objects: 100% (4/4), done.<tt>
</tt> To /Users/user/code/tmp/rbx.git<tt>
</tt> 43b9035..0ae5cd3 master -> master<tt>
</tt> $ cd ..<tt>
</tt><tt>
</tt> # Alright. Now, our test situation is that Joe just hacks on rubyspec and<tt>
</tt> # Bob hacks on rubyspec as a part of rbx!<tt>
</tt><tt>
</tt> # Let us create Bob's repo quick first:<tt>
</tt> $ git clone rbx.git bobs_rbx<tt>
</tt> $ cd bobs_rbx<tt>
</tt> $ ls -la<tt>
</tt> total 8<tt>
</tt> drwxr-xr-x 4 user group 204 Mar 12 19:47 .<tt>
</tt> drwxr-xr-x 9 user group 306 Mar 12 19:44 ..<tt>
</tt> drwxr-xr-x 7 user group 374 Mar 12 19:44 .git<tt>
</tt> -rw-r--r-- 1 user group 85 Mar 12 19:44 .gitmodules<tt>
</tt> -rw-r--r-- 1 user group 0 Mar 12 19:45 README<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:44 spec<tt>
</tt><tt>
</tt> # Now, as you can see, a pristine checkout of a superproject will not actually contain the submodule code<tt>
</tt> $ ls -la spec/ruby<tt>
</tt> total 0<tt>
</tt> drwxr-xr-x 2 user group 68 Mar 12 19:44 .<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:44 ..<tt>
</tt><tt>
</tt> # We need to first init to properly link the modules and then update to pull the data in<tt>
</tt> $ git submodule init<tt>
</tt> Submodule 'spec/ruby' (/Users/user/code/tmp/rubyspec.git) registered for path 'spec/ruby'<tt>
</tt> $ git submodule update<tt>
</tt> Initialized empty Git repository in /Users/user/code/tmp/bobs_rbx/spec/ruby/.git/<tt>
</tt> Submodule path 'spec/ruby': checked out '4c43e665381054478aa7c82da1d1d63b5c258e4b'<tt>
</tt> $ ls -la spec/ruby<tt>
</tt> total 8<tt>
</tt> drwxr-xr-x 3 user group 136 Mar 12 19:48 .<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:48 ..<tt>
</tt> drwxr-xr-x 7 user group 408 Mar 12 19:48 .git<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:48 README<tt>
</tt> # OK, now it is there. Let us hop out of here for a bit.<tt>
</tt> $ cd ..<tt>
</tt><tt>
</tt> # Now, Joe is doing some work on his repo which is JUST the rubyspec submodule<tt>
</tt> $ git clone rubyspec.git joes_spec<tt>
</tt> Initialized empty Git repository in /Users/user/code/tmp/joes_spec/.git/<tt>
</tt> $ cd joes_spec<tt>
</tt> $ ls<tt>
</tt> README<tt>
</tt> # OK, Joe makes a change<tt>
</tt> $ echo 'new spec' > spec.rb<tt>
</tt> $ git add spec.rb<tt>
</tt> $ git commit -m 'Added spec.rb'<tt>
</tt> Created commit f380258: Added spec.rb<tt>
</tt> 1 files changed, 1 insertions(+), 0 deletions(-)<tt>
</tt> create mode 100644 spec.rb<tt>
</tt> # Joe pushes to mainline of rubyspec<tt>
</tt> $ git push<tt>
</tt> Counting objects: 4, done.<tt>
</tt> Compressing objects: 100% (2/2), done.<tt>
</tt> Writing objects: 100% (3/3), 290 bytes, done.<tt>
</tt> Total 3 (delta 0), reused 0 (delta 0)<tt>
</tt> Unpacking objects: 100% (3/3), done.<tt>
</tt> To /Users/user/code/tmp/rubyspec.git<tt>
</tt> 4c43e66..f380258 master -> master<tt>
</tt><tt>
</tt> # Now, let us check in with Bob who has his clone of the rbx repo<tt>
</tt> $ cd bobs_rbx<tt>
</tt><tt>
</tt> # Bob does not have Joe's spec yet<tt>
</tt> $ ls -la spec/ruby/<tt>
</tt> total 8<tt>
</tt> drwxr-xr-x 3 user group 136 Mar 12 19:48 .<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:48 ..<tt>
</tt> drwxr-xr-x 7 user group 408 Mar 12 19:48 .git<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:48 README<tt>
</tt><tt>
</tt> # Updating does not seem to work either!<tt>
</tt> $ git submodule update<tt>
</tt> $ ls -la spec/ruby/<tt>
</tt> total 8<tt>
</tt> drwxr-xr-x 3 user group 136 Mar 12 19:48 .<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:48 ..<tt>
</tt> drwxr-xr-x 7 user group 408 Mar 12 19:48 .git<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:48 README<tt>
</tt><tt>
</tt> # Did Joe's change get registered? Let us check..<tt>
</tt> $ cd ..<tt>
</tt> $ git clone rubyspec.git check_joes_change<tt>
</tt> Initialized empty Git repository in /Users/user/code/tmp/check_joes_change/.git/<tt>
</tt> $ ls check_joes_change/<tt>
</tt> README spec.rb<tt>
</tt> # Yep, it is there! So what is going on?<tt>
</tt><tt>
</tt> # Right, we need to update the mainline rbx. Technically Bob could actually do this<tt>
</tt> # too but for now, let us pretend that some access control allows only me to make<tt>
</tt> # that update. So back to my repo.<tt>
</tt> $ cd my_rbx/<tt>
</tt> $<tt>
</tt> # Now, we need to grab the change first<tt>
</tt> $ cd spec/ruby/<tt>
</tt> $ ls<tt>
</tt> README<tt>
</tt> $ git status<tt>
</tt> On branch master<tt>
</tt> nothing to commit (working directory clean)<tt>
</tt> $ git pull<tt>
</tt> remote: Counting objects: 4, done.<tt>
</tt> remote: Compressing objects: 100% (2/2)remote: , done.<tt>
</tt> remote: Total 3 (delta 0), reused 0 (delta 0)<tt>
</tt> Unpacking objects: 100% (3/3), done.<tt>
</tt> From /Users/user/code/tmp/rubyspec<tt>
</tt> 4c43e66..f380258 master -> origin/master<tt>
</tt> Updating 4c43e66..f380258<tt>
</tt> Fast forward<tt>
</tt> spec.rb | 1 +<tt>
</tt> 1 files changed, 1 insertions(+), 0 deletions(-)<tt>
</tt> create mode 100644 spec.rb<tt>
</tt> $ ls -la<tt>
</tt> total 16<tt>
</tt> drwxr-xr-x 3 user group 170 Mar 12 19:54 .<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:39 ..<tt>
</tt> drwxr-xr-x 7 user group 442 Mar 12 19:54 .git<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:39 README<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:54 spec.rb<tt>
</tt> # OK, there it is!<tt>
</tt> $ cd ../../<tt>
</tt> # So, need to record this update in the superproject<tt>
</tt> $ git status<tt>
</tt> On branch master<tt>
</tt> Changed but not updated:<tt>
</tt> (use "git add <file>..." to update what will be committed)<tt>
</tt><tt>
</tt> modified: spec/ruby<tt>
</tt><tt>
</tt> no changes added to commit (use "git add" and/or "git commit -a")<tt>
</tt> $ git add spec/ruby<tt>
</tt> $ git commit -m 'Updated our rubyspec checkout to newest version'<tt>
</tt> Created commit 0d96517: Updated our rubyspec checkout to newest version<tt>
</tt> 1 files changed, 1 insertions(+), 1 deletions(-)<tt>
</tt> # And then push this change to mainline<tt>
</tt> $ git push<tt>
</tt> Counting objects: 5, done.<tt>
</tt> Compressing objects: 100% (2/2), done.<tt>
</tt> Writing objects: 100% (3/3), 319 bytes, done.<tt>
</tt> Total 3 (delta 1), reused 0 (delta 0)<tt>
</tt> Unpacking objects: 100% (3/3), done.<tt>
</tt> To /Users/user/code/tmp/rbx.git<tt>
</tt> 0ae5cd3..0d96517 master -> master<tt>
</tt> $ cd ..<tt>
</tt> $ cd bobs_rbx/<tt>
</tt> # NOW Bob should be able to access it<tt>
</tt> $ git submodule update<tt>
</tt> # No? How about this:<tt>
</tt> $ git pull<tt>
</tt> remote: Counting objects: 5, done.<tt>
</tt> remote: Compressing objects: 100% (2/2), done.<tt>
</tt> remote: Total 3 (delta 1), reused 0 (delta 0)<tt>
</tt> Unpacking objects: 100% (3/3), done.<tt>
</tt> From /Users/user/code/tmp/rbx<tt>
</tt> 0ae5cd3..0d96517 master -> origin/master<tt>
</tt> Updating 0ae5cd3..0d96517<tt>
</tt> README: needs update<tt>
</tt> Fast forward<tt>
</tt> spec/ruby | 2 +-<tt>
</tt> 1 files changed, 1 insertions(+), 1 deletions(-)<tt>
</tt> # That by itself does not update yet<tt>
</tt> $ ls -la spec/ruby<tt>
</tt> total 8<tt>
</tt> drwxr-xr-x 3 user group 136 Mar 12 19:48 .<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:48 ..<tt>
</tt> drwxr-xr-x 7 user group 408 Mar 12 19:48 .git<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:48 README<tt>
</tt> # Now we must update<tt>
</tt> $ git submodule update<tt>
</tt> Submodule path 'spec/ruby': checked out 'f38025812763dd8ee44beebcc0c8a3997c9aac0f'<tt>
</tt> # And now it is there<tt>
</tt> $ ls -la spec/ruby<tt>
</tt> total 16<tt>
</tt> drwxr-xr-x 3 user group 170 Mar 12 19:57 .<tt>
</tt> drwxr-xr-x 3 user group 102 Mar 12 19:48 ..<tt>
</tt> drwxr-xr-x 7 user group 408 Mar 12 19:57 .git<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:48 README<tt>
</tt> -rw-r--r-- 1 user group 9 Mar 12 19:57 spec.rb<tt>
</tt> # And there we go, properly updated now<tt>
</tt><tt>
</tt> # Of course, Bob can make a few changes now too. Here is the only potential problem.<tt>
</tt> # First, change something in rbx.<tt>
</tt> $ echo 'RTFM' > INSTALL<tt>
</tt> $ git add INSTALL<tt>
</tt> $ git commit -m 'Installation instructions'<tt>
</tt> Created commit c0e6667: Installation instructions<tt>
</tt> 1 files changed, 1 insertions(+), 0 deletions(-)<tt>
</tt> create mode 100644 INSTALL<tt>
</tt> $ git push<tt>
</tt> Counting objects: 4, done.<tt>
</tt> Compressing objects: 100% (2/2), done.<tt>
</tt> Writing objects: 100% (3/3), 361 bytes, done.<tt>
</tt> Total 3 (delta 0), reused 0 (delta 0)<tt>
</tt> Unpacking objects: 100% (3/3), done.<tt>
</tt> To /Users/user/code/tmp/rbx.git<tt>
</tt> 0d96517..c0e6667 master -> master<tt>
</tt> # That was normal. Now, what if Bob wants to make changes to rubyspec?<tt>
</tt> # He can make the changes normally. If he has commit access, he can<tt>
</tt> # just hop over and do so.<tt>
</tt> $ cd spec/ruby<tt>
</tt> $ ls<tt>
</tt> README spec.rb<tt>
</tt> # One notable thing is that this is a detached by default to avoid some problems, so<tt>
</tt> # Bob must go to a real branch.<tt>
</tt> $ git status<tt>
</tt> Not currently on any branch.<tt>
</tt> nothing to commit (working directory clean)<tt>
</tt> $ git checkout master<tt>
</tt> Previous HEAD position was b292add... Added a spec<tt>
</tt> Switched to branch "master"<tt>
</tt> $ echo 'my spec' > spec2.rb<tt>
</tt> $ git add spec2.rb<tt>
</tt> $ git commit -m 'Added a spec'<tt>
</tt> Created commit b1e7bdb: Added a spec<tt>
</tt> 1 files changed, 1 insertions(+), 0 deletions(-)<tt>
</tt> create mode 100644 spec2.rb<tt>
</tt> # Now Bob can just push it if he has access<tt>
</tt> $ git push<tt>
</tt> Counting objects: 4, done.<tt>
</tt> Compressing objects: 100% (2/2), done.<tt>
</tt> Writing objects: 100% (3/3), 313 bytes, done.<tt>
</tt> Total 3 (delta 0), reused 0 (delta 0)<tt>
</tt> Unpacking objects: 100% (3/3), done.<tt>
</tt> To /Users/user/code/tmp/rubyspec.git<tt>
</tt> f380258..b1e7bdb master -> master<tt>
</tt> # As the data shows, we directly updated the rubyspec project<tt>
</tt> $<tt>
</tt> # Obviously, if Bob did not have commit rights, he would do the normal git-format-patch dance instead<tt>
</tt> $<tt>
</tt> # Now, the problem<tt>
</tt> $ cd ../..<tt>
</tt> $ git status<tt>
</tt> On branch master<tt>
</tt> Changed but not updated:<tt>
</tt> (use "git add <file>..." to update what will be committed)<tt>
</tt><tt>
</tt> modified: spec/ruby<tt>
</tt><tt>
</tt> no changes added to commit (use "git add" and/or "git commit -a")<tt>
</tt> # This shows the change we made--and adding it is perfectly safe so long<tt>
</tt> # as we do it correctly. This is incorrect:<tt>
</tt> $ git add spec/ruby/<tt>
</tt> $ git status<tt>
</tt> On branch master<tt>
</tt> Changes to be committed:<tt>
</tt> (use "git reset HEAD <file>..." to unstage)<tt>
</tt><tt>
</tt> deleted: spec/ruby<tt>
</tt> new file: spec/ruby/README<tt>
</tt> new file: spec/ruby/spec.rb<tt>
</tt> new file: spec/ruby/spec2.rb<tt>
</tt><tt>
</tt> $ git reset --hard HEAD<tt>
</tt> HEAD is now at c0e6667... Installation instructions<tt>
</tt> # OK, so that is not good. The trailing / has git thinking this is a new<tt>
</tt> # path which overwrites the submodule. So, without:<tt>
</tt> $ git add spec/ruby<tt>
</tt> $ git status<tt>
</tt> On branch master<tt>
</tt> Changes to be committed:<tt>
</tt> (use "git reset HEAD <file>..." to unstage)<tt>
</tt><tt>
</tt> modified: spec/ruby<tt>
</tt><tt>
</tt> # So that worked fine. Now we can update mainline normally<tt>
</tt> $ git commit -m 'New spec in rubyspec, updated here and pushed to rubyspec mainline'<tt>
</tt> Created commit 3749f4b: New spec in rubyspec, updated here and pushed to rubyspec mainline<tt>
</tt> 1 files changed, 1 insertions(+), 1 deletions(-)<tt>
</tt> $ git push<tt>
</tt> Counting objects: 5, done.<tt>
</tt> Compressing objects: 100% (2/2), done.<tt>
</tt> Writing objects: 100% (3/3), 331 bytes, done.<tt>
</tt> Total 3 (delta 1), reused 0 (delta 0)<tt>
</tt> Unpacking objects: 100% (3/3), done.<tt>
</tt> To /Users/user/code/tmp/rbx.git<tt>
</tt> c0e6667..3749f4b master -> master<tt>
</tt> $<tt>
</tt></pre></td>
</tr></table>
ruetag:journal.kittensoft.org,2008-02-15:8932008-02-15T04:49:00Z2008-02-15T06:30:47ZReinventing the Which Wheel Comes First
<p>Aside from research, the past few days I have been putzing with reimplementing Rubinius' <code>Array#sort</code> and <code>Array#sort!</code> because, well, they sucked. The implementation is an iterative three-way partitioning <a href="http://en.wikipedia.org/wiki/Quicksort">Quicksort</a> that drops down to <a href="http://en.wikipedia.org/wiki/Insertion_sort">Insertion Sort</a> for small <code>Array</code>s or subpartitions. Two observations:</p>
<ul>
<li><p>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. <code>String</code> <code>Array</code>s are about two orders of magnitude faster on small-medium <code>Arrays</code> and perform at the same scale with (theoretically) infinitely large ones. The old version ran out of stack space around 2000 or so.</p></li>
<li><p>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.</p></li>
</ul>
<p>Here are some benchmarking figures. Note the disparity between the <code>Array</code> sizes.
<code><pre></p>
<pre><code>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
</code></pre>
<p></pre></code></p>
<p>Next mini-project will be converting <code>Array</code> to use a more efficient storage mechanism. That should be fun.</p>
ruetag:journal.kittensoft.org,2008-02-13:8912008-02-13T03:25:00Z2008-09-08T22:19:44ZPlatform Abstraction Musings
<p>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. </p>
<h1>General idea</h1>
<p>So, we take <code>POSIX</code> to be one of the top-level implementations (others could be <code>WinNT</code> etc.) <code>POSIX</code> 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, <code>POSIX</code> can be subclassed for example as <code>Linux</code>, which allows us to override the parts of <code>POSIX</code> where a Linux machine will differ or provide extra functionality. This can further be subclassed as <code>Debian < Linux</code>, for example, if anything like that is needed. Furthermore, we can use Ruby modules to represent cross-cutting concerns. So while we could split <code>Linux</code> into <code>Linux32</code> and <code>Linux64</code>, it may be simpler to just implement <code>Linux</code> as a 32-bit and provide <code>Linux64</code> (or even just a <code>Generic64</code> for some things) as a module that can be inserted anywhere it is needed. Further, we can even divide to OS versions.</p>
<table class="CodeRay"><tr>
<td title="click to toggle" class="line_numbers"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt></pre></td>
<td class="code"><pre><tt>
</tt> <span class="c"># A 64-bit MonkeyLinux 1.8 could look like this</span><tt>
</tt> <span class="co">POSIX</span><tt>
</tt> ^<tt>
</tt> |<tt>
</tt> <span class="co">Linux</span><tt>
</tt> ^<tt>
</tt> |<tt>
</tt> <span class="co">MonkeyLinux</span> <<< <span class="co">Linux64</span><tt>
</tt> ^<tt>
</tt> |<tt>
</tt> <span class="co">MonkeyLinux</span>::<span class="co">V18</span><tt>
</tt></pre></td>
</tr></table>
<p>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 <code>Linux</code> provided, then that is what is used.</p>
<h1>Config vs. Runtime</h1>
<p>This scheme needs to be split into two components: the build-time config such as struct and constant definitions and the runtime that <em>uses</em> 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.</p>
<p>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 (<code>StructGenerator</code> 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 <code>kernel/platform</code> now, with the exception that, for example, the <code>.attach_method</code> call that ultimately gets run is possibly the result of overrides in the descent through the class hierarchy instead of a hardcoded guess.</p>
<h1>Resolving the Correct Platform</h1>
<p>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 <code>Platform</code> uses <code>POSIX.resolve</code> to determine it is a POSIX platform (initially this 'check' is probably <code>platform !~ /winnt/i</code> or something) and then <code>POSIX</code> peddles it to its subclasses until possibly <code>BSD.resolve</code> accepts it and so on until no subclass can further resolve it. Modules, of course, are taken into account in this whenever inserted.</p>
ruetag:journal.kittensoft.org,2008-02-11:8892008-02-11T00:50:00Z2008-02-12T01:19:56ZAll Rubinius All the Time
<p>The cat is <a href="http://brainspl.at/articles/2008/02/12/what-do-you-want-to-see-in-mod_rubinius">out of the bag</a>, so I can finally publically express a huge <em>"YAY"</em> for the opportunity to work full-time on Rubinius, courtesy of <a href="http://www.engineyard.com">Engine Yard</a>. 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.)</p>
<p>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.</p>
<p>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.</p>
<p>You have a say in what happens with mod_rubinius, too! Hop over to <a href="http://brainspl.at/articles/2008/02/12/what-do-you-want-to-see-in-mod_rubinius">Ezra's post</a> to tell us exactly how you deploy your Merb/Ramaze/Rails/Nitro/IOWA/plain CGI/whatever applications in your wildest dreams.</p>
<p>Lastly, a <em>huge</em> thanks to <a href="http://www.engineyard.com">Engine Yard</a> 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.</p>
ruetag:journal.kittensoft.org,2007-11-09:7032007-11-09T19:49:00Z2008-02-08T04:08:38ZCompiler Walkthrough Illustration
Note: this is a sort of a draft. See the real document over in <a href="http://git.rubini.us/?p=code;a=blob_plain;f=doc/compiler_intro.txt;hb=HEAD">the repo</a>.
<table class="CodeRay"><tr>
<td title="click to toggle" class="line_numbers"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt><strong>15</strong><tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt><strong>25</strong><tt>
</tt>26<tt>
</tt>27<tt>
</tt>28<tt>
</tt>29<tt>
</tt><strong>30</strong><tt>
</tt>31<tt>
</tt>32<tt>
</tt>33<tt>
</tt>34<tt>
</tt><strong>35</strong><tt>
</tt>36<tt>
</tt>37<tt>
</tt>38<tt>
</tt>39<tt>
</tt><strong>40</strong><tt>
</tt>41<tt>
</tt>42<tt>
</tt>43<tt>
</tt>44<tt>
</tt><strong>45</strong><tt>
</tt>46<tt>
</tt>47<tt>
</tt>48<tt>
</tt>49<tt>
</tt><strong>50</strong><tt>
</tt>51<tt>
</tt>52<tt>
</tt>53<tt>
</tt>54<tt>
</tt><strong>55</strong><tt>
</tt>56<tt>
</tt>57<tt>
</tt>58<tt>
</tt>59<tt>
</tt><strong>60</strong><tt>
</tt>61<tt>
</tt>62<tt>
</tt>63<tt>
</tt>64<tt>
</tt><strong>65</strong><tt>
</tt>66<tt>
</tt>67<tt>
</tt>68<tt>
</tt>69<tt>
</tt><strong>70</strong><tt>
</tt>71<tt>
</tt>72<tt>
</tt>73<tt>
</tt>74<tt>
</tt><strong>75</strong><tt>
</tt>76<tt>
</tt>77<tt>
</tt>78<tt>
</tt>79<tt>
</tt><strong>80</strong><tt>
</tt>81<tt>
</tt>82<tt>
</tt>83<tt>
</tt>84<tt>
</tt><strong>85</strong><tt>
</tt>86<tt>
</tt>87<tt>
</tt>88<tt>
</tt>89<tt>
</tt><strong>90</strong><tt>
</tt>91<tt>
</tt>92<tt>
</tt>93<tt>
</tt>94<tt>
</tt><strong>95</strong><tt>
</tt>96<tt>
</tt>97<tt>
</tt>98<tt>
</tt>99<tt>
</tt><strong>100</strong><tt>
</tt>101<tt>
</tt>102<tt>
</tt>103<tt>
</tt>104<tt>
</tt><strong>105</strong><tt>
</tt>106<tt>
</tt>107<tt>
</tt>108<tt>
</tt>109<tt>
</tt><strong>110</strong><tt>
</tt>111<tt>
</tt>112<tt>
</tt>113<tt>
</tt>114<tt>
</tt><strong>115</strong><tt>
</tt>116<tt>
</tt>117<tt>
</tt>118<tt>
</tt>119<tt>
</tt><strong>120</strong><tt>
</tt>121<tt>
</tt>122<tt>
</tt>123<tt>
</tt>124<tt>
</tt><strong>125</strong><tt>
</tt>126<tt>
</tt>127<tt>
</tt>128<tt>
</tt>129<tt>
</tt><strong>130</strong><tt>
</tt>131<tt>
</tt>132<tt>
</tt>133<tt>
</tt>134<tt>
</tt><strong>135</strong><tt>
</tt>136<tt>
</tt>137<tt>
</tt>138<tt>
</tt>139<tt>
</tt><strong>140</strong><tt>
</tt>141<tt>
</tt>142<tt>
</tt>143<tt>
</tt>144<tt>
</tt><strong>145</strong><tt>
</tt>146<tt>
</tt>147<tt>
</tt>148<tt>
</tt>149<tt>
</tt><strong>150</strong><tt>
</tt>151<tt>
</tt>152<tt>
</tt>153<tt>
</tt>154<tt>
</tt><strong>155</strong><tt>
</tt>156<tt>
</tt>157<tt>
</tt>158<tt>
</tt>159<tt>
</tt><strong>160</strong><tt>
</tt>161<tt>
</tt>162<tt>
</tt>163<tt>
</tt>164<tt>
</tt><strong>165</strong><tt>
</tt>166<tt>
</tt>167<tt>
</tt>168<tt>
</tt>169<tt>
</tt><strong>170</strong><tt>
</tt>171<tt>
</tt>172<tt>
</tt>173<tt>
</tt>174<tt>
</tt><strong>175</strong><tt>
</tt>176<tt>
</tt>177<tt>
</tt>178<tt>
</tt>179<tt>
</tt><strong>180</strong><tt>
</tt>181<tt>
</tt>182<tt>
</tt>183<tt>
</tt>184<tt>
</tt><strong>185</strong><tt>
</tt>186<tt>
</tt>187<tt>
</tt></pre></td>
<td class="code"><pre><tt>
</tt><span class="c"># Start</span><tt>
</tt>[<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:defn</span>, <span class="sy">:foo</span>, <tt>
</tt> [<span class="sy">:scope</span>, <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ], <tt>
</tt> [<span class="sy">:a</span>, <span class="sy">:b</span>]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt>]<tt>
</tt><tt>
</tt><span class="c"># into_script</span><tt>
</tt>[<span class="sy">:script</span>, <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:defn</span>, <span class="sy">:foo</span>, <tt>
</tt> [<span class="sy">:scope</span>, <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ], <tt>
</tt> [<span class="sy">:a</span>, <span class="sy">:b</span>]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt>]<tt>
</tt><tt>
</tt><span class="c"># Script.create strips :script</span><tt>
</tt>[<tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:defn</span>, <span class="sy">:foo</span>, <tt>
</tt> [<span class="sy">:scope</span>, <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ], <tt>
</tt> [<span class="sy">:a</span>, <span class="sy">:b</span>]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt>]<tt>
</tt><span class="c"># out = [<script node>]</span><tt>
</tt><tt>
</tt><tt>
</tt><span class="c"># Script.consume</span><tt>
</tt><span class="c"># convert sexp.first -></span><tt>
</tt><span class="c"># Block.create comp, sexp</span><tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:defn</span>, <span class="sy">:foo</span>, <tt>
</tt> [<span class="sy">:scope</span>, <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ], <tt>
</tt> [<span class="sy">:a</span>, <span class="sy">:b</span>]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt><span class="c"># out = [<block node>]</span><tt>
</tt><tt>
</tt><span class="c"># Block#consume sexp.shift</span><tt>
</tt> [ <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:defn</span>, <span class="sy">:foo</span>, <tt>
</tt> [<span class="sy">:scope</span>, <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ], <tt>
</tt> [<span class="sy">:a</span>, <span class="sy">:b</span>]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt><span class="c"># out = [<newline node>]</span><tt>
</tt><tt>
</tt><span class="c"># Compiler#convert_sexp first</span><tt>
</tt><span class="c"># -> Newline.create</span><tt>
</tt><span class="c"># Newline.new.consume sexp.shift</span><tt>
</tt> [<span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:defn</span>, <span class="sy">:foo</span>, <tt>
</tt> [<span class="sy">:scope</span>, <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ], <tt>
</tt> [<span class="sy">:a</span>, <span class="sy">:b</span>]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt><tt>
</tt><span class="c"># << out = [1, "eval", <defn node>]</span><tt>
</tt><span class="c"># compiler.convert <defn node></span><tt>
</tt><tt>
</tt><span class="c"># Define.create</span><tt>
</tt><span class="c"># Define.new.consume sexp.shift</span><tt>
</tt><span class="c"># name = sexp[0] (:foo), body = sexp[1..-1]</span><tt>
</tt><span class="c"># scope = super(body)</span><tt>
</tt><span class="c"># ClosedScope#consume body</span><tt>
</tt> [<tt>
</tt> [<span class="sy">:scope</span>, <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ], <tt>
</tt> [<span class="sy">:a</span>, <span class="sy">:b</span>]<tt>
</tt> ]<tt>
</tt> ]<tt>
</tt><span class="c"># out = []</span><tt>
</tt><tt>
</tt><span class="c"># Scope.new.consume sexp.shift</span><tt>
</tt><span class="c"># convert args.first, </span><tt>
</tt><span class="c"># out = [<converted>, locals]</span><tt>
</tt> [ <tt>
</tt> [<span class="sy">:block</span>, <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt> ], <tt>
</tt> [<span class="sy">:a</span>, <span class="sy">:b</span>]<tt>
</tt> ]<tt>
</tt><tt>
</tt><span class="c"># Block.new.consume sexp.shift</span><tt>
</tt><span class="c"># :args => convert</span><tt>
</tt><span class="c"># :newline => convert</span><tt>
</tt><tt>
</tt> [ <tt>
</tt> [<span class="sy">:args</span>, [<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>], <tt>
</tt> [<span class="sy">:newline</span>, <span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ]<tt>
</tt><tt>
</tt><tt>
</tt><span class="c"># out = [<args node>, <newline node>] </span><tt>
</tt><tt>
</tt><span class="c"># Arguments.new.consume sexp.shift</span><tt>
</tt>[[<span class="sy">:a</span>, <span class="sy">:b</span>], [], <span class="pc">nil</span>, <span class="pc">nil</span>]<tt>
</tt><tt>
</tt><span class="c"># Newline.new.consume sexp.shift</span><tt>
</tt> [<span class="i">1</span>, <span class="s"><span class="dl">"</span><span class="k">(eval)</span><span class="dl">"</span></span>, <tt>
</tt> [<span class="sy">:yield</span>, <tt>
</tt> [<span class="sy">:call</span>, [<span class="sy">:lvar</span>, <span class="sy">:a</span>, <span class="i">0</span>], <span class="sy">:+</span>, [<span class="sy">:array</span>, [<span class="sy">:lvar</span>, <span class="sy">:b</span>, <span class="i">0</span>]]], <span class="pc">false</span><tt>
</tt> ]<tt>
</tt> ] <tt>
</tt></pre></td>
</tr></table>
ruetag:journal.kittensoft.org,2007-07-12:712007-07-12T18:27:00Z2008-02-08T04:05:55ZIRC Newsletter has moved
<p>Hello!</p>
<p>More recent <span class="caps">IRC</span> dispatches can be found on the <a href="http://rubini.us/forums/7">Rubinius website</a>.</p>
<p>Thanks for stopping by!</p>
ruetag:journal.kittensoft.org,2007-05-05:692007-05-05T01:42:00Z2008-02-08T02:47:16ZThe Dailyish IRC Newsletter, 2007.05.03
<p>Stuff from 2007.05.02-03</p>
<ul>
<li>Libevent woes
<p>Evan has been tracking down a bug in the library used for
monitoring files and sockets, Libevent. It is supposed to
abstract the best platform-specific library into an event-
based one. On <span class="caps">BSD</span> this means using kqueue, epoll on Linux
and so on (it can fall back on select() or poll() also.)</p>
<p>Aanyway. Apparently epoll is causing problems with regular
files for some reason. There is currently a workaround in
place but if anyone wants to try to tackle it, go for it.</p></li>
</ul>
<ul>
<li>I/O buffering
<p>Currently no buffering is being done on I/O (except of
course whatever the platform may add) which means it is
performing less-than optimally. A few ideas were tossed
around from writing our own buffering to borrowing ideas
from nginx’ probably brilliant implementation.</p></li>
</ul>
<ul>
<li>!=
<p>Defiler was working on implementing != as a method
rather than as a simple translation to a not
compiler translation. A default implementation in
(presumably) Object would still be a not-condition
but it might allow some nice tricks where and !=
might measure different things. This is, of course,
wildly incompatible with <span class="caps">MRI</span>.</p></li>
</ul>
<ul>
<li>Packaging
<p>brixen was wondering about future packaging needs
and whether the rubinius team should be responsible
for maintaining those instead of the traditional
shift of responsibility to third-party packagers.
Discussion on the topic and volunteers most welcome.</p></li>
</ul>
<ul>
<li>Debugging
<p>It is about time to start implementing a debugger to
help with some of the trickier VM issues. Implementation
is at this point completely open.</p></li>
</ul>
<ul>
<li>Developments
<p>A mysterious coder by the <span class="caps">IRC</span> nick of mojambo has
been working on Time.</p></li>
</ul>
<ul>
<li>Loading libraries
<p>kevinclark (guess what his real name is.. no fun some
of these people not embracing anonymity) found out that
the syntax for loading a library (#require, #load etc.)
is</p>
<p>out = VM.load_library ‘path/to/file’, ‘file’</p>
<p>where the first argument is the full path and the second
is the extension name. In the context of normal Ruby loading
these will be the same.</p>
<p>The extension suffix is currently determined statically
for the platform (.so, .bundle or .dll) in library.c.</p></li>
</ul>
<ul>
<li>rbconfig
<p>The above discussion lead into a short discussion about
implementing rbconfig.</p></li>
</ul>
<ul>
<li>Raw logs
<p>I have the raw <span class="caps">IRC</span> logs available uncropped and infrequently
updated with few gaps at http://files.kittensoft.org/rubinius.txt</p></li>
</ul>
ruetag:journal.kittensoft.org,2007-05-04:682007-05-04T00:21:00Z2007-05-04T00:26:17ZThe Dailyish IRC Newsletter, 2007.05.02
<p>Hi!</p>
<p>After a hiatus due to an ill-advised <span class="caps">COBOL</span>->Java conversion project
at work, I may again have enough time to post these semi-regularly.
My apologies. I will start off easy with two topics and then try to
work in some older news along with a hopefully-steady stream of, er,
new news.</p>
<p>I think this forum might actually be easier for me to work with so
I will try it out for a bit. Perhaps brixen could set up a nice
subforum just for the Newsletter for ease of navigation and
<span class="caps">RSS</span>’ing.</p>
<ul>
<li>Locality of testing platforms
<p>Evan put some collected money to good use and got
an Intel Mac Mini. Currently he has managed to cram
Solaris and FreeBSD on there as well so potential
platform-specific problems and tweaks should be
easier to do. He also said that if we ever get an
UltraSparc machine, I get to house it :D</p></li>
</ul>
<ul>
<li>Speccing
<p>We (and by we I mean brixen) finally got fed up
trying to get RSpec to run natively on Rubinius
and the host/target workaround so he wrote a quick
little replacement residing at spec/mini_rspec.rb.</p>
<p>I contributed a few small improvements and a stupid
bash kludge to run the specs so now </p>
<pre><code>bin/specrunner <file></code></pre>
<p>will allow you to run new-style specs with relative
ease.</p>
<p>New-style? Well, with the change we can finally
get rid of the example do … end syntax for the
specs. This means that all current specs have to
be restructured to the normal spec-style. I am
currently working down spec/core (Enumerable now)
and brixen is “cherry-picking” files to convert
whatever that means. Any help there is appreciated.</p>
<p>Next step, once all of the specs are converted,
is to start running them at least semi-regularly.
Watching thousands of specs go by is probably not
the easiest way to figure out whether your change
is working as intended so the Rakefile has two new
tasks, spec:diff:run and spec:diff:save. The first
one grabs a previous capture of a full spec run
from spec/diffs/base.txt and runs a diff -u against
a current spec run. This should make it easier to
see what has changed and whether you might have
broken something else. The latter task just saves
a new base run.</p></li>
</ul>
<p>Until later! Watch this space.</p>
ruetag:journal.kittensoft.org,2007-02-24:662007-02-24T07:23:00Z2007-02-24T07:31:17ZThe Dailyish IRC Newsletter, 2007.02.21-23
<p>The past few days have been almost entirely chatless on the channel, people being involved in various time-consuming projects. Yours truly has been suffering from the quinquennial case of Being Sick (a good Constitution score keeps me healthy for the intervening periods—definitely not a dump stat for a Code Wizard) and apparently some wild, roaming dog ate everyone else’s homework.</p>
<p>The next installment should actually have something more interesting again.</p>