<?xml version="1.0"?>
<rss version="2.0">

<channel>
	<title>Planet Ruby</title>
	<link>http://planetruby.0x42.net/</link>
	<language>en</language>
	<description>Planet Ruby - http://planetruby.0x42.net/</description>

<item>
	<title>Phil Hagelberg: in which telephone seems like entirely the wrong word</title>
	<guid isPermaLink="false">tag:technomancy.us,2007:in%20which%20telephone%20seems%20like%20entirely%20the%20wrong%20word</guid>
	<link>http://technomancy.us/134</link>
	<description>&lt;p&gt;After years of resisting phone ownership followed by a few years
  of owning a 2003-era Nokia dumbphone, I finally decided to make
  the jump when the Nexus One was announced. I've got a strong
  distaste for systems that &lt;a href=&quot;http://apple.com/iphone&quot;&gt;place
  arbitrary restrictions on their users&lt;/a&gt;, and while the Android
  OS itself doesn't have any, many Android phones before the Nexus
  One have had the carriers interfere with the user's control over
  their phone, though not to the same offensive degree as
  Apple. The Nexus One is sold directly through Google without
  giving the carriers a chance to sully it.&lt;/p&gt;

&lt;h3&gt;Daily Usage&lt;/h3&gt;

&lt;p&gt;The screen is just brilliant, and the 800x480 resolution means
  everything is sharp. The OS is very smooth and responsive. Having
  spent so long on a system where the keyboard is king and the mouse
  is only used in exceptional cases, switching to the inverse
  situation on the phone is a bit odd, but not as disorienting as
  you'd expect. Like any handheld keyboard, the Nexus's is bad for
  writing anything longer than a tweet, but it's certainly no worse
  than the hardware keyboard on the
  old &lt;a href=&quot;http://www.amazon.com/Sharp-SL-5500-Zaurus-PDA/dp/B000063D6E&quot;&gt;Zaurus&lt;/a&gt;
  I toy around with occasionally. The built-in apps work great, and
  if you take the plunge to fully switch to GMail, it pretty much
  makes syncing your mailbox a solved problem.&lt;/p&gt;

&lt;img src=&quot;http://technomancy.us/i/nexus-one.jpg&quot; alt=&quot;nexus logo&quot; align=&quot;right&quot; /&gt;

&lt;p&gt;There are a few nit picks like the color balance being a bit off
  on the camera, the way the face buttons don't trigger unless you
  push the upper half, and the fact that the built-in jabber client
  only supports a single account. But these are all pretty minor or
  easy to work around. The only thing that really bugs me about it
  is the fact that there's no ZeroConf implementation yet for the
  platform. But there are people working on this, so it's just a
  matter of time.&lt;/p&gt;

&lt;h3&gt;Oh, and using it to Talk?&lt;/h3&gt;

&lt;p&gt;It turns out you can also use the Nexus One to interface with the
  global legacy telephone system and make calls on that. Supposedly
  it has a very nice dual-mic noise suppression system for when you
  do this, but I've only made a handful of test calls so far. I got
  a &lt;a href=&quot;http://www.t-mobile.com/shop/plans/cell-phone-plans-detail.aspx?tp=tb1&amp;amp;rateplan=T-Mobile-Total-Internet-Rate-Plan&quot;&gt;data-only
  plan&lt;/a&gt; for half of what the regular voice+data plans go for and
  had planned to use &lt;a href=&quot;http://sipdroid.org/&quot;&gt;Sipdroid&lt;/a&gt; to
  make VoIP calls with it, but then I realized I just don't make
  voice calls any more. So while there's a barely-noticeable delay
  with SIP calls over the 3G network, it really doesn't bother me. I
  also have used
  the &lt;a href=&quot;http://code.google.com/p/android-wired-tether/&quot;&gt;Wired
  Tether&lt;/a&gt; app to hook up my laptop on the go and can confirm that
  calls via Skype sound fine too. So it's nice that T-Mobile isn't
  blocking that on a network level. They do seem to be the
  least-user-hostile of all the US carriers.&lt;/p&gt;

&lt;h3&gt;Hacking It&lt;/h3&gt;

&lt;p&gt;Of course once you get past the formalities, the question that
  matters to a hacker is how it feels to hack. I've only really
  gotten started with this, but my initial report is fairly
  positive. The official toolsets are either Eclipse or Ant, neither
  of which give me warm fuzzies, but luckily you can use Ant out of
  the box without getting exposed to the XML-editing ickiness.&lt;/p&gt;

&lt;img src=&quot;http://technomancy.us/i/garrett.png&quot; alt=&quot;garrett demo&quot; align=&quot;left&quot; /&gt;

&lt;p&gt;Getting programs onto the device is pretty simple. Once your
  source is ready, you run &lt;kbd&gt;ant debug&lt;/kbd&gt;, which produces a
  .apk package. You can use the &lt;kbd&gt;adb&lt;/kbd&gt; (android debugger)
  program to load it up over USB, but since I keep leaving my USB
  cable various places, I prefer just &lt;kbd&gt;scp&lt;/kbd&gt;ing it to my
  server and pointing my device's browser directly at the .apk. You
  can also use this to install dev builds of various apps before
  they have been uploaded to the Market.&lt;/p&gt;

&lt;p&gt;The API seems pretty sane. A lot of thought has gone into the
  notion of supporting a single front-and-center application while
  allowing others to run in the background without impacting battery
  life and performance too severely. I've played a bit with the
  graphics tools, and they remind me a fair bit
  of &lt;a href=&quot;http://processing.org&quot;&gt;Processing&lt;/a&gt;, which is a good
  thing. I haven't done much intricate UI work with a lot of buttons
  or menus, but that kind of stuff can be tedious even in the nicest
  environments.&lt;/p&gt;

&lt;h3&gt;Language of Choice&lt;/h3&gt;

&lt;p&gt;Since the Android VM is based on the JVM, there's a whole host of
  languages that can run on it. Unfortunately, Dalvik is no
  Hotspot&amp;mdash;it currently lacks JIT, and the GC is merely
  serviceable rather than astoundingly good like Hotspot's. The lack
  of a good GC makes using &lt;a href=&quot;http://technomancy.us/132&quot;&gt;persistent data
  structures&lt;/a&gt; a real drag since they generate a lot of ephemeral
  garbage, so Clojure is not a good choice. The lack of JIT coupled
  with CPUs that are comparatively low-powered means that
  while &lt;a href=&quot;http://groups.google.com/group/ruboto&quot;&gt;JRuby
  runs&lt;/a&gt;, it's not altogether pleasant, especially considering the
  blitz with which regular apps perform. I've been told there is
  some low-hanging fruit for improving performance on Android, so
  this is likely to improve to a degree. Rhino, Python, Lua, Scala,
  and others work, (including, I'm told, even some legacy languages
  like Java, if you can imagine that) but I decided to try the
  less-traveled route with something
  called &lt;a href=&quot;http://github.com/headius/duby&quot;&gt;Duby&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Duby is a language created by Charles Nutter, the head of the
  JRuby project. JRuby is an amazing feat in part because Ruby's
  object model is vastly different from what's natively available on
  the Java platform. By an astounding effort they've managed to put
  together a first-class Ruby implementation, but it does beg the
  question: what would a modern language look like that
  went &lt;i&gt;with&lt;/i&gt; the grain of its host instead of violently
  against it? Duby is an attempt to answer that question.&lt;/p&gt;

&lt;p&gt;The syntax of Duby is nearly identical to that of Ruby; it only
  adds type declarations to method definitions. Yes, that means it's
  statically-typed. While it has type inference, it's not
  Hindley-Milner-style, it's closer to Scala's. Locals get their
  types inferred, it's only arguments in method definitions that
  need hints. So far I keep forgetting this nearly every time
  I write a new method since it looks so close to Ruby otherwise,
  but I'm sure I'll get the hang of it. Closures are implemented, so
  you can iterate over collections with blocks. Duby is also unique
  in that it literally has no runtime&amp;mdash; its literals translate
  directly to ArrayLists and HashMaps, so once you've compiled, the
  code is more or less identical to what the Java compiler would
  have output.&lt;/p&gt;

&lt;h3&gt;Progress&lt;/h3&gt;

&lt;p&gt;So far I've only put together a couple toy apps: Hello World, and
  a &lt;a href=&quot;http://github.com/technomancy/Garrett&quot;&gt;graphics demo
  with a bouncing ball&lt;/a&gt;. Unfortunately, Duby is a &lt;i&gt;very&lt;/i&gt;
  immature language, and it shows. Starting out I had to go to
  Charlie at nearly every turn with stack traces. Half the time it
  would be my fault, and half the time it would be something
  as-yet-unsupported by the compiler. But so far he's been able to
  turn around and bring in all the features I need, which has been
  quite amazing. I'm hoping to get a chance to dive into the
  compiler source myself and get to the point where I can add
  features I need with minimal guidance.&lt;/p&gt;

&lt;p&gt;Adapting the build process to Duby was surprisingly easy. You
  &lt;a href=&quot;http://github.com/technomancy/Garrett/blob/master/build.xml#L67&quot;&gt;redeclare
    the compile task&lt;/a&gt; to call the Duby compiler instead of javac,
    tell it to output its bytecode in the right directory, and the
    rest of it just falls into place.&lt;/p&gt;

&lt;p&gt;My next plans are to add more interactivity to my graphics demo;
  I'd like to play with creating objects and applying motion rules
  to them; I hope to come up with something my two-year-old would
  get a kick out of. So far it's been a lot of fun and a great way
  to explore the capabilities of this remarkable device.&lt;/p&gt;</description>
	<pubDate>Sun, 07 Feb 2010 21:35:24 +0000</pubDate>
</item>
<item>
	<title>Tomasz Wegrzanowski: What is all this Perl doing in my Ruby?</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-27488238.post-8969037111727694265</guid>
	<link>http://t-a-w.blogspot.com/2010/02/what-is-all-this-perl-doing-in-my-ruby.html</link>
	<description>&lt;div class=&quot;separator&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_IYGc_MWwkfw/S2yPBGnfITI/AAAAAAAAAxw/DnMiSMmzwAY/s1600-h/spacecat_by_kmndr_from_flickr_cc-by.jpg&quot; title=&quot;Spacecat. by kmndr from flickr (CC-BY)&quot;&gt;&lt;img alt=&quot;Spacecat. by kmndr from flickr (CC-BY)&quot; border=&quot;0&quot; height=&quot;428&quot; src=&quot;http://2.bp.blogspot.com/_IYGc_MWwkfw/S2yPBGnfITI/AAAAAAAAAxw/DnMiSMmzwAY/s640/spacecat_by_kmndr_from_flickr_cc-by.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;First, some quick background. C is a very simple programming language and doesn't have exceptions - problems are indicated with return codes, which you're supposed to check but always forget about it, resulting in all sorts of problems. C++ tried to retrofit exceptions on top of that, and it was a spectacular failure due to bad interactions between exceptions and manual memory management, but let's skip that.&lt;br /&gt;&lt;br /&gt;Shell doesn't have exceptions either, but almost all problems result in some error message being printed to stderr, so at least you know that something went wrong.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Perl is trying to be higher level but is modeled after C and shell, so while it sort of support exceptions for some high level packages, almost all of its basic OS-interacting functions like &lt;tt&gt;open&lt;/tt&gt; will fail quietly and you need to manually check their return codes - at least it's easier than C, and &lt;tt&gt;... or die &quot;Cheeseburger acquisition failed: $!&quot;;&lt;/tt&gt; usually suffices.&lt;br /&gt;&lt;br /&gt;Ruby mostly copies Perl when it comes to OS interaction, but fixes this particular problem - OS interaction always raises an exception when something goes wrong. Or does it?&lt;br /&gt;&lt;h3&gt;system()&lt;/h3&gt;&lt;br /&gt;There is one really infuriating exception, where not only Perl error handling is worse than both C and shell, Ruby copies this design failure straight from it, and it's not even fixed in Ruby 1.9 yet!&lt;br /&gt;&lt;br /&gt;C function &lt;tt&gt;system&lt;/tt&gt; is fairly straightforward - it executes whatever string you pass to it in shell. So if there's an error and let's say the command &lt;tt&gt;fail&lt;/tt&gt; doesn't exist - &lt;tt&gt;int main(){ system(&quot;fail&quot;); return 0; }&lt;/tt&gt; results in &lt;tt&gt;&quot;sh: fail: command not found&quot;&lt;/tt&gt; printed on stderr, or somesuch depending on your variant of Unix. Just like shell would do it, and what would be sane.&lt;br /&gt;&lt;br /&gt;Both Perl and Ruby copy this function - except they do it wrong! &lt;tt&gt;system&lt;/tt&gt; funciton is not terribly efficient - it first spawns shell process, which only then executes the relevant command. So some smarty pants decided to optimize it a bit - if the string passed to Perl/Ruby &lt;tt&gt;system&lt;/tt&gt; looks straightforward enough, Perl/Ruby will execute it directly (split on spaces, &lt;tt&gt;fork&lt;/tt&gt;, pass to &lt;tt&gt;exec&lt;/tt&gt;) without spawing the shell process.&lt;br /&gt;&lt;br /&gt;And in this micro-shell implementation inside &lt;tt&gt;system&lt;/tt&gt; they both just forgot to check for error conditions altogether. &lt;tt&gt;system &quot;fail &amp;gt;/dev/null&quot;&lt;/tt&gt; (in either of these languages) looks &quot;non-trivial&quot;, so it spawns shell process, and results in &lt;tt&gt;sh: fail: command not found&lt;/tt&gt;. But &lt;tt&gt;system &quot;fail&quot;&lt;/tt&gt; - as it's so simple - goes straight to the optimized micro-shell, and fail silently. No exception, no stderr warning, no error code, nothing.&lt;br /&gt;&lt;br /&gt;Well yes, you could check process return code - but process return code is non-zero not only on errors, but as a generic way for Unix processes to communicate - for example diff will return non-zero if files differ, which is in no way an error condition.&lt;br /&gt;&lt;h3&gt;The fix&lt;/h3&gt;The optimization should be either fixed or turned off. As a trivial workaround - because the triviality check verifies that string contains none of &lt;tt&gt;*?{}[]&amp;lt;&amp;gt;()~&amp;amp;| \ $;'`&quot;&lt;/tt&gt; or newline, prepending &lt;tt&gt;&quot;&quot;&lt;/tt&gt; in front of the first non-empty character passed system() seems to work well enough. &lt;tt&gt;&quot;&quot;&lt;/tt&gt; evaluates to an empty string in shell.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ ruby -e 'system &quot;\&quot;\&quot;fail&quot;'&lt;br /&gt;sh: fail: command not found&lt;/pre&gt;&lt;pre&gt;$ ruby1.9 -e 'system &quot;\&quot;\&quot;fail&quot;'&lt;br /&gt;sh: fail: command not found&lt;br /&gt;$ perl -e 'system &quot;\&quot;\&quot;fail&quot;'&lt;br /&gt;sh: fail: command not found&lt;/pre&gt;&lt;br /&gt;&amp;nbsp;But seriously, please fix this, okay? Even Python gets it right already.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/27488238-8969037111727694265?l=t-a-w.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 05 Feb 2010 22:45:27 +0000</pubDate>
	<author>noreply@blogger.com (taw)</author>
</item>
<item>
	<title>Tom Copeland: Leveraging config.gem in Capistrano's deploy:check</title>
	<guid isPermaLink="false">http://tomcopeland.blogs.com/juniordeveloper/2010/02/leveraging-configgem-in-capistranos-deploycheck.html</guid>
	<link>http://tomcopeland.blogs.com/juniordeveloper/2010/02/leveraging-configgem-in-capistranos-deploycheck.html</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.capify.org/index.php/Capistrano&quot;&gt;Capistrano&lt;/a&gt; lets you enumerate your Rails application's dependencies so you can check them at deploy time. &lt;a href=&quot;http://mislav.uniqpath.com/rails/specify-your-dependencies-with-capistrano/&quot;&gt;Mislav Marohnić&lt;/a&gt; did a good description of it a while back; here are some example &lt;code&gt;depend&lt;/code&gt; entries:&lt;/p&gt;

&lt;pre&gt;depend :remote, :gem, &amp;quot;tzinfo&amp;quot;, &amp;quot;&amp;gt;=0.3.3&amp;quot;&lt;br /&gt;depend :local, :command, &amp;quot;svn&amp;quot;&lt;br /&gt;depend :remote, :directory, &amp;quot;/u/depot/files&amp;quot;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;The problem with &lt;code&gt;depend :remote, :gem&lt;/code&gt;, though, is that it duplicates the &lt;code&gt;config.gem&lt;/code&gt; entries that you already have in &lt;code&gt;config/environment.rb&lt;/code&gt;. It'd be much nicer if you could just reuse those.&lt;/p&gt;

&lt;p&gt;So, here's some code that you can paste in your deploy.rb to do just that:&lt;/p&gt;

&lt;pre&gt;# Add dependencies on gems listed in config/environment.rb&lt;br /&gt;class Collecter&lt;br /&gt; attr_accessor :dependencies&lt;br /&gt; def initialize&lt;br /&gt;  @dependencies = {}&lt;br /&gt;  File.read(File.join(&amp;quot;config&amp;quot;, &amp;quot;environment.rb&amp;quot;)).split(&amp;quot;\n&amp;quot;).select {|line| line.match(/^(\s)*config.gem/) }.each do |line|&lt;br /&gt;   self.instance_eval(line)&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt; def gem(name, args)&lt;br /&gt;  @dependencies[name] = args&lt;br /&gt;  args[:version] = &amp;quot;&amp;gt;=0.0.1&amp;quot; unless args.include?(:version)&lt;br /&gt; end&lt;br /&gt; def config&lt;br /&gt;  self&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;Collecter.new.dependencies.each do |name, args|&lt;br /&gt; depend :remote, :gem, name, args[:version]&lt;br /&gt;end&lt;br /&gt;after &amp;quot;deploy:setup&amp;quot;, &amp;quot;deploy:check&lt;/pre&gt;

&lt;p&gt;This parses your &lt;code&gt;config/environment.rb&lt;/code&gt;, extracts the &lt;code&gt;config.gem&lt;/code&gt; calls, and evaluates them in the context of an object that gathers up the dependency arguments. Then it declares an after hook for &lt;code&gt;deploy:setup&lt;/code&gt; that runs &lt;code&gt;deploy:check&lt;/code&gt;, so when you set up the application on a new server it'll ensure that the right stuff is in place.&lt;/p&gt;

&lt;p&gt;Here's a sample run from my &lt;a href=&quot;http://militaryprofessionalreadinglists.com/&quot;&gt;military reading list&lt;/a&gt; app:&lt;/p&gt;

&lt;pre&gt;$ cap deploy:setup&lt;br /&gt; * executing `deploy:setup'&lt;br /&gt; * executing &amp;quot;mkdir -p /var/www/militaryprofessionalreadinglists.com/&amp;quot;&lt;br /&gt;[blah blah blah]&lt;br /&gt; command finished&lt;br /&gt; triggering after callbacks for `deploy:setup'&lt;br /&gt; * executing `deploy:check'&lt;br /&gt; * executing &amp;quot;test -d /var/www/militaryprofessionalreadinglists.com/releases&amp;quot;&lt;br /&gt; servers: [&amp;quot;militaryprofessionalreadinglists.com&amp;quot;]&lt;br /&gt; [militaryprofessionalreadinglists.com] executing command&lt;br /&gt; command finished&lt;br /&gt;[blah blah blah]&lt;br /&gt; * executing &amp;quot;gem specification --version '&amp;gt;=0.0.1' mislav-will_paginate 2&amp;gt;&amp;amp;1 | awk 'BEGIN { s = 0 } /^name:/ { s = 1; exit }; END { if(s == 0) exit 1 }'&amp;quot;&lt;br /&gt; servers: [&amp;quot;militaryprofessionalreadinglists.com&amp;quot;]&lt;br /&gt; [militaryprofessionalreadinglists.com] executing command&lt;br /&gt; command finished&lt;br /&gt;You appear to have all necessary dependencies installed&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;Good times. The nice thing here is that the developer only has to list the dependencies in one place, and the hook ensures that failures are loudly proclaimed during initial setup.&lt;/p&gt;

&lt;p&gt;I'm not sure how to integrate this into Capistrano itself; if Lee Hambley or one of the other Capistrano gurus sees this perhaps they can weigh in... thanks!&lt;/p&gt;</description>
	<pubDate>Fri, 05 Feb 2010 17:00:19 +0000</pubDate>
</item>
<item>
	<title>Ruby on Rails: Rails 3.0: Beta release</title>
	<guid isPermaLink="false">tag:weblog.rubyonrails.org,2010-02-05:26212</guid>
	<link>http://feedproxy.google.com/~r/RidingRails/~3/YKWnd31u9Hg/rails-3-0-beta-release</link>
	<description>&lt;p&gt;You thought we were never going to get to this day, didn’t you? Ye of little faith. Because here is the first real, public release of Rails 3.0 in the form of a beta package that we’ve toiled long and hard over.&lt;/p&gt;


	&lt;p&gt;It’s surely not perfect yet, but we were out of blockers on the list, so here we go. Please give it a run around the block, try to update some old applications, try to start some new ones, and report back all the issues you find.&lt;/p&gt;


	&lt;p&gt;I’m really proud of this moment, actually. We’ve had more than 250 people help with the release and we’ve been through almost 4,000 commits since 2.3 to get here. Yet still the new version feels lighter, more agile, and easier to understand. It’s a great day to be a Rails developer.&lt;/p&gt;


	&lt;p&gt;There’s plenty to get excited about here. A few of the headliner features are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Brand new router with an emphasis on RESTful declarations&lt;/li&gt;
		&lt;li&gt;New Action Mailer &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; modelled after Action Controller (now without the agonizing pain of sending multipart messages!)&lt;/li&gt;
		&lt;li&gt;New Active Record chainable query language built on top of relational algebra&lt;/li&gt;
		&lt;li&gt;Unobtrusive JavaScript helpers with drivers for Prototype, jQuery, and more coming (end of inline JS)&lt;/li&gt;
		&lt;li&gt;Explicit dependency management with Bundler&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;But please take a look at the &lt;a href=&quot;http://guides.rails.info/3_0_release_notes.html&quot;&gt;full release notes&lt;/a&gt; and enjoy the latest!&lt;/p&gt;


	&lt;p&gt;To install:&lt;/p&gt;


&lt;pre&gt;
gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n
gem install rails --pre
&lt;/pre&gt;

	&lt;p&gt;&lt;small&gt;&lt;i&gt;Notes: The first line is required because RubyGems currently can’t mix prerelease and regular release gems (someone please fix that!).&lt;/i&gt;&lt;/small&gt;&lt;/p&gt;</description>
	<pubDate>Fri, 05 Feb 2010 03:42:25 +0000</pubDate>
</item>
<item>
	<title>Jamis Buck: There is no magic, there is only awesome (Part 4)</title>
	<guid isPermaLink="false">tag:weblog.jamisbuck.org,2010-01-26:7923</guid>
	<link>http://weblog.jamisbuck.org/2010/1/26/there-is-no-magic-there-is-only-awesome-part-4</link>
	<description>&lt;p&gt;&lt;em&gt;This is the fourth (and final) article in a series titled “There is no magic, there is only awesome.” The first article introduced the &lt;a href=&quot;http://weblog.jamisbuck.org/2009/9/17/there-is-no-magic-there-is-only-awesome-part-1&quot;&gt;four cardinal rules of awesomeness&lt;/a&gt;, the second was about &lt;a href=&quot;http://weblog.jamisbuck.org/2009/9/25/there-is-no-magic-there-is-only-awesome-part-2&quot;&gt;knowing thy tools&lt;/a&gt;, and the third encouraged you to &lt;a href=&quot;http://weblog.jamisbuck.org/2009/10/9/there-is-no-magic-there-is-only-awesome-part-3&quot;&gt;know thy languages&lt;/a&gt; .&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;First off, I apologize for dragging this out. It’s really become a weight on my shoulders. I’ve been fretting and fretting about writing the last two or three posts in this series, and I just couldn’t find the inspiration to make them come out like I wanted…and they’ve been holding up other posts I’ve been wanting to write.&lt;/p&gt;


	&lt;p&gt;So I’m going to cheat. You’re going to get a braindump, more or less, of the last two rules of awesomeness. Yes, I am entirely cognizant of the irony here. Nonetheless, here goes.&lt;/p&gt;
&lt;h2&gt;Rule #3: Know thy libraries!&lt;/h2&gt;


	&lt;p&gt;If you want to be awesome, know your dependencies. At the very least, understand what each plugin, library, and technique you use, does. If called on to explain why you are using a particular design pattern, could you justify it? If someone asked you to compare plugin X and plugin Y, could you explain what their different strengths and weaknesses are? If you discover a particular library behaving erratically, would you be able to dig into the library’s guts to tell the author roughly where the problem is? Or would you be one of those who has to tug on the author’s sleeve and say, metaphorically, “it hurts when I do this”?&lt;/p&gt;


	&lt;p&gt;By libraries, I mean (essentially) any bit of code that you depend on, that has a life of its own outside your application. I’m including design patterns in this, although they aren’t really code, but they do represent a “library” of possibly ways to architect code. Basically, if you’re using someone else’s code, algorithms, or techniques, know why you’re using them. Make sure you can answer the four questions:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;What does this do best?&lt;/li&gt;
		&lt;li&gt;What does this do worst?&lt;/li&gt;
		&lt;li&gt;Why should I use this in particular?&lt;/li&gt;
		&lt;li&gt;When was the last time I learned something new about this?&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h2&gt;Rule #4: Know thy communities!&lt;/h2&gt;


	&lt;p&gt;The last rule says that if you want to be awesome, you can’t do it in a vacuum. By writing code, you automatically join an ecosystem, whether it be a network of coworkers who will help you write, debug, deploy, and maintain that code, or a community of hobbyists who might wish to use your code in applications of their own (or who are writing code that &lt;em&gt;you&lt;/em&gt; want to use). Even if all you do is pop up out of your cave long enough to toss some code into the public domain, you’re still contributing to a community, and if you’re using other people’s code, then you’re a consumer as well.&lt;/p&gt;


	&lt;p&gt;Don’t be blind to those communities. Stop for a minute and think about the communities you belong to, whether explicitly (where you’re a card-carrying, due-paying member) or implicitly (where you’re passively consuming someone else’s code), or somewhere in-between.&lt;/p&gt;


	&lt;p&gt;Why is this important? Mostly because communities are resources. Each community will be good for different kinds of help, collaboration, or criticism, and if you want to make the most of those resources (which, if you’re really awesome, you will), you need to know where each shines. Again, apply the four questions. What does this community do best? What is it worst at? Why should I participate in this particular community, over all the possible alternatives? And when was the last time I learned from this community?&lt;/p&gt;


	&lt;p&gt;That last is important, and surprisingly deep. If you are no longer learning from a community, what are you still doing there? Some of you are no doubt saying “but, but, but” and eagerly pointing out that maybe someone is part of a community so that they can lift others up, but note: if you’re doing that right, you’re still learning from those you teach. You learn new ways that your craft can be confusing to people. You learn new ways of looking at things that you’ve been taking from granted. You learn new ways to rephrase concepts that have grown stale in your own mind. It keeps you fresh. If you’re doing it wrong, though, then the only reason you remain in a community that teaches you nothing is complacency. And complacency is on the opposite end of the excellence spectrum from awesomeness.&lt;/p&gt;


	&lt;h2&gt;Words of caution&lt;/h2&gt;


	&lt;p&gt;So, those are the four rules. There is one overriding caveat to all of this, though, and that is: use moderation. You’re not going to master all of this in a day. Or even a week, or month, or year. I don’t know anyone that is perfect at all four things (though I know many who are much, much better than I am). To sound all zen and mysterious: awesomeness is a journey, not a destination. Enjoy the trip, appreciate the view, but don’t overdo it.&lt;/p&gt;


	&lt;p&gt;When you overdo it, you risk burning out. I’ve been riding that line for a couple years now, which was frightening. When writing code is your bread and butter, paying the bills and putting food on the table for you and your family, it is scary to contemplate “what do I do when I suddenly don’t want to do what I’ve been doing”. This is a big reason why I had to let go of &lt;a href=&quot;http://capify.org&quot;&gt;Capistrano&lt;/a&gt; and other projects, and why I’ve discovered other hobbies (like woodcarving, string figuring, and cooking) that do not involve computers. I’m trying to find the middle ground, so that I can recapture the joy of writing code.&lt;/p&gt;


	&lt;p&gt;So: be awesome. But only in moderation.&lt;/p&gt;</description>
	<pubDate>Sun, 31 Jan 2010 23:42:02 +0000</pubDate>
</item>
<item>
	<title>Phil Hagelberg: in which, were a title to be summarized from the content, it would be altogether too similar to many of the titles used for past articles, possibly to the point of indistinguishability</title>
	<guid isPermaLink="false">tag:technomancy.us,2007:in%20which,%20were%20a%20title%20to%20be%20summarized%20from%20the%20content,%20it%20would%20be%20altogether%20too%20similar%20to%20many%20of%20the%20titles%20used%20for%20past%20articles,%20possibly%20to%20the%20point%20of%20indistinguishability</guid>
	<link>http://technomancy.us/133</link>
	<description>&lt;p&gt;Anyone who follows my exploits will have noticed I'm a tireless
  proponent of &lt;a href=&quot;http://tromey.com/elpa&quot;&gt;ELPA&lt;/a&gt;, the Emacs
  Lisp Package Archive. As a maintainer of several Elisp libraries,
  ELPA makes my life easier by helping me sidestep the boring
  problems of distribution and installation. You may not know that
  package.el, the software behind ELPA, has been submitted for
  inclusion in the next version of Emacs. I've taken up the task of
  getting it ready.&lt;/p&gt;

&lt;img src=&quot;http://technomancy.us/i/flight-museum.jpg&quot; alt=&quot;museum of flight bridge&quot; align=&quot;right&quot; /&gt;

&lt;p&gt;Including something like package.el into Emacs is a big job, and
  it's something that can only happen gradually. Emacs comes with a
  number of applications such as &lt;a href=&quot;http://orgmode.org&quot;&gt;Org
  Mode&lt;/a&gt; and &lt;a href=&quot;http://gnus.org&quot;&gt;Gnus&lt;/a&gt; that are developed
  externally to Emacs and merged periodically into the main Emacs
  source tree. If they were to be redone as packages they could
  still be distributed with Emacs builds but kept out of the source
  tree. They could also be upgraded and installed/removed
  independently of Emacs' historically long release cycles.&lt;/p&gt;

&lt;p&gt;If you've submitted packages to ELPA before, you know it's a
  process that could use some streamlining. Currently it's all done
  by email, and packages must be manually uploaded by a single
  maintainer before they appear to users. This has long been the
  biggest shortcoming of ELPA. I've written some additions
  (package-maint.el) that allow you to automate the maintenance of a
  package source. Basically you provide it with a list of git URLs,
  and it will check out each tagged version and create a package
  from it. Of course, that wouldn't be useful without giving clients
  the ability to get packages from multiple sources at once, which I
  also added to package.el.&lt;/p&gt;

&lt;p&gt;If you maintain any Emacs packages of your own, please try out
  &lt;a href=&quot;http://github.com/technomancy/package.el&quot;&gt;my changes to
  package.el&lt;/a&gt;. If you use any of my packages, try upgrading and
  adding my package source to your list.&lt;/p&gt;

  &lt;pre class=&quot;code&quot;&gt;(add-to-list 'package-archives
             '(&quot;technomancy&quot; . &quot;http://repo.technomancy.us/emacs/&quot;) t)&lt;/pre&gt;

  &lt;p&gt;That way you'll get access to my updates as soon as they're
    tagged rather than waiting for them to be manually uploaded,
    though currently the latest versions of all my packages are in
    ELPA. Next steps are closer integration with Emacs in order to
    have packages installable on a system-wide level as well as a
    per-user level, prerelease version number support, and
    extraction of some built-in Emacs libraries as
    packages. Suggestions, bug reports, and patches welcome!&lt;/p&gt;</description>
	<pubDate>Sun, 31 Jan 2010 18:10:28 +0000</pubDate>
</item>
<item>
	<title>O'Reilly Ruby: Exploring Rails 3 - Our Free Rails Online Conference, Feb 18 @ 9am PT</title>
	<guid isPermaLink="false">http://en.oreilly.com/railswinter10</guid>
	<link>http://feeds.oreilly.com/~r/oreilly/ruby/~3/7x_Mg2f7hCE/railswinter10</link>
	<description>Rails 3 is taking its final shape, so there's no better time to take a close look at the work that's been done in the past year. Join us for a series of talks on everything you'll need to get started with it &amp;mdash; from creating a new application, to upgrading from Rails 2, to the foundation that makes it all possible. Attendance is limited, so register now!
	&lt;img src=&quot;http://feeds.feedburner.com/~r/oreilly/ruby/~4/7x_Mg2f7hCE&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sat, 30 Jan 2010 01:07:15 +0000</pubDate>
</item>
<item>
	<title>Nick Sieger: Gem clash: activerecord-jdbc-adapter and pg</title>
	<guid isPermaLink="false">urn:uuid:1500ad3a-6955-43fe-975a-3c663b48c100</guid>
	<link>http://blog.nicksieger.com/articles/2010/01/28/gem-clash-activerecord-jdbc-adapter-and-pg</link>
	<description>&lt;p&gt;I got a note from a community member about an annoying problem that a &lt;a href=&quot;http://blog.admoolabs.com/uninitialized-constant-activerecord-connectionadapters-postgresqladapter-pgconn/&quot;&gt;few people have run into&lt;/a&gt; when installing &lt;code&gt;activerecord-jdbc-adapter&lt;/code&gt; (AR&amp;#45;JDBC) into a C Ruby implementation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NameError: uninitialized constant
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::PGconn
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Turns out it&amp;#8217;s pretty easy to momentarily forget to use &lt;code&gt;jruby -S gem&lt;/code&gt; or &lt;code&gt;jgem&lt;/code&gt; and just &lt;code&gt;gem install activerecord-jdbc-adapter&lt;/code&gt; and suddenly your &lt;code&gt;pg&lt;/code&gt; Postgres gems are not working properly&amp;#46; I thought it was worth documenting here in case others run into this problem&amp;#46;&lt;/p&gt;

&lt;p&gt;I apologize for the clash&amp;#46; I had to provide a stub &lt;code&gt;pg.rb&lt;/code&gt; in AR&amp;#45;JDBC inside of JRuby so that I could get &lt;code&gt;active_record/connection_adapters/postgresql_adapter.rb&lt;/code&gt; to load with a database adapter type of &lt;code&gt;postgresql&lt;/code&gt;&amp;#46; Because of load path order issues, I couldn&amp;#8217;t get AR&amp;#45;JDBC&amp;#8217;s code to load before ActiveRecord&amp;#8217;s&amp;#46; At the time I was thinking this wouldn&amp;#8217;t be a problem because the &lt;code&gt;pg&lt;/code&gt; library won&amp;#8217;t work on JRuby anyway, right? Wrong&amp;#46;&lt;/p&gt;

&lt;p&gt;I can think of a couple options going forward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Submit a patch to ActiveRecord so that &lt;code&gt;active_record/connection_adapters/postgresql_adapter.rb&lt;/code&gt; can load without requiring &lt;code&gt;pg&lt;/code&gt; up front and then AR&amp;#45;JDBC won&amp;#8217;t have to stub it out&amp;#46;&lt;/li&gt;
&lt;li&gt;Display a big fat warning message when AR&amp;#45;JDBC is installed into anything other than JRuby&amp;#46;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Any other thoughts?&lt;/p&gt;</description>
	<pubDate>Thu, 28 Jan 2010 15:16:49 +0000</pubDate>
</item>
<item>
	<title>Charles Oliver Nutter: Five Reasons to Wait on the iPad</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-20975090.post-4361804608832616645</guid>
	<link>http://blog.headius.com/2010/01/five-reasons-to-wait-on-ipad.html</link>
	<description>Like most geeks, I watched with great anticipation as the iPad was unveiled yesterday. In my case, it was from liveblogs monitored on spotty 3G and WiFi access at the Jfokus after-conference event. I'm reasonably impressed with the device, especially the $500 price point on the low end. But after giving it some thought, I have a few good reasons to wait on purchasing one. Here's five I came up with:&lt;br /&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Wait for the next generation.&lt;/b&gt; Never, ever buy the first generation of a device this new and this complex. Doubly so for anything the Apple hype machine is pimping. First-gen devices are always at least a little bit tweaky, and Apple has proven repeatedly that their first-gen devices are overpriced, underpowered, and replaced by something better in 4-6 months.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Wait for competitors to answer.&lt;/b&gt; Sure, there have been other tablets and &quot;slates&quot; announced over the past year, but the iPad has moved the bar. Given the number of competing vendors, the availability of viable tablet options like Windows 7 and Android (or Chrome OS), and the ever-present iControl and iLock-in associated with all things Apple, you can bet there's going to be a bunch of competitive options during 2010.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Wait for everyone else to buy it.&lt;/b&gt; Yeah, this one is painful, but think about all the suckers that bought the iPhone right when it came out. You'll spend a couple months as a temporary luddite, ridiculed by your peers. And then you'll get a better device for cheaper and have the last laugh. I mean, isn't half the joy of the iPad in having the bigger iPenis? You can hold off for a while.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Wait for crackers to bust it wide open.&lt;/b&gt; Nobody's happy that the iPhone is a closed platform, nor are they happy that the App Store is so sketchy at approving applications. So why not wait and see what the busy iPhone hackers can do with an iPad before diving it? Chances are it will be a far better laptop replacement once they get ahold of it.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Wait because you don't actually need it.&lt;/b&gt; It can't replace your phone. It can't replace your laptop. It can't replace your 50&quot; LCD TV. Seriously now...what do you need it for?&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Me, I'm on the fence. I can afford it, but then I probably wouldn't be able to afford something else. And I'm a programmer...I want to be able to put my own apps on the device (or give apps to friends) without dealing with the App Store gatekeeper. In my ideal world, it would be Apple's hardware and design sensibility combined with Android's open platform and familiar runtime. Anything even close to that would outshine the iPad for me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;Update:&lt;/i&gt;&lt;span class=&quot;Apple-style-span&quot;&gt; One last bit of anecdotal evidence. Before the iPhone, I had held off buying anything other than the crappiest, cheapest phones, the lowest-end music devices (yep, I had the &quot;pack of gum&quot; Shuffle), the most basic digital cameras, and no PDA. I was waiting for something that would allow me to get rid of all devices at once. iPhone obviously did that, as a music/media player, internet device, PDA, phone, and camera all in one. iPad takes two of those features away (phone and camera) and only adds a larger screen with the potential for large-form apps.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/20975090-4361804608832616645?l=blog.headius.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 28 Jan 2010 03:05:18 +0000</pubDate>
	<author>headius@headius.com (Charles Oliver Nutter)</author>
</item>
<item>
	<title>Chad Fowler: RubyConf India</title>
	<guid isPermaLink="false">tag:www.chadfowler.com,2010-01-25:21042</guid>
	<link>http://www.chadfowler.com/2010/1/25/rubyconf-india</link>
	<description>&lt;p&gt;I’ve decided to travel less this year. Since my job involves a lot of travel, this mostly translates into going to less conferences.&lt;/p&gt;


	&lt;p&gt;So for 2010 I so far have only one conference on the agenda (other than those I’m co-organizing): &lt;a href=&quot;http://rubyconfindia.org/&quot;&gt;RubyConf India&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I’m speaking at the event and also helping out on the proposal committee along with &lt;a href=&quot;http://m.onkey.org/&quot;&gt;Pratik Naik&lt;/a&gt; and &lt;a href=&quot;http://olabini.com/blog/&quot;&gt;Ola Bini&lt;/a&gt;.  So far the program is shaping up well, and I’m excited about the conference.&lt;/p&gt;


	&lt;p&gt;If you’re looking for a combined technical and cultural education experience, I highly recommend going to RubyConf India.  Kelly and I &lt;a href=&quot;http://chadfowler.com/2009/8/2/how-learning-a-second-language-changed-my-life&quot;&gt;lived in Bangalore&lt;/a&gt; several years ago and absolutely loved it there. We can’t wait to get back to our second home. Bangalore was a culture shock at first, but that’s another strong reason to go. For us, it went from culture shock to comfort. Bangalore certainly didn’t change to make that happen—we did.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://rubyconfindia.org/stock/rubyconf-badges/RubyConf2010/270X185_speaking.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;So, while it’s hectic, noisy,  and sometimes shocking, Bangalore is a beautiful place which had a profound effect on me. When I was there, I couldn’t find any other Ruby programmers. It will be really exciting to go back to an entire conference devoted to Rubyists.&lt;/p&gt;


	&lt;p&gt;Registration will be opening in the next couple of weeks. Follow &lt;a href=&quot;http://twitter.com/rubyconfindia&quot;&gt;RubyConfIndia&lt;/a&gt; on twitter for announcements. Bangalore men milenge?&lt;/p&gt;</description>
	<pubDate>Mon, 25 Jan 2010 16:13:13 +0000</pubDate>
</item>
<item>
	<title>Ruby on Rails: Getting a New App Running on Edge</title>
	<guid isPermaLink="false">tag:weblog.rubyonrails.org,2010-01-01:26166</guid>
	<link>http://feedproxy.google.com/~r/RidingRails/~3/F7NEVNdLVpE/getting-a-new-app-running-on-edge</link>
	<description>&lt;p&gt;(cross-posted from &lt;a href=&quot;http://yehudakatz.com/2009/12/31/spinning-up-a-new-rails-app/&quot;&gt;Yehuda’s Blog&lt;/a&gt;)&lt;/p&gt;


	&lt;p&gt;So people have been attempting to get a Rails app up and running recently. I also have some apps in development on Rails 3, so I’ve been experiencing some of the same problems many others have.&lt;/p&gt;


	&lt;p&gt;The other night, I worked with &lt;a href=&quot;http://github.com/sferik&quot;&gt;sferik&lt;/a&gt; to start porting &lt;a href=&quot;http://github.com/sferik/merb-admin&quot;&gt;merb-admin&lt;/a&gt; over to Rails. Because this process involved being on edge Rails, we got the process honed to a very simple, small, repeatable process.&lt;/p&gt;


&lt;h2&gt;The Steps&lt;/h2&gt;

&lt;h3&gt;Step 1: Install bundler (version 0.8.1 required)&lt;/h3&gt;

&lt;pre&gt;$ sudo gem install bundler&lt;/pre&gt;

&lt;h3&gt;Step 2: Check out Rails&lt;/h3&gt;

&lt;pre&gt;$ git clone git://github.com/rails/rails.git
$ cd rails&lt;/pre&gt;

&lt;h3&gt;Step 3: Bundle Rails dependencies&lt;/h3&gt;

&lt;pre&gt;$ gem bundle --only default&lt;/pre&gt;

&lt;h3&gt;Step 4: Generate a new app&lt;/h3&gt;

&lt;pre&gt;$ ruby railties/bin/rails ../new_app --dev
$ cd ../new_app&lt;/pre&gt;

&lt;h3&gt;Done&lt;/h3&gt;

	&lt;p&gt;Everything should now work: &lt;code&gt;script/server&lt;/code&gt;, &lt;code&gt;script/console&lt;/code&gt;, etc.&lt;/p&gt;


	&lt;p&gt;When you execute &lt;code&gt;rails APP_NAME --dev&lt;/code&gt;, it will create a new Rails application with a Gemfile pointing to your Rails checkout and bundle it right after.&lt;/p&gt;


	&lt;p&gt;Also notice that in Step 3 we pass &lt;code&gt;--only default&lt;/code&gt; to the bundle command. This will skip bundling of both mysql and pg (for postgresql) gems.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;Updated on 01/15/2010&lt;/b&gt; – Rewrote steps to include &lt;code&gt;gem install bundler&lt;/code&gt; and use &lt;code&gt;rails APP_NAME --dev&lt;/code&gt;.&lt;/p&gt;</description>
	<pubDate>Fri, 15 Jan 2010 13:20:40 +0000</pubDate>
</item>
<item>
	<title>Ruby on Rails: Rails 3 Bugmash</title>
	<guid isPermaLink="false">tag:weblog.rubyonrails.org,2010-01-15:26177</guid>
	<link>http://feedproxy.google.com/~r/RidingRails/~3/iqJW0yJcXMk/rails-3-bugmash</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://railsbridge.org/&quot;&gt;RailsBridge&lt;/a&gt; has organized a Rails 3 Bugmash on January 16th and 17th. The idea is to try and upgrade your apps and favourite plugins/gems to work with Rails 3 and make the upgrade path as smooth as possible for everyone else by documenting the process and fixing the bugs you encounter. Rails core team and others will be around in #railsbridge to help out the participants during the bugmash. Check the &lt;a href=&quot;http://railsbridge.org/news_items/10&quot;&gt;RailsBridge announcement&lt;/a&gt; for more details.&lt;/p&gt;</description>
	<pubDate>Fri, 15 Jan 2010 12:12:45 +0000</pubDate>
</item>
<item>
	<title>Charles Oliver Nutter: Busy Week: JRuby with Android, Maven, Rake, C exts, and More!</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-20975090.post-6101950269326188393</guid>
	<link>http://blog.headius.com/2010/01/busy-week-jruby-with-android-maven-rake.html</link>
	<description>(How long has it been since I last blogged? Answer: a long time. I'll try to blog more frequently now that the (TOTALLY INSANE) fall conference season is over. Remind me to never have three conferences in a month ever again.)&lt;br /&gt;&lt;br /&gt;Hello friends! It's been a busy week! I thought I'd show some of what's happening with JRuby, so you know we're still here plugging away.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Android Update&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Earlier this week I helped Jan Berkel get the Ruboto IRB application working on a more recent JRuby build. There were a few minor tweaks needed, and Jan was interested in helping out, so I made the tweaks and added him as a committer.&lt;br /&gt;&lt;br /&gt;The Ruboto IRB project repository is here: &lt;a href=&quot;http://github.com/headius/ruboto-irb&quot;&gt;http://github.com/headius/ruboto-irb&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Lately my interest in JRuby on Android has increased. I realized very recently that JRuby is just about the only mainstream JVM languge that can create *new* code while running on the device, which opens up a whole host of possibilities. It is not possible to implement an interactive shell in Groovy or Scala or Clojure, for example, since they all must first compile code to JVM bytecode, and JVM bytecode can't run on the Dalvik VM directly.&lt;br /&gt;&lt;br /&gt;As I played with Ruboto IRB this week, I discovered something even more exciting: almost all the bugs that prevented JRuby from working well in early Android releases have been solved! Specifically, the inability to reflect any android.* classes seems to be fixed in both Android 1.6 and Android 2.0.x. Why is this so cool? It's cool because with Ruboto IRB you can interactively play with almost any Android API:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://img.skitch.com/20100108-1nr5rj4y7dpw4spfr9sf5w3ui3.jpg&quot;&gt;&lt;img src=&quot;http://img.skitch.com/20100108-1nr5rj4y7dpw4spfr9sf5w3ui3.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This example accesses the Activity (the IRB class in Ruboto IRB), constructs a new WebView, loads some HTML into it, and (not shown) replaces the content WebView. Interactively. On the device. Awesome.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://img.skitch.com/20100108-dagfkf1thqktftghpnaigxhus5.jpg&quot;&gt;&lt;img src=&quot;http://img.skitch.com/20100108-dagfkf1thqktftghpnaigxhus5.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I am trusting you to not go mad with power, and to use Ruboto only for good.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;RubyGems/Maven Integration&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;JRuby has always been a Ruby implementation first, and as a result we've often neglected Java platform integration. But with Ruby 1.8.7 compatibility very solid and Ruby 1.9 work under way, we've started to turn our attentions toward Java again.&lt;br /&gt;&lt;br /&gt;One of the key areas for language integration is tool support. And for Java developers, tool support invariably involves Maven.&lt;br /&gt;&lt;br /&gt;About a year ago, I started a little project to turn Maven artifacts into RubyGems. The mapping was straightforward: both have dependencies, a name, a description, a unique identifier, version numbers, and a standard file format for describing a given package. The maven_gem project was my proof-of-concept that it's possible to merge the two worlds.&lt;br /&gt;&lt;br /&gt;The maven_gem repository is here: &lt;a href=&quot;http://github.com/jruby/maven_gem&quot;&gt;http://github.com/jruby/maven_gem&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The project sat mostly dormant until I circled back to it this fall. But once I got the guys from Sonatype involved (purveyors of the Nexus Maven server) things really got interesting.&lt;br /&gt;&lt;br /&gt;Thanks to Tamas Cservenak from Sonatype, we now have something once thought impossible: full RubyGems integration of all the Maven artifacts in the world!&lt;br /&gt;&lt;br /&gt;The Nexus RubyGems support repository is here: &lt;a href=&quot;http://github.com/cstamas/nexus-ruby-support/&quot;&gt;http://github.com/cstamas/nexus-ruby-support/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;~/projects/jruby ➔ gem install com.lowagie.itext-rtf&lt;br /&gt;Successfully installed bouncycastle.bcmail-jdk14-138-java&lt;br /&gt;Successfully installed bouncycastle.bcprov-jdk14-138-java&lt;br /&gt;Successfully installed bouncycastle.bctsp-jdk14-138-java&lt;br /&gt;Successfully installed com.lowagie.itext-rtf-2.1.7-java&lt;br /&gt;4 gems installed&lt;br /&gt;Installing ri documentation for bouncycastle.bcmail-jdk14-138-java...&lt;br /&gt;Installing ri documentation for bouncycastle.bcprov-jdk14-138-java...&lt;br /&gt;Installing ri documentation for bouncycastle.bctsp-jdk14-138-java...&lt;br /&gt;Installing ri documentation for com.lowagie.itext-rtf-2.1.7-java...&lt;br /&gt;Installing RDoc documentation for bouncycastle.bcmail-jdk14-138-java...&lt;br /&gt;Installing RDoc documentation for bouncycastle.bcprov-jdk14-138-java...&lt;br /&gt;Installing RDoc documentation for bouncycastle.bctsp-jdk14-138-java...&lt;br /&gt;Installing RDoc documentation for com.lowagie.itext-rtf-2.1.7-java...&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's a an example of a full session, where I additionally install Rhino and then use it from IRB: &lt;a href=&quot;http://gist.github.com/271764&quot;&gt;http://gist.github.com/271764&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I should reiterate what this means for JRuby users: as of JRuby 1.5, you'll be able to install or use in dependencies any Java library ever published to the public Maven repository. In short, you now have an additional 60000-some libraries at your fingertips. Awesome, no?&lt;br /&gt;&lt;br /&gt;There are some remaining issues to work through, like the fact that RubyGems itself chokes on that many gems when generating indexes, but there's a test server up and working. We'll get all the issues resolved by the time we release JRuby 1.5 RC1. Jump on the JRuby mailing list if you're like to discuss this new capability.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Rake? Ant? Why not Both?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Another item on the integration front is Tom Enebo's work on providing seamless two-way integration of Rake (Ruby's build tool) and Ant. There's three aspects to Rake/Ant integration:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Using Rake tasks from Ant and Ant tasks from Rake&lt;/li&gt;&lt;li&gt;Calling Rake targets from Ant and Ant targets from Rake&lt;/li&gt;&lt;li&gt;Mixed build systems with part in Rake and part in Ant&lt;/li&gt;&lt;/ul&gt;Tom's work so far has focused on the first bullet, but the other two will come along as well. You'll be able to translate your Ant script to Rake and have it work without modification, call out to Rake from Ant, include a Rakefile in Ant and use its targets, and so on.&lt;br /&gt;&lt;br /&gt;Here's an example of pulling in a build.xml file, depending on its targets, and calling Ant tasks from Rake:&lt;br /&gt;&lt;pre&gt;require 'ant'&lt;br /&gt;&lt;br /&gt;ant.load 'build.xml' # defines tasks :mkdir + :setup in ant!&lt;br /&gt;&lt;br /&gt;task :compile =&gt; [:mkdir, :setup] do&lt;br /&gt;  ant.javac(:srcdir =&gt; src_dir, :destdir =&gt; &quot;./build/classes&quot;) do&lt;br /&gt;    classpath :refid =&gt; &quot;project.class.path&quot; &lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;Ideally we'll cover all possible integration scenarios, and finally blur the lines between Rake and Ant. And we'll be able to move JRuby's build into Rake, which will make all of us very happy. Look forward to this in JRuby 1.5 as well.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;The C Extension Question&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One aspect of Ruby itself that we've punted on is support for Ruby's C extension API. We haven't done that to spite C extension users or developers--far from it...we'd love to flip a switch and have C extensions magically work. The problem is that Ruby's C API provides too-invasive access to the internals of objects, and there's just no way we can support that sort of access without incurring a massive overhead (because we'd have to copy stuff back and forth for every operation).&lt;br /&gt;&lt;br /&gt;But there's another possibility we've started to explore: supporting only a &quot;safe&quot; subset of the Ruby C API, and providing a few additional functions to replace the &quot;unsafe&quot; invasive bits. To that end, we (as in Wayne Meissner, creator of the FFI implementations for JRuby and Ruby) have cleaned up and published a C extension API shim library to Github.&lt;br /&gt;&lt;br /&gt;The JRuby C extension shim library repository is here: &lt;a href=&quot;http://github.com/wmeissner/jruby-cext&quot;&gt;http://github.com/wmeissner/jruby-cext&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Last night I spent some time getting this building and working on OS X, and to my surprise I was able to get a (very) trivial C extension to work!&lt;br /&gt;&lt;br /&gt;Here's the part in C. Note that this is identical to what you'd write if you were implementing the extension for Ruby:&lt;br /&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;ruby.h&amp;gt;&lt;br /&gt; &lt;br /&gt;VALUE HelloModule = Qnil;&lt;br /&gt;VALUE HelloClass = Qnil;&lt;br /&gt; &lt;br /&gt;VALUE say_hello(VALUE self, VALUE hello);&lt;br /&gt;VALUE get_hello(VALUE self);&lt;br /&gt; &lt;br /&gt;void&lt;br /&gt;Init_defineclass()&lt;br /&gt;{&lt;br /&gt;    HelloClass = rb_define_class(&quot;Hello&quot;, rb_cObject);&lt;br /&gt;    rb_define_method(HelloClass, &quot;get_hello&quot;, get_hello, 0);&lt;br /&gt;    rb_define_method(HelloClass, &quot;say_hello&quot;, say_hello, 1);&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;VALUE&lt;br /&gt;say_hello(VALUE self, VALUE hello)&lt;br /&gt;{&lt;br /&gt;    return Qnil;&lt;br /&gt;}&lt;br /&gt;VALUE&lt;br /&gt;get_hello(VALUE self)&lt;br /&gt;{&lt;br /&gt;    return rb_str_new2(&quot;Hello, World&quot;);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Here's the little snippit of Ruby code that loads and calls it. Note that the ModuleLoader logic would be hidden behind require/load in a final version of the C extension support.&lt;br /&gt;&lt;pre&gt;require 'java'&lt;br /&gt; &lt;br /&gt;m = org.jruby.cext.ModuleLoader.new&lt;br /&gt;m.load(self, &quot;defineclass&quot;)&lt;br /&gt; &lt;br /&gt;h = Hello.new&lt;br /&gt;puts &quot;Hello.new returned #{h.inspect}&quot;&lt;br /&gt;puts &quot;h.get_hello returns #{h.get_hello}&quot;&lt;/pre&gt;&lt;br /&gt;Among the C API pieces we probably won't ever support are things like RSTRING, RARRAY, RHASH that give direct access to string, array, and hash internals, anything dealing with Ruby's threads or runtime, and so on. Basically the pieces that don't fit well into JNI (the Java VM C API) would not be supported.&lt;br /&gt;&lt;br /&gt;It's also worth mentioning that this is really a user-driven venture. If you are interested in a C extension API for JRuby, then you'll need to help us get there. Not only are we plenty busy with Java and Ruby support, we are also not extension authors ourselves. Have a look at the repository, hop on the JRuby dev list, and we'll start collaborating.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;JRuby in 2010&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There's a lot more coming for JRuby in 2010. We're going to finally let you create &quot;real&quot; Java classes from Ruby code that you can compile against, serialize, annotate, and specify in configuration files. We're going to offer JRuby development support to help prioritize and accelerate bug fixes for commercial users that really need them. We're going to have a beautiful, simple deployment option in Engine Yard Cloud, with fire-and-forget for your JRuby-based applications (including any non-Ruby libraries and code you might use like Java, Scala or Clojure). And we're going to finally publish a JRuby book, with all the walkthroughs, reference material, and troubleshooting tips you'll need to adopt JRuby today.&lt;br /&gt;&lt;br /&gt;It's going to be a great year...and a lot of fun.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/20975090-6101950269326188393?l=blog.headius.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 08 Jan 2010 17:15:49 +0000</pubDate>
	<author>headius@headius.com (Charles Oliver Nutter)</author>
</item>
<item>
	<title>Phil Hagelberg: in which persistence proves a propitious property</title>
	<guid isPermaLink="false">tag:technomancy.us,2007:in%20which%20persistence%20proves%20a%20propitious%20property</guid>
	<link>http://technomancy.us/132</link>
	<description>&lt;p&gt;When you read about functional languages, one of the things that
  frequently comes up is the value of persistent data structures. If
  you come from an OOP background where persistent means &quot;it gets
  saved to disk&quot;, this is a little confusing until you do a little
  digging to find out it's a different meaning of the word
  persistent; you discover that it just means the data structures
  are immutable. This is technically true; all persistent data
  structures are immutable. But this understanding is a little bit
  lacking&amp;mdash;it doesn't really get at the meaning of
  persistent.&lt;/p&gt;

&lt;p&gt;The point of persistence in this case is that future versions of
  the object in question can be created without changing either the
  value &lt;b&gt;or&lt;/b&gt; the performance characteristics of the existing
  instance. So when you've got a vector that you want to work with,
  you can create another vector based on the original, but with a
  few new items added to it. In languages that provide persistent
  data structures this is done without copying; internally the
  portions of the vector that are the same use a shared
  structure. But there are some pseudo-persistent implementations
  that cheat; as you create more and more versions based on the
  original vector, the performance of the original degrades even
  though the value is preserved. This is avoided in true persistent
  implementations such as Clojure's.&lt;/p&gt;

&lt;p&gt;The other important thing about understanding persistence is
  understanding what it's not. A new feature in Clojure 1.1 is the
  addition of &lt;a href=&quot;http://clojure.org/transients&quot;&gt;transient&lt;/a&gt;
  data structures. Transients provide speed boosts in cases where
  you decide performance is more important than persistence by using
  mutable data structures in a controlled, thread-safe way. If you
  don't understand what persistence means then you might see the
  fact that they are mutable and use them as you would in an
  imperative language&amp;mdash;but that's not what they're meant for!
  The key to understanding transients is not that they're mutable
  but that they're &lt;i&gt;not persistent&lt;/i&gt;. The fact that they are
  mutable is an implementation detail; you should treat them like
  regular immutable data structures, you just shouldn't rely on
  their persistent qualities.&lt;/p&gt;

&lt;p&gt;Focusing on immutability is focusing on the negative: what
  you &lt;i&gt;can't&lt;/i&gt; do. Thinking in terms of persistence is focusing
  on the positive: there are a certain set of guarantees that we may
  rely on. If you decide in some cases to give up those guarantees
  for speed benefits, transients allow you to do that, but you
  shouldn't think of them as your old imperative friends you can
  alter as you wish.&lt;/p&gt;</description>
	<pubDate>Tue, 22 Dec 2009 15:14:16 +0000</pubDate>
</item>
<item>
	<title>Ruby Extensions: Immediate values</title>
	<guid isPermaLink="false">urn:uuid:c3b45396-38bb-4d1b-ba7f-6f010057ad40</guid>
	<link>http://rubyextensions.com/2009/12/14/immediate-values</link>
	<description>&lt;p&gt;A few weeks ago I came across François Lamontagne's &lt;a href=&quot;http://www.rubyfleebie.com/ruby-and-c-part-1/&quot;&gt;&quot;Ruby and C : Part 1&quot;&lt;/a&gt; post.  He talks about the &lt;code&gt;VALUE&lt;/code&gt; type in Ruby and how that's typedef'd to an &lt;code&gt;unsigned long&lt;/code&gt;.  You can see this in ruby.h; in ruby 1.8.6 p369 it's line 86:&lt;/p&gt;

&lt;pre&gt;
typedef unsigned long VALUE;
&lt;/pre&gt;

&lt;p&gt;One interesting thing that François' article notes is that VALUE can contain either a pointer to the data or the data itself.  You can see this in Aman Gupta's latest post to &lt;a href=&quot;http://timetobleed.com/what-is-a-ruby-object-introducing-memprof-dump/&quot;&gt;Time to Bleed&lt;/a&gt;.  In one example he creates an Array containing a few Fixnums and a String and then dumps the heap using &lt;a href=&quot;http://github.com/ice799/memprof&quot;&gt;memprof&lt;/a&gt;.  This yields:&lt;/p&gt;

&lt;pre&gt;
  {
    &quot;type&quot;: &quot;array&quot;,
    &quot;length&quot;: 4,
    &quot;data&quot;: [
      1,
      2,
      3,
      &quot;0x12aa0c0&quot;
    ]
  }
&lt;/pre&gt;

&lt;p&gt;So the three Fixnums are stored as immediate values, and the last value is the pointer to the String.&lt;/p&gt;

&lt;p&gt;What other Ruby types are stored as immediate values?  From ruby.h around line 697 in the &lt;code&gt;rb_type&lt;/code&gt; function:&lt;/p&gt;

&lt;pre&gt;
    if (FIXNUM_P(obj)) return T_FIXNUM;
    if (obj == Qnil) return T_NIL;
    if (obj == Qfalse) return T_FALSE;
    if (obj == Qtrue) return T_TRUE;
    if (obj == Qundef) return T_UNDEF;
    if (SYMBOL_P(obj)) return T_SYMBOL;
&lt;/pre&gt;

&lt;p&gt;Looks like Fixnums, Nil, False, True, and Symbols.  Everything else gets identified using the &lt;code&gt;BUILTIN_TYPE&lt;/code&gt; macro.   The Ruby 1.9.1 code looks kind of similar, although it uses different macros (like &lt;code&gt;RTEST&lt;/code&gt;) and does the comparisons in a different order.&lt;/p&gt;</description>
	<pubDate>Tue, 15 Dec 2009 02:38:00 +0000</pubDate>
	<author>tom@infoether.com (Tom Copeland)</author>
</item>
<item>
	<title>Ruby on Rails: Ruby on Rails 2.3.5 Released</title>
	<guid isPermaLink="false">tag:weblog.rubyonrails.org,2009-11-30:26095</guid>
	<link>http://feedproxy.google.com/~r/RidingRails/~3/flj7DQOLfjE/ruby-on-rails-2-3-5-released</link>
	<description>&lt;p&gt;Rails 2.3.5 was released over the weekend which provides several bug-fixes and one &lt;a href=&quot;http://groups.google.com/group/rubyonrails-security/browse_thread/thread/4d4f71f2aef4c0ab&quot;&gt;security fix&lt;/a&gt;. It should be fully compatible with all prior 2.3.x releases and can be easily upgraded to with “gem update rails”.  The most interesting bits can be summarized in three points.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Improved compatibility with Ruby 1.9&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;There were a few small bugs preventing full compatibility with Ruby 1.9.  However, we wouldn’t be surprised you were already running Rails 2.3.X successfully before these bugs were fixed (they were small).&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;RailsXss plugin availability&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;As you may have heard, in Rails 3 we are now automatically escaping all string content in erb (where as before you needed to use “h()” to escape).  If you want to have this functionality today you can install Koz’s &lt;a href=&quot;http://github.com/nzkoz/rails_xss&quot;&gt;RailsXss plugin&lt;/a&gt; in Rails 2.3.5.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Fixes for the Nokogiri backend for XmlMini&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;With Rails 2.3 we were given the ability to switch out the default &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; parser from &lt;span class=&quot;caps&quot;&gt;REXML&lt;/span&gt; to other faster parsers like Nokogiri.  There were a few issues with using Nokogiri which are now resolved, so if your application is parsing lots of xml you may want to switch to this faster &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; parser.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;And that’s the gist of it&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Feel free to browse through the &lt;a href=&quot;http://github.com/rails/rails/commits/v2.3.5/&quot;&gt;commit history&lt;/a&gt; if you’d like to see what else has been fixed (but it’s mostly small stuff).&lt;/p&gt;</description>
	<pubDate>Mon, 30 Nov 2009 19:58:33 +0000</pubDate>
</item>
<item>
	<title>Jim Weirich: Now Using Pivotal Tracker</title>
	<guid isPermaLink="false">http://onestepback.org/index.cgi/News/PivotalTracker.red</guid>
	<link>http://onestepback.org/index.cgi/News/PivotalTracker.red</link>
	<description>&lt;p&gt;&lt;em&gt;I&amp;#8217;m switching from self-hosting Redmine to using Pivotal
Tracker for issue tracking on my Open Source projects.&lt;/em&gt;&lt;/p&gt;


	&lt;h2&gt;Switching to Pivotal Tracker&lt;/h2&gt;


	&lt;p&gt;After running Redmine locally for a while, I&amp;#8217;ve decided to switch to a
hosted issue tracking service.  I&amp;#8217;ve moved all the open tickets on the
onestepback.org Redmine app to my account on Pivotal Tracker.&lt;/p&gt;


	&lt;h2&gt;Current Project Links&lt;/h2&gt;


	&lt;p&gt;Here are the links to my current projects:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.pivotaltracker.com/projects/28469&quot;&gt;Rake&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.pivotaltracker.com/projects/28401&quot;&gt;FlexMock&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.pivotaltracker.com/projects/29210&quot;&gt;Builder&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.pivotaltracker.com/projects/42967&quot;&gt;TExp&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.pivotaltracker.com/projects/36147&quot;&gt;Given&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;All the projects are marked public so you should be able to view
the projects (and subscribe to an &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; feed) without actually signing
up for anything.&lt;/p&gt;


	&lt;h2&gt;Did I miss anything?&lt;/h2&gt;


	&lt;p&gt;All the open tickets should be migrated to Pivotal Tracker.  If you
notice anything missing, let me know.  Thanks.&lt;/p&gt;</description>
	<pubDate>Mon, 30 Nov 2009 18:00:44 +0000</pubDate>
</item>
<item>
	<title>Evan Phoenix: Helpful syntax errors</title>
	<guid isPermaLink="false">http://blog.fallingsnow.net/?p=97</guid>
	<link>http://blog.fallingsnow.net/2009/11/29/helpful-syntax-errors/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;Syntax errors are a part of life for programmers. The language of the computer, no matter how flexible the language, is very picky.&lt;/p&gt;
&lt;p&gt;And thus how the language communicates back to the user about what it didn&amp;#8217;t understand is important, because time is spent in this phase, no matter the skill level of the programmer.&lt;/p&gt;
&lt;p&gt;In Ruby specifically, MRI&amp;#8217;s parser (and by extension the melbourne parser Rubinius uses) use yacc, and thus suffer from syntax errors which can be particularly difficult to understand. One particular syntax error that commonly occurs is when there is an &amp;#8216;end&amp;#8217; missing from an expression. This results in the dreaded &lt;em&gt;&lt;b&gt;syntax error, unexpected $end, expecting kEND&lt;/b&gt;&lt;/em&gt; message.&lt;/p&gt;
&lt;p&gt;Here is a quick example:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
class Spaghetti
  class Sause
     def add(plate)
        while more?
           plate &amp;lt;&amp;lt; self
     end
  end
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Now, this is a short example and so spotting the error is fairly easy. But this error typically occurs when you&amp;#8217;re working on a 600 line file with multiple classes inside classes and with complicated logic, making it quite difficult to find.&lt;/p&gt;
&lt;p&gt;This evening, I decided to try and at least help make this easier to find. So now in Rubinius, rather than&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;b&gt;syntax error, unexpected $end, expecting kEND&lt;/b&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;you get&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;b&gt;missing &amp;#8216;end&amp;#8217; for &amp;#8216;class&amp;#8217; started on line 1&lt;/b&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Thats a big improvement, because now first off, it&amp;#8217;s fairly clearly communicated what is wrong, i.e. that you&amp;#8217;ve forgotten an &amp;#8216;end&amp;#8217;. In addition, it tells you what element still required a &amp;#8216;end&amp;#8217;, in this case, a &amp;#8216;class&amp;#8217; on line 1.&lt;/p&gt;
&lt;p&gt;Now, this is far from perfect. It&amp;#8217;s pointing you to the element that was unclosed, rather than the one that you actually forgot the &amp;#8216;end&amp;#8217; on. But it at least is now pointing you to the chunk of code that is the offending code. In practice, this can be a big help.&lt;/p&gt;
&lt;p&gt;In the future, it might be possible to try and use indentation to try and narrow down where the missing &amp;#8216;end&amp;#8217; should be. But for now, every little bit helps.&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/evanphx.wordpress.com/97/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/evanphx.wordpress.com/97/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/evanphx.wordpress.com/97/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/evanphx.wordpress.com/97/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/evanphx.wordpress.com/97/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/evanphx.wordpress.com/97/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/evanphx.wordpress.com/97/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/evanphx.wordpress.com/97/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/evanphx.wordpress.com/97/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/evanphx.wordpress.com/97/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blog.fallingsnow.net&amp;amp;blog=1516804&amp;amp;post=97&amp;amp;subd=evanphx&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 30 Nov 2009 05:39:21 +0000</pubDate>
</item>
<item>
	<title>Phil Hagelberg: in which projects may be more easily compiled and distributed</title>
	<guid isPermaLink="false">tag:technomancy.us,2007:in%20which%20projects%20may%20be%20more%20easily%20compiled%20and%20distributed</guid>
	<link>http://technomancy.us/131</link>
	<description>&lt;a href=&quot;http://www.flickr.com/photos/31151628@N03/4010921064/&quot;&gt;&lt;img src=&quot;http://technomancy.us/i/leiningen.jpg&quot; alt=&quot;leiningen portrait&quot; align=&quot;right&quot; /&gt;&lt;/a&gt;
&lt;p&gt;So build tools have been a long-standing pain point when working
  on Clojure projects. Most projects have used JVM-centric tools
  like ant or maven, which are far more complicated than what you
  need to build Clojure, and on top of that must be configured with
  XML. It could be made to work, and in the case of projects with
  significant dependencies it was much better than doing it by hand,
  but it was a pain.&lt;/p&gt;

&lt;p&gt;Last week I
  launched &lt;a href=&quot;http://github.com/technomancy/leiningen&quot;&gt;Leiningen&lt;/a&gt;,
  which is a project that brings a native build tool to Clojure. It
  seems to have people pretty excited about it, which leads me to
  believe I'm far from the only one who's been feeling the pain
  here. It's configured using a Clojure file called project.clj like
  the sample below.&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;&lt;span class=&quot;esk-paren&quot;&gt;(&lt;/span&gt;defproject leiningen &lt;span class=&quot;string&quot;&gt;&quot;1.0.0-SNAPSHOT&quot;&lt;/span&gt;
  &lt;span class=&quot;builtin&quot;&gt;:description&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;A build tool designed not to set your hair on fire.&quot;&lt;/span&gt;
  &lt;span class=&quot;builtin&quot;&gt;:main&lt;/span&gt; leiningen.core
  &lt;span class=&quot;builtin&quot;&gt;:dependencies&lt;/span&gt; [[org.clojure/clojure &lt;span class=&quot;string&quot;&gt;&quot;1.1.0-alpha-SNAPSHOT&quot;&lt;/span&gt;]
                 [org.clojure/clojure-contrib &lt;span class=&quot;string&quot;&gt;&quot;1.0-SNAPSHOT&quot;&lt;/span&gt;]
                 [ant/ant-launcher &lt;span class=&quot;string&quot;&gt;&quot;1.6.2&quot;&lt;/span&gt;]
                 [org.apache.maven/maven-ant-tasks &lt;span class=&quot;string&quot;&gt;&quot;2.0.10&quot;&lt;/span&gt;]]
  &lt;span class=&quot;builtin&quot;&gt;:dev-dependencies&lt;/span&gt; [[org.clojure/swank-clojure &lt;span class=&quot;string&quot;&gt;&quot;1.0&quot;&lt;/span&gt;]]&lt;span class=&quot;esk-paren&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;

&lt;h3&gt;Testing&lt;/h3&gt;

&lt;p&gt;This one's pretty straightforward: &lt;kbd&gt;lein test&lt;/kbd&gt; searches
  the test/ directory for namespaces and runs the tests in each.&lt;/p&gt;

&lt;h3&gt;Building&lt;/h3&gt;

&lt;p&gt;Running &lt;kbd&gt;lein jar&lt;/kbd&gt; will compile your code and package it
  up as a .jar file. If you specify a &lt;code&gt;:main&lt;/code&gt; class in
  your project config, this will be an executable jar with the class
  you specified. If you just want to compile your code, there's
  a &lt;kbd&gt;compile&lt;/kbd&gt; task for that too. Alternatively if you want
  to build a standalone jar that includes all your project's
  dependencies for easier distribution, you can do that
  with &lt;kbd&gt;lein uberjar&lt;/kbd&gt;.&lt;/p&gt;

&lt;h3&gt;Dependency Management&lt;/h3&gt;

&lt;p&gt;This is the fun part. Rather than tracking down and downloading
  all your dependency jars manually (or worse: &lt;i&gt;checking them
  in&lt;/i&gt; to your source repository), Leiningen provides
  a &lt;kbd&gt;deps&lt;/kbd&gt; task to automatically download them and place
  them in the lib/ directory. This uses some Maven code under the
  covers, but don't panic&amp;mdash;you won't have to see a bit of XML
  unless you want to. It pulls from the central Maven repositories
  by default as well as
  from &lt;a href=&quot;http://build.clojure.org&quot;&gt;Clojure's nightly builds&lt;/a&gt;
  and &lt;a href=&quot;http://clojars.org&quot;&gt;http://clojars.org&lt;/a&gt;. Clojars
  has built-in search, but if you want to pull a library from the
  central repository, you can search for it
  on &lt;a href=&quot;http://jarvana.com&quot;&gt;Jarvana&lt;/a&gt;. You can also specify
  development dependencies with the &lt;code&gt;:dev-dependencies&lt;/code&gt;
  key for things that shouldn't be pulled in at production or
  included in the standalone jar; the syntax is the same.&lt;/p&gt;

&lt;h3&gt;Publishing with Clojars&lt;/h3&gt; &lt;p&gt;By a stroke of luck I dropped
hints about Leiningen the week before I made a public announcement
only to find out that Alex Osborne was approaching the same problem
from the other direction.  He'd been cooking up a web site and
service for hosting Clojure libraries independently of my work on
Leiningen, and we started talking about ways to integrate the
two. So now Leiningen makes it easy to publish jars publicly via
Clojars so other projects can depend on them. The day after
announcing Clojars, Alex was &lt;a href=&quot;http://www.infoq.com/news/2009/11/clojars-leiningen-clojure&quot;&gt;interviewed
on InfoQ&lt;/a&gt; about the site and how it interacts with Leiningen, so
I was thrilled to see both our projects getting exposure so
quickly.&lt;/p&gt;

&lt;h3&gt;Coming Soon...&lt;/h3&gt; &lt;p&gt;Soon after the 0.5.0 release, Alex along
with Dan Larkin (of the wonderful &lt;a href=&quot;http://github.com/danlarkin/clojure-json&quot;&gt;Clojure JSON
library&lt;/a&gt; fame) started diving in and adding
features. &lt;strike&gt;We've got &lt;a href=&quot;http://github.com/technomancy/leiningen/blob/master/todo.org&quot;&gt;a
few more tasks&lt;/a&gt; on the plate targeted for a 1.0 release, but
should be right around the corner.&lt;/strike&gt; &lt;b&gt;Update&lt;/b&gt;: &lt;a href=&quot;http://github.com/technomancy/leiningen/blob/1.0.0/NEWS&quot;&gt;Leiningen
1.0 released&lt;/a&gt;. If you'd like to say hi or drop a line, there's
a #leiningen channel on freenode as well as a &lt;a href=&quot;http://groups.google.com/group/leiningen&quot;&gt;mailing
list&lt;/a&gt;. If you found this useful, you should take a look at the &lt;a href=&quot;http://peepcode.com/products/functional-programming-with-clojure&quot;&gt;Clojure PeepCode screencast&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Logo
by &lt;a href=&quot;http://lorenbroach.blogspot.com/&quot;&gt;Loren Broach&lt;/a&gt;.&lt;/p&gt;
&lt;!-- TODO: note that some tasks implicitly call others --&gt;</description>
	<pubDate>Wed, 25 Nov 2009 22:28:10 +0000</pubDate>
</item>
<item>
	<title>Vladimir Sizikov: Making Sense out of Slow Rubygems Startup</title>
	<guid isPermaLink="false">http://blog.emptyway.com/2009/11/21/making-sense-out-of-slow-rubygems-startup/</guid>
	<link>http://blog.emptyway.com/2009/11/21/making-sense-out-of-slow-rubygems-startup/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://jruby.org/&quot; target=&quot;_blank&quot;&gt;JRuby&lt;/a&gt; is pretty fast these days, in most cases it is faster than MRI. JRuby is especially good at handling long-lasting repeating tasks (on server side). But one thing where JRuby is not blazingly fast is during the startup. Well, actually, JRuby starts up within 0.5 second, which is really nice for the JVM-based implementation. But as soon as rubygems comes into play, the situation gets worse.&lt;/p&gt;
&lt;p&gt;So, I spent some time trying to understand why just loading the rubygems package eats up a second or two more. Well, it turned out that rubygems loads almost entire standard library, which is crazy! Sure, this is a bit of exaggeration, but still, let’s see, shall we?&lt;/p&gt;
&lt;p&gt;First, fileutils are loaded, 100+ms passed, then rubygems tries to figure out where is the system-level config file, and for that on Windows it uses Win32API library (!!!), which in turn requires FFI (the native interface). Ka-ching, 300+ ms for that. Then, we need to read the configs and stuff, this requires YAML parser, and in JRuby that means loading Yecht, 350+ ms more. Next, JRuby provides some extension of rubygems functionality, like possibility to load gems from the JAR files, and for that we need some classpath magic and the ‘uri’ library. To obtain the JRuby’s classloader, we need to require ‘jruby’, which in turn requires ‘java’, and the java library loads the whole bunch of extra functionality (which we are not using here, btw), that adds up to 400 ms. So, we barely loaded the rubygems library, but already consumed 1200ms of time, or more.&lt;/p&gt;
&lt;p&gt;Take a look at the following picture that shows the times to load all those libraries:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.emptyway.com/wp-content/uploads/Rubygems.jpg&quot;&gt;&lt;img title=&quot;Rubygems&quot; border=&quot;0&quot; alt=&quot;Rubygems&quot; src=&quot;http://blog.emptyway.com/wp-content/uploads/Rubygems_thumb.jpg&quot; width=&quot;617&quot; height=&quot;407&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you see, loading rubygems themselves is not that time consuming, most of the time is spent in loading the dependencies. There are some low-hanging fruits here, like lazily loading the ‘uri’ library. I also don’t like that rubygems loads the Win32API and the whole FFI stuff, removing that would also eliminate quite a lot of startup time. Loading the whole bunch of java integration magic in order to only be able to obtain the JRuby classpath also seems to be overkill. All those tweaks, if implemented, might actually cut the rubygems startup time in half. We’ll see.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; Wayne Meissner has just tweaked the loading of Win32API, and I adjusted JRuby-specific rubygems tweaks to lazily load the ‘uri’. So, the loading of rubygems is already about 200ms faster than it was yesterday! &lt;img src=&quot;http://blog.emptyway.com/wp-includes/images/smilies/icon_cool.gif&quot; alt=&quot;8-)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE#2:&lt;/strong&gt; Here’s the log of rubygems loading timings in JRuby, in easy to read text format: &lt;a title=&quot;http://gist.github.com/240322&quot; href=&quot;http://gist.github.com/240322&quot;&gt;http://gist.github.com/240322&lt;/a&gt;.&lt;/p&gt;</description>
	<pubDate>Sat, 21 Nov 2009 17:29:17 +0000</pubDate>
</item>

</channel>
</rss>
