Kittensoft - rubinius tag:journal.kittensoft.org,2008:mephisto/rubinius Mephisto Drax 2008-11-20T05:10:38Z rue tag:journal.kittensoft.org,2008-11-20:995 2008-11-20T04:41:00Z 2008-11-20T05:10:38Z Phase 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> rue tag:journal.kittensoft.org,2008-09-24:969 2008-09-24T23:39:00Z 2008-09-24T23:43:17Z Guy 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> rue tag:journal.kittensoft.org,2008-09-12:967 2008-09-12T09:57:00Z 2008-09-12T19:50:58Z Defensive 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&lt;Tuple&gt;(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> rue tag:journal.kittensoft.org,2008-09-11:966 2008-09-11T11:44:00Z 2008-09-11T12:03:59Z The 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> rue tag:journal.kittensoft.org,2008-09-08:965 2008-09-08T22:20:00Z 2008-09-08T22:41:44Z ucontext 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 &lt;ucontext.h&gt; struct thready { : ucontext_t some_context; ucontext_t some_other_context; : }; </code></pre> <p>The fixed version inserts the padding:</p> <pre><code>#include &lt;ucontext.h&gt; #define HAS_UCONTEXT // Or something struct thready { : #if defined(__APPLE__) &amp;&amp; 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> rue tag:journal.kittensoft.org,2008-04-01:912 2008-04-01T23:31:00Z 2008-04-02T00:17:58Z Conditional 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">&quot;</span><span class="k">Blah blah: </span><span class="il"><span class="dl">#{</span>some_variable<span class="dl">}</span></span><span class="dl">&quot;</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> rue tag:journal.kittensoft.org,2008-03-13:906 2008-03-13T01:47:00Z 2008-03-13T01:56:32Z Splitting 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`.) &lt;—<span class="caps">THIS IS IMPORTANT</span></li> <li>`cd ../..`</li> <li>`git add spec/ruby` &lt;—<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' &gt; 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' &gt; 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 &quot;spec/ruby&quot;]<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 &quot;git reset HEAD &lt;file&gt;...&quot; 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 -&gt; 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' &gt; 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 -&gt; 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 -&gt; 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 &quot;git add &lt;file&gt;...&quot; to update what will be committed)<tt> </tt><tt> </tt> modified: spec/ruby<tt> </tt><tt> </tt> no changes added to commit (use &quot;git add&quot; and/or &quot;git commit -a&quot;)<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 -&gt; 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 -&gt; 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' &gt; 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 -&gt; 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 &quot;master&quot;<tt> </tt> $ echo 'my spec' &gt; 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 -&gt; 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 &quot;git add &lt;file&gt;...&quot; to update what will be committed)<tt> </tt><tt> </tt> modified: spec/ruby<tt> </tt><tt> </tt> no changes added to commit (use &quot;git add&quot; and/or &quot;git commit -a&quot;)<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 &quot;git reset HEAD &lt;file&gt;...&quot; 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 &quot;git reset HEAD &lt;file&gt;...&quot; 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 -&gt; master<tt> </tt> $<tt> </tt></pre></td> </tr></table> rue tag:journal.kittensoft.org,2008-02-15:893 2008-02-15T04:49:00Z 2008-02-15T06:30:47Z Reinventing 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> rue tag:journal.kittensoft.org,2008-02-13:891 2008-02-13T03:25:00Z 2008-09-08T22:19:44Z Platform 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 &lt; 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> &lt;&lt;&lt; <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> rue tag:journal.kittensoft.org,2008-02-11:889 2008-02-11T00:50:00Z 2008-02-12T01:19:56Z All 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> rue tag:journal.kittensoft.org,2007-11-09:703 2007-11-09T19:49:00Z 2008-02-08T04:08:38Z Compiler 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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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 = [&lt;script node&gt;]</span><tt> </tt><tt> </tt><tt> </tt><span class="c"># Script.consume</span><tt> </tt><span class="c"># convert sexp.first -&gt;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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 = [&lt;block node&gt;]</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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 = [&lt;newline node&gt;]</span><tt> </tt><tt> </tt><span class="c"># Compiler#convert_sexp first</span><tt> </tt><span class="c"># -&gt; 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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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"># &lt;&lt; out = [1, &quot;eval&quot;, &lt;defn node&gt;]</span><tt> </tt><span class="c"># compiler.convert &lt;defn node&gt;</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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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 = [&lt;converted&gt;, 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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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 =&gt; convert</span><tt> </tt><span class="c"># :newline =&gt; 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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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 = [&lt;args node&gt;, &lt;newline node&gt;] </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">&quot;</span><span class="k">(eval)</span><span class="dl">&quot;</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> rue tag:journal.kittensoft.org,2007-07-12:71 2007-07-12T18:27:00Z 2008-02-08T04:05:55Z IRC 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> rue tag:journal.kittensoft.org,2007-05-05:69 2007-05-05T01:42:00Z 2008-02-08T02:47:16Z The 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> rue tag:journal.kittensoft.org,2007-05-04:68 2007-05-04T00:21:00Z 2007-05-04T00:26:17Z The Dailyish IRC Newsletter, 2007.05.02 <p>Hi!</p> <p>After a hiatus due to an ill-advised <span class="caps">COBOL</span>-&gt;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 &lt;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> rue tag:journal.kittensoft.org,2007-02-24:66 2007-02-24T07:23:00Z 2007-02-24T07:31:17Z The 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>