<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6608275468089048982</id><updated>2012-01-31T11:02:54.033-08:00</updated><category term='ruby'/><category term='rubykaigi'/><category term='euruko'/><category term='inheritance'/><category term='technology'/><category term='bundler'/><category term='tools'/><category term='travis'/><category term='build'/><category term='2011'/><category term='development'/><category term='microsoft'/><category term='metaprogramming'/><category term='github'/><category term='modules'/><category term='language'/><category term='conference'/><category term='book'/><category term='presentation'/><title type='text'>Duck Typo</title><subtitle type='html'>This is your brain on software.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-181539875781886305</id><published>2011-10-11T08:32:00.000-07:00</published><updated>2011-10-11T11:28:01.620-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>Is Windows 8 solving the wrong problem?</title><content type='html'>In the 80s and the 90s, we had a Holy Grail: cross-platform compatibility. We wanted to write our software once, and then run it on different platforms. It felt like a good dream to share: it wasn't pretty to rewrite the same stuff over and over. If your company wanted to support Windows and Apple, then you needed two separate teams writing the same application for two separate OSs. That felt like a huge waste.&lt;br /&gt;&lt;br /&gt;We tried hard. We looked at every C compiler flaunting cross-compilation, every database driver promising vendor independency, every high-level approach touting push-button code generation. The more these solutions became sophisticated, the less they seemed to work.&lt;br /&gt;&lt;br /&gt;We blamed Microsoft, Oracle and other corporate lockers-in for that sorry state of affairs. We were wrong. As it turned out, we were just trying to solve the wrong problem.&lt;br /&gt;&lt;br /&gt;The real problem was not a technological issue: it was a usability issue, a culture issue, and a marketing issue. Different platforms approach the same domains differently, and their relative value lies in those differences, not in the common denominator. At one point, Java managed to solve the technological problem for good, and that was the point where we realized the awful truth: cross-platform compatibility &lt;i&gt;was not important&lt;/i&gt;. It never had been.&lt;br /&gt;&lt;br /&gt;So we quit trying to solve that problem. Instead, we left it behind by moving up a level and inventing a new, shared platform on the Web. (I still see companies pursuing push-button tools that generate or translate code for the CLR and JVM alike. That saddens me: somebody is still working on the wrong problem.)&lt;br /&gt;&lt;br /&gt;Now, as it happens in IT, we're running another iteration of facing the same issues and making the same mistakes. We have multiple devices (PCs, smartphones, tablets), so we'd like to use the same software all over the spectrum. That's where Windows 8 &lt;a href="http://www.informationweek.com/news/windows/microsoft_news/229900100"&gt;seems to be going&lt;/a&gt;: you have the same OS on your tablet and your PC, so you can leverage the same technologies on both. And once again, this isn't going to work, because a tablet and a PC are different, and all those subtle and not-so-subtle differences pile up to require different approaches. Convergence is not important, interoperability is. Broad commonalities are not important, tiny details are. And please, Microsoft, get over it: the OS is not important, the user experience is.&lt;br /&gt;&lt;br /&gt;That's why I think that Windows' current approach to tablets and smartphones is fundamentally, tragically, so-fucking-broken-it-cannot-be-fixed wrong.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-181539875781886305?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/181539875781886305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2011/10/is-windows-8-solving-wrong-problem.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/181539875781886305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/181539875781886305'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2011/10/is-windows-8-solving-wrong-problem.html' title='Is Windows 8 solving the wrong problem?'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-5380847725120480589</id><published>2011-08-09T10:05:00.000-07:00</published><updated>2011-08-09T18:10:22.945-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='bundler'/><category scheme='http://www.blogger.com/atom/ns#' term='build'/><category scheme='http://www.blogger.com/atom/ns#' term='travis'/><title type='text'>Get Your Ruby Project on Travis and Have a Martini in 15 Minutes</title><content type='html'>Almost overnight, &lt;a href="http://travis-ci.org/#%21/rails/rails"&gt;every&lt;/a&gt; &lt;a href="http://travis-ci.org/#%21/sinatra/sinatra"&gt;Ruby&lt;/a&gt; &lt;a href="http://travis-ci.org/#%21/rspec/rspec-core"&gt;project&lt;/a&gt; out there seem to be moving to &lt;a href="http://travis-ci.org/"&gt;Travis&lt;/a&gt;. Travis is a dead-simple, community-owned &lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;build system&lt;/a&gt;. I'm usually too lazy to put all my projects on automated build. Travis took away my excuses by getting me from zero to the first build in a matter of minutes.&lt;br /&gt;&lt;br /&gt;Here are step-by-step instructions to get your project on Travis &lt;i&gt;and&lt;/i&gt; have a delicious Martini Cocktail in about 15 minutes. Please note that preparing the Martini will take about 5 minutes, so the Travis part should take just 10 minutes of your life.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Check That Your Project Has What It Takes &lt;i&gt;(2 minutes)&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Your project needs three prerequisites to get on Travis:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It's a Ruby project on GitHub.&lt;/li&gt;&lt;li&gt;It uses &lt;a href="http://ducktypo.blogspot.com/2010/12/bundler-how-you-can-start-using-it.html"&gt;Bundler&lt;/a&gt; to manage its gems. (Actually, that’s not strictly necessary, but it will make it easier to set up Travis.)&lt;/li&gt;&lt;li&gt;You can run the project's tests with a single command. A &lt;a href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt; task is typical, but other commands (like, say, &lt;i&gt;bundle exec rspec spec&lt;/i&gt;) are also fine.&lt;/li&gt;&lt;/ol&gt;Ultimately, you should be able to test your project on a new machine by just doing a &lt;i&gt;bundle install&lt;/i&gt; followed by the test command. If your setup is more complicated, then you'll need extra work to put the project on Travis. It's probably a good idea to make your project very easy to setup, whether or not you want to use Travis.&lt;br /&gt;&lt;br /&gt;I’ll assume that your project meets the three prerequisites, and that you can run your test with &lt;i&gt;bundle exec rake test&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Create a Travis Configuration File &lt;i&gt;(3 minutes)&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Commit a new file named &lt;i&gt;.travis.yml&lt;/i&gt; in your project root. Here is what mine looks like:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/1134203.js"&gt;&lt;/script&gt;&lt;br /&gt;All the entries have sensible defaults, so your configuration could be even simpler. For example, if you skip the &lt;i&gt;script&lt;/i&gt; property, then Travis will try &lt;i&gt;bundle exec rake&lt;/i&gt;, or just &lt;i&gt;rake&lt;/i&gt; if you're not using Bundler. You can find more details on &lt;a href="http://about.travis-ci.org/docs/user/build-configuration/"&gt;the Travis configuration page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Activate Your Project on Travis &lt;i&gt;(2 minutes)&lt;/i&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Go to &lt;a href="http://travis-ci.org/"&gt;http://travis-ci.org&lt;/a&gt; and sign in with your GitHub account. Grant Travis read/write access to your GitHub. You should see your private Travis build token on  &lt;a href="http://travis-ci.org/profile"&gt;your profile page&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-R-v6iXAJ77U/TkFm1gjSAYI/AAAAAAAAAIg/MOBbCC0Qq1k/s1600/travis_config.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="322" src="http://3.bp.blogspot.com/-R-v6iXAJ77U/TkFm1gjSAYI/AAAAAAAAAIg/MOBbCC0Qq1k/s400/travis_config.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;You don't really need to care about the token now - but while you’re on the profile page, flip the switch for the project that you want to build with Travis.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Run Your First Build &lt;i&gt;(3 minutes)&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Push to your git repository (make sure that you committed the &lt;i&gt;.travis.yml&lt;/i&gt; file), then go to the &lt;a href="http://travis-ci.org/"&gt;Travis home page&lt;/a&gt; and sit back as Travis adds your project to its build queue, installs the bundle and runs the tests. When the build is done, check your email to find a little love message from Travis - and congratulations for getting it green (or red)!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;If You're Curious...&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Why did Travis require write access to your GitHub account? That's because Travis automagically configures GitHub to be notified when you push to the project. Go check it if you like: on your project's admin page on GitHub, follow &lt;i&gt;Service Hooks,&lt;/i&gt; and click on the &lt;i&gt;Travis&lt;/i&gt; hook. The configuration should look like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-c7bvbx6T9_U/TkFeOCRe3PI/AAAAAAAAAIY/a-ydrGrpVgI/s1600/github_travis_cfg.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="290" src="http://3.bp.blogspot.com/-c7bvbx6T9_U/TkFeOCRe3PI/AAAAAAAAAIY/a-ydrGrpVgI/s400/github_travis_cfg.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If you click &lt;i&gt;Test Hook&lt;/i&gt;, Travis should schedule a build right now.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Prepare the Martini &lt;i&gt;(5 minutes)&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Fill a frozen cocktail glass with cold gin, add a touch of vermouth and stir. Garnish with an olive.&lt;br /&gt;&lt;br /&gt;(If you’re in a hurry, you can merge this step with the previous one, thus sparing 3 minutes and keeping yourself busy as Travis is building your project.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Drink the Martini &lt;i&gt;(extra quality time)&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I don’t think you need my help here. Just find good company and enjoy. Drink responsibly!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-wqWAkcORynE/TkFgLG0ZJTI/AAAAAAAAAIc/uX7jbYDy7JY/s1600/76419935_ecaf44df78_o.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-wqWAkcORynE/TkFgLG0ZJTI/AAAAAAAAAIc/uX7jbYDy7JY/s200/76419935_ecaf44df78_o.jpg" width="196" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-5380847725120480589?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/5380847725120480589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2011/08/get-your-ruby-project-on-travis-and.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/5380847725120480589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/5380847725120480589'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2011/08/get-your-ruby-project-on-travis-and.html' title='Get Your Ruby Project on Travis and Have a Martini in 15 Minutes'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-R-v6iXAJ77U/TkFm1gjSAYI/AAAAAAAAAIg/MOBbCC0Qq1k/s72-c/travis_config.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-391504143237472881</id><published>2011-06-01T09:14:00.000-07:00</published><updated>2011-06-01T16:50:01.589-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='2011'/><category scheme='http://www.blogger.com/atom/ns#' term='euruko'/><title type='text'>Euruko 2011 Thoughts</title><content type='html'>Back from &lt;a href="http://euruko2011.org/"&gt;the European Ruby Conference&lt;/a&gt;. Great people, good talks overall. Here are my quick thoughts on what was good, and what could be improved.&lt;br /&gt;&lt;br /&gt;(But first, a message to the people who praised &lt;a href="http://speakerrate.com/talks/7670-the-revenge-of-method_missing"&gt;my speech&lt;/a&gt;: I'd have to spam Twitter to thank each one of you, so please accept one big collective "thank you". I was stoked by your feedback.)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why Euruko Was Brilliant&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Flawless organization. I don't mean to reinforce cultural stereotypes ("The Germans are well-organized"), but this was one of the smoothest conference experiences I've ever been through. The volunteer organizers did a better job than most people who do this for a living. I heard there were a few people lost in the bushes or eaten by wild animals while hunting for the Saturday night party, but you can argue that was part of the fun. ;)&lt;br /&gt;&lt;br /&gt;In particular, the location was great. Berlin is already one of my favourite cities, but this topped my best expectations: Karl-Marx Allee, near Alexanderplatz, one of the most reachable landmarks in town. That, and the &lt;a href="http://www.flickr.com/photos/mfilej/5768540968/"&gt;most impressive conference screen&lt;/a&gt; I've seen so far.&lt;br /&gt;&lt;br /&gt;Internet connection is usually a sore spot at conferences, but these guys astounded everyone by &lt;a href="http://euruko2011.org/2011/05/26/such-great-heights.html"&gt;installing a parabolic dish on a nearby building&lt;/a&gt; just to provide us with perfect wireless connections. There were a few minor hiccups on the fist day, but they were quickly fixed. I was as impressed as everyone else. Standing ovation!&lt;br /&gt;&lt;br /&gt;Oh, and most conferences should get a clue from these people when it comes to classy, non-dorky-looking &lt;a href="http://www.hagenburger.net/PHOTOGRAPHY/euruko-t-shirts.html"&gt;t-shirts&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why Euruko Should Get Bigger&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I've read &lt;a href="http://renderedtext.com/blog/2011/06/01/notes-from-euruko-2011-day-1/"&gt;comments&lt;/a&gt; that the conference was too big, and previous Eurukos felt cozier. I do agree that small conferences make it easier to socialize. Nonetheless, I think that Euruko should be bigger, not smaller.&lt;br /&gt;&lt;br /&gt;Matter of fact, only a selected lucky few made it to the conference. I'm talking out of experience here: if I hadn't been a speaker, I would also have been left out. Getting a ticket proved impossible. Like so many other people, I was hitting "Refresh" constantly, and tickets went  straight from "Not yet available" to "Sold out" in the space of one HTTP call. Some of the people who were left out organized their own &lt;a href="http://eurucamp.org/"&gt;parallel conference&lt;/a&gt;. Most likely,  hundreds more people just gave up and  stayed home.&lt;br /&gt;&lt;br /&gt;The organizers told me that they were taken by storm by the number of requests, and I understand that. Still, it's frustrating to think that next year I might have to either submit a speech or snipe the tickets if I hope to enter the conference (especially since &lt;a href="http://lasteuruko.org/"&gt;next year's Euruko&lt;/a&gt; will be in Amsterdam, my &lt;i&gt;other&lt;/i&gt; favourite northern city).&lt;br /&gt;&lt;br /&gt;Apparently, only a small fraction of the submitted  speeches made the cut. I gather that the  organizers intentionally kept the conference single-track, to keep  people closer together - but I think the idea backfired. I'm more likely  to socialize if I have multiple tracks, smaller rooms, and plenty of corridors to hang around. Many talks received lukewarm feedback, and I think that was because most talks were very specific, so they couldn't possibly appeal to everyone. I'd rather let people select the talks that &lt;i&gt;they&lt;/i&gt; find interesting across multiple separate tracks, than have the organizers do the selection for them.&lt;br /&gt;&lt;br /&gt;One of the organizers told me that he thinks the European conference should strive to stay small and single-track. Apparently there is this meme that small conferences are more about people, and big conferences are more about money and business. I guess this fits with Berlin's young-and-smart, community-oriented, mildly anarchist mindset. Again, I sympathize with those feelings, but I disagree with the conclusions. Small conferences may be more about the people, but matter of fact, most of that people are being left out in the cold now. If it's small conferences we want, we already get plenty. Ruby is growing big in Europe, and the main European conference should be as big as the number of attendees - not the other way round.&lt;br /&gt;&lt;br /&gt;So, to the folks organizing next year's Euruko: maybe it's time to go bigger?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-391504143237472881?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/391504143237472881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2011/06/euruko-2011-thoughts.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/391504143237472881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/391504143237472881'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2011/06/euruko-2011-thoughts.html' title='Euruko 2011 Thoughts'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-7530818633007277168</id><published>2011-03-29T13:50:00.000-07:00</published><updated>2011-03-30T11:08:02.212-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='github'/><title type='text'>GitHub is a game changer</title><content type='html'>&lt;i&gt;&lt;b&gt;Update:&lt;/b&gt; here is &lt;a href="http://www.rubyinside.com/the-end-of-monkeypatching-4570.html"&gt;another recent blog post&lt;/a&gt; with excellent detailed instructions on forking and contributing to a GitHub project.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I used &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt; for a while before I could really appreciate what this site is doing to our culture as software developers. GitHub isn't just a neat tool: it's a revolution in the making.&lt;br /&gt;&lt;br /&gt;GitHub is a social platform for developing software, built around &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt;.  The use cases for git have always been interesting, but not necessarily compelling. GitHub builds on the strenghts of git, and the result is a brand new approach to writing and sharing code. While git takes care of the technical issues like forks and merges, GitHub takes care of the social issues like pull requests and tracking  forks.&lt;br /&gt;&lt;br /&gt;Just think of a typical development problem: patches. Your project uses a third-party library, and that library has a bug. Here is how you usually deal with the problem if the library is proprietary:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You contact the producer's customer service and report the problem.&lt;/li&gt;&lt;li&gt;You sit on your hands until the company fixes the problem. If ever. &lt;/li&gt;&lt;/ol&gt;Here is what you tipically do with an open source library:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You go to the library project's forum and report the problem.&lt;/li&gt;&lt;li&gt;You sit on your hands until the authors fix the problem. Eventually. &lt;/li&gt;&lt;/ol&gt;As an alternative, you could fix the problem yourself. To do that, you have to download the library's code, set it up, make sense of it, patch it, build it and test it. It could take you weeks. Then you submit a patch, and you hope that your patch will end up in the original codebase. Until then, you have to merge subsequent changes from the original codebase into your patched local codebase. Merges are usually painful enough that you'll probably stick with steps 1 and 2 in most cases. Bottom line, you'll probably end up doing like you would for a proprietary project: you find a workaround, and keep hoping. &lt;br /&gt;&lt;br /&gt;Now, here is what you do with GitHub:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You fork the library.&lt;/li&gt;&lt;li&gt;You fix the problem.&lt;/li&gt;&lt;li&gt;You use your own forked library in your project.&lt;/li&gt;&lt;li&gt;You send a pull request to the original library.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;GitHub makes step 1 &lt;a href="http://help.github.com/fork-a-repo/"&gt;as easy as you could reasonably hope&lt;/a&gt;. If you use good tools like &lt;a href="http://ducktypo.blogspot.com/2010/12/bundler-how-you-can-start-using-it.html"&gt;Bundler&lt;/a&gt;, step 3 becomes a &lt;a href="http://gembundler.com/git.html"&gt;one-liner&lt;/a&gt; as well. And step 4 is both trivial and not necessarily critical. You still have to merge future changes from the project into your fork, but git makes it easy for you to merge, and for the original library to incorporate your patch. All in all, GitHub turns patching from a bottomless pit of pain into a geeky form of pleasure.&lt;br /&gt;&lt;br /&gt;Now look at step 2, the remaining difficult step. To make it worth the trouble, you need a project that is easy to setup, easy to understand, and well covered by tests. So GitHub is a perfect fit for languages that promote clear, concise code and for communities who take pride in unit testing and easy project setup.&lt;br /&gt;&lt;br /&gt;Suddenly, complicated open source projects feel so last century. By removing all accidental difficulties of patching, GitHub tips the balance towards projects that are trivial to set up and test, and languages that promote easy change. If I need to pick between two projects, I'll probably pick the one that's easier to patch over the one that has the most bells and whistles. Month by month, GitHub is shifting our collective coders' hivemind towards simplicity.&lt;br /&gt;&lt;br /&gt;After all, wasn't this one of the original promises of open source? "It's your code. You'll never be stuck."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-7530818633007277168?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/7530818633007277168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2011/03/github-is-game-changer.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/7530818633007277168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/7530818633007277168'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2011/03/github-is-game-changer.html' title='GitHub is a game changer'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-8702532413347189562</id><published>2010-12-01T13:14:00.000-08:00</published><updated>2011-08-09T09:50:06.387-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='bundler'/><title type='text'>Bundler: How You Can Start Using It Today</title><content type='html'>I took some time before I could understand and use &lt;a href="http://gembundler.com/"&gt;Bundler&lt;/a&gt; in my Ruby projects. There was something about it that just didn't click with me.&lt;br /&gt;&lt;br /&gt;In hindsight, I should have learned Bundler earlier. Once you "get" the workflow, Bundler is very simple and very powerful at the same time. It's one of those well-made tools that makes it dead easy to do simple stuff, and entirely possible to do complex stuff when the time comes.&lt;br /&gt;&lt;br /&gt;I wrote a &lt;a href="http://www.pragprog.com/magazines/2010-12/three-bundler-benefits"&gt;Bundler primer&lt;/a&gt; for the latest &lt;a href="http://www.pragprog.com/magazines/2010-12/content"&gt;PragPub&lt;/a&gt;, the Pragmatic Programmer's monthly magazine. If you're not using Bundler yet, I hope that this article will turn you into a Bundler user before dinner.&lt;br /&gt;&lt;br /&gt;(Even if you don't care about Bundler, the rest of the magazine is likely to have something for you. PragPub is my favourite programming mag ever, and I'm proud to write for them when it happens.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-8702532413347189562?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/8702532413347189562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/12/bundler-how-you-can-start-using-it.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/8702532413347189562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/8702532413347189562'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/12/bundler-how-you-can-start-using-it.html' title='Bundler: How You Can Start Using It Today'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-8440750914174973902</id><published>2010-10-07T03:19:00.000-07:00</published><updated>2010-10-07T03:39:05.233-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><title type='text'>The method_missing() Chainsaw</title><content type='html'>I have a &lt;a href="http://rubylearning.com/blog/2010/10/07/do-you-know-rubys-chainsaw-method/"&gt;guest post&lt;/a&gt; about &lt;i&gt;method_missing()&lt;/i&gt; on &lt;a href="http://rubylearning.com/"&gt;RubyLearning&lt;/a&gt;. It's intended for Ruby beginners, but it's attracting interesting discussions in the comments and on &lt;a href="http://news.ycombinator.com/item?id=1766381"&gt;Hacker News&lt;/a&gt; - mainly from people dissing &lt;a href="http://gist.github.com/535070"&gt;Dynamic Methods&lt;/a&gt; in favor of &lt;a href="http://gist.github.com/534776"&gt;Ghost Methods&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-8440750914174973902?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/8440750914174973902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/10/methodmissing-chainsaw_07.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/8440750914174973902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/8440750914174973902'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/10/methodmissing-chainsaw_07.html' title='The method_missing() Chainsaw'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-8633243199175170761</id><published>2010-08-29T06:58:00.000-07:00</published><updated>2010-09-03T01:39:41.933-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>A Metaprogramming Spell Book</title><content type='html'>I put all the spells from &lt;a href="http://www.pragprog.com/titles/ppmetr"&gt;Metaprogramming Ruby&lt;/a&gt; on &lt;a href="http://gist.github.com/"&gt;Gist&lt;/a&gt;, so that I can easily link to spells from future posts (and of course, you're welcome to do the same). Here they are:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534765.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534772.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534987.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534678.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535001.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535012.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535018.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535023.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535051.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535053.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535058.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535065.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535070.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535077.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535082.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534776.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534994.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535089.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535107.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535110.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534690.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535115.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535118.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535121.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534667.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535127.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535134.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535138.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535140.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535147.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535156.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534685.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535047.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/535164.js"&gt; &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-8633243199175170761?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/8633243199175170761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/08/metaprogramming-spell-book.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/8633243199175170761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/8633243199175170761'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/08/metaprogramming-spell-book.html' title='A Metaprogramming Spell Book'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-5135073370632156192</id><published>2010-08-28T22:51:00.000-07:00</published><updated>2010-09-03T01:40:13.986-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rubykaigi'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>RubyKaigi 2010</title><content type='html'>The scarily efficient organizers of &lt;a href="http://rubykaigi.org/2010/en"&gt;RubyKaigi 2010&lt;/a&gt; only took a few hours to publish the &lt;a href="http://rubykaigi.tdiary.net/20100829.html#p12"&gt;video of my talk&lt;/a&gt; on metaprogramming and the Ruby object model (slides and audio only).&lt;br /&gt;&lt;br /&gt;Yesterday I also lived the Andy Warhol moment of my life when I signed the first hundred or so copies of &lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048687158"&gt;Metaprogramming Ruby Japanese Edition&lt;/a&gt; together with translator Kado Masanori and &lt;a href="http://en.wikipedia.org/wiki/Yukihiro_Matsumoto"&gt;Matz&lt;/a&gt;. I looked at the long line of people happily waiting half an hour to have their copy signed, and suddenly spending three years to write a book seemed like a perfectly rational thing to do.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_lOnlzlozMt4/THnvShRzzRI/AAAAAAAAAEI/6a5DoIwg4jw/s1600/kaigi_signing.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_lOnlzlozMt4/THnvShRzzRI/AAAAAAAAAEI/6a5DoIwg4jw/s320/kaigi_signing.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-5135073370632156192?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/5135073370632156192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/08/rubykaigi-2010.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/5135073370632156192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/5135073370632156192'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/08/rubykaigi-2010.html' title='RubyKaigi 2010'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lOnlzlozMt4/THnvShRzzRI/AAAAAAAAAEI/6a5DoIwg4jw/s72-c/kaigi_signing.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-106538144236243</id><published>2010-08-27T06:17:00.000-07:00</published><updated>2010-09-03T01:39:20.194-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rubykaigi'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Metaprogramming Ruby in Japanese is Out</title><content type='html'>&lt;a href="http://www.amazon.co.jp/exec/obidos/ASIN/4048687158"&gt;This&lt;/a&gt; is selling great at &lt;a href="http://rubykaigi.org/"&gt;RubyKaigi&lt;/a&gt; in Tsukuba. I'm a happy little author.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_lOnlzlozMt4/THe64nS2ZxI/AAAAAAAAADw/Ps3YkD_m8Mc/s1600/metaprogramming_ruby_jp.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_lOnlzlozMt4/THe64nS2ZxI/AAAAAAAAADw/Ps3YkD_m8Mc/s320/metaprogramming_ruby_jp.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Big thanks to my translator, Kado Masanori, and my Japanese editor-in-Chief, Kahei Suzuki.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-106538144236243?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/106538144236243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/08/metaprogramming-ruby-in-japanese-is-out.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/106538144236243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/106538144236243'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/08/metaprogramming-ruby-in-japanese-is-out.html' title='Metaprogramming Ruby in Japanese is Out'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lOnlzlozMt4/THe64nS2ZxI/AAAAAAAAADw/Ps3YkD_m8Mc/s72-c/metaprogramming_ruby_jp.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-2123454232124796646</id><published>2010-08-18T05:39:00.000-07:00</published><updated>2010-08-21T01:11:03.643-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='inheritance'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><title type='text'>Why Inheritance Sucks (in Ruby, at least)</title><content type='html'>&lt;i&gt;[Update: Some readers went up in arms over this post, probably because the original title didn't specify which language I'm talking about. To clarify, I'm talking about inheritance &lt;/i&gt;in Ruby&lt;i&gt;, compared to using modules, also &lt;/i&gt;in Ruby&lt;i&gt;. My point here is that inheritance is an essential feature in C++/Java/C#, but not as much in Ruby. No, I'm not saying that Java should drop inheritance anytime soon.]&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I came to Ruby from a static language background (C++, Java), and I had a hard time leaving my hold habits behind. In particular, as a Ruby beginner I tended to overuse inheritance. These days, I rarely use inheritance at all. Instead, I use &lt;a href="http://juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby/"&gt;modules&lt;/a&gt;. Let's look at the difference.&lt;br /&gt;&lt;br /&gt;When you use inheritance, the superclass becomes an ancestor of the subclass. When you call a method, Ruby walks up the chain of ancestors until it finds the method. So, objects of the subclass also get the methods defined in the superclass.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534477.js?file=inheritance_sucks_1.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_lOnlzlozMt4/TGvL0oYPbiI/AAAAAAAAADM/IvS23VKh9ww/s1600/why_inheritance_sucks.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://3.bp.blogspot.com/_lOnlzlozMt4/TGvL0oYPbiI/AAAAAAAAADM/IvS23VKh9ww/s400/why_inheritance_sucks.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;When you use modules, the module also becomes an ancestor of the class, just like the superclass does:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/534488.js?file=inheritance_sucks_2.rb"&gt;&lt;/script&gt;&lt;br /&gt;When you call a method, Ruby still walks up the ancestors chain until it finds the method. The net effect is exactly the same as the picture above, except that &lt;i&gt;Bird&lt;/i&gt; is now a module instead of a class. So, having a method in a superclass or having the same method in a module doesn't make much difference in practice.&lt;br /&gt;&lt;br /&gt;However, modules are generally more flexible than superclasses. Modules can be managed at runtime, because &lt;a href="http://ruby-doc.org/core/classes/Module.html#M001638"&gt;&lt;i&gt;include&lt;/i&gt;&lt;/a&gt; is just a regular method call, while superclasses are set in stone as you write your class definitions. Modules are much easier to use and test in isolation than strictly coupled hierarchy of classes. You can include as many modules as you like, while you can only have one superclass per class. And finally, when you get into advanced Ruby, modules give you much more flexibility than classes, so you can use modules to cast magic metaprogramming spells like &lt;a href="http://gist.github.com/534685"&gt;Singleton Methods&lt;/a&gt; and &lt;a href="http://gist.github.com/534678"&gt;Class Extensions&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If inheritance is so much worse than modules in Ruby, then why do languages like Java and C# rely on inheritance so much? There are two reasons why you use inheritance in these languages. The first reason is that you want to manage your methods - for example, re-use the same method in different subclasses. The second reason is because you want to upcast the type of a reference from a subclass to a superclass - that's the only way to get polimorphism in Java. The first reason is not as valid in Ruby, because you can just as well use modules to manage your methods. However, upcasting is more interesting.&lt;br /&gt;&lt;br /&gt;Java is both compiled and statically typed, so the compiler can analyze your code and spot type-related mistakes. In particular, it can spot upcasting mistakes: if you have a method that takes &lt;i&gt;Mineral&lt;/i&gt;s, and you pass a &lt;i&gt;Dog&lt;/i&gt; to the method, then the compiler will complain that a &lt;i&gt;Dog&lt;/i&gt; is an &lt;i&gt;Animal&lt;/i&gt;, not a &lt;i&gt;Mineral&lt;/i&gt;, so you cannot upcast a &lt;i&gt;Dog&lt;/i&gt; reference to a &lt;i&gt;Mineral&lt;/i&gt; reference. In Ruby you don't declare your types, so you don't have upcasting at all. Even if you did have upcasting, you wouldn't have a compiler double-checking it. So you don't get the same advantages out of inheritance in Ruby compared to Java.&lt;br /&gt;&lt;br /&gt;"Wait a minute," I hear you say. "Some of the limitations of inheritance are actually a good thing! Including multiple modules in Ruby is just like having multiple inheritance in C++, and multiple inheritance is a big mess. That's why Java and C# force you to inherit from a single class". This is the &lt;a href="http://en.wikipedia.org/wiki/Diamond_problem"&gt;"diamond" problem&lt;/a&gt; that my original C++ mentor used to warn me about: if your class has two superclasses, and they both inherit from yet another superclass, then you get a diamond-shaped inheritance chain that can potentially be confusing. Wouldn't modules be a throwback to this kind of headaches?&lt;br /&gt;&lt;br /&gt;In practice, however, Ruby modules tend to be more manageable than multiple superclasses. In Ruby, the chain of ancestors always follows a single path, where each module or class can only appear once - so you can't have diamond-shaped inheritance. If you understand how Ruby builds the chain of ancestors, you're never going to find yourself in an ambiguous situation where you don't know  which method is called: simply enough, Ruby always calls the version of  the method that's lower on the ancestors chain. (You can still get a clash if two separate modules reference instance variables with the same name, but that rarely happens in practice.) More crucially, the way you write code in Ruby is different from the way you write code in a static language. If you get used to crazy stuff like replacing methods with &lt;a href="http://gist.github.com/534690"&gt;Monkeypatches&lt;/a&gt;, then there is no reason why you shouldn't get used to managing methods with modules.&lt;br /&gt;&lt;br /&gt;I took literally years to get rid of my tendency to think in inheritance. Now I finally understand why large Ruby projects such as Rails barely use inheritance at all, and rely almost exclusively on modules.&lt;br /&gt;&lt;br /&gt;Use inheritance sparingly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-2123454232124796646?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/2123454232124796646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/08/why-inheritance-sucks.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/2123454232124796646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/2123454232124796646'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/08/why-inheritance-sucks.html' title='Why Inheritance Sucks (in Ruby, at least)'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lOnlzlozMt4/TGvL0oYPbiI/AAAAAAAAADM/IvS23VKh9ww/s72-c/why_inheritance_sucks.jpg' height='72' width='72'/><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-396630921019766552</id><published>2010-06-25T02:07:00.000-07:00</published><updated>2010-08-18T08:52:41.830-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='language'/><title type='text'>The New Ruby Ecosystem</title><content type='html'>Last week I finally caught up with the state of Ruby - the language, the community and the tools in fashion. I'm impressed. These guys seem to be doing a lot of things right.&lt;br /&gt;&lt;br /&gt;I'd taken a break from Ruby a few months ago, after &lt;a href="http://www.amazon.com/Metaprogramming-Ruby-Paolo-Perrotta/dp/1934356476"&gt;Metaprogramming Ruby&lt;/a&gt; had gone out of beta. On my comeback, I was a tad disappointed at first. I couldn't see much progress on things like &lt;a href="http://ruby-std.netlab.jp/"&gt;standard language specs&lt;/a&gt;, Windows support or in-process concurrency. I didn't even see an increase in Ruby's popularity. In fact, even as the language is &lt;a href="http://www.indeed.com/jobtrends?q=ruby%2C+rails&amp;amp;l="&gt;going strong in the marketplace&lt;/a&gt;, the burst of adrenaline that used to accompany its rise &lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.htm"&gt;seems to have faded&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So, where did the once-vocal Ruby community go? As it turns out, they're hard at work building a new environment. It's an ecosystem composed of many small moving pieces, mostly interchangeable and in continuous flux, yet integrating nicely with each other. It's young and rough around the edges, but it's working well enough, and it pushes the envelope far enough, that it deserves its own name: I'll call it the New Ruby Ecosystem.&lt;br /&gt;&lt;br /&gt;Here are a few examples:&lt;br /&gt;&lt;br /&gt;- It seems yesterday that the Rails team &lt;a href="http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3"&gt;announced their merging&lt;/a&gt; with Merb, their primary competitor for web developer love. In less than one and a half years, these guys merged two large frameworks into &lt;a href="http://guides.rails.info/3_0_release_notes.html"&gt;one better, cleaner framework&lt;/a&gt; that some people are already using in production. Most companies I worked with would take multiple years to accomplish such a feat - if ever.&lt;br /&gt;&lt;br /&gt;- Any Ruby web framework now &lt;a href="http://rack.rubyforge.org/doc/"&gt;jives great&lt;/a&gt; with any Ruby web server. I can scale down from a fully load-balanced production system, to a local Apache, to a quick in-process web server without even thinking about it. I can also &lt;a href="http://rtomayko.github.com/rack-cache/"&gt;add components&lt;/a&gt; to the HTTP chain in a snap. Thanks to &lt;a href="http://vision-media.ca/resources/ruby/ruby-rack-middleware-tutorial"&gt;Rack's amazing simplicity&lt;/a&gt;, it took less than one year to move from Rack 1.0 to widespread Rack compliance. As Sam Ruby put it: &lt;a href="http://intertwingly.net/blog/2008/12/17/Rackem-Up"&gt;I love it when a plan comes together.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;- In what seems like one year, pretty much all Ruby-related development migrated to &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; and &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;. GitHub is now a one-stop shop to do whatever you wish to whatever piece of open code in the Ruby world. Forking and contributing has never been so easy. The technology behind the library repositories took the time to split, experiment and then &lt;a href="http://ruby.dzone.com/articles/new-rubygemsorg-gemcutter-and"&gt;merge again&lt;/a&gt;, so that publishing a project to the community is now &lt;a href="http://rubygems.org/pages/gem_docs"&gt;boringly easy&lt;/a&gt;. The barrier to contribute, join efforts or part efforts in the Ruby community is as low as they get.&lt;br /&gt;&lt;br /&gt;- No other technology offers a comparable number of options to connect to just about any &lt;s&gt;cool&lt;/s&gt; recent thingie out there, from &lt;a href="http://en.wikipedia.org/wiki/NoSQL"&gt;noSQL databases&lt;/a&gt; to &lt;a href="http://en.wikipedia.org/wiki/Cloud_computing"&gt;clouds&lt;/a&gt;. Yesterday I was looking for libraries to access &lt;a href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt;, and I was &lt;a href="http://rubygems.org/search?query=mongo"&gt;totally overwhelmed&lt;/a&gt;. These libraries also tend to be simple enough that switching from one to the other is as easy as I could hope. I just picked up &lt;a href="http://rubygems.org/gems/mongo"&gt;the default Mongo driver&lt;/a&gt; for my next project, and I'm confident I'll be able to switch quickly to another driver or even a relational DB if I need to.&lt;br /&gt;&lt;br /&gt;- There are now about &lt;a href="http://rvm.beginrescueend.com/interpreters/"&gt;ten flavours of Ruby interpreters&lt;/a&gt;, ranging from experimental, to cutting-edge, to enterprise-stable. I can have all of those interpreters, or even multiple versions of the same interpreter, &lt;a href="http://rvm.beginrescueend.com/"&gt;on one computer&lt;/a&gt;. I can install a new Ruby, select a default Ruby, switch Ruby on the fly - each of those &lt;a href="http://rvm.beginrescueend.com/rubies/"&gt;with a single command&lt;/a&gt;. I can switch Ruby automatically for a specific project directory, and I don't even have to notice: I just type &lt;span style="font-style: italic;"&gt;ruby&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;irb&lt;/span&gt;, and bang - I'm using the “right” interpreter. I can even have multiple sets of gems (libraries) for each Ruby, and switch gemsets with &lt;a href="http://rvm.beginrescueend.com/gemsets/using/"&gt;one command&lt;/a&gt; like I switch Rubies. I cannot imagine a more flexible language environment.&lt;br /&gt;&lt;br /&gt;- I can &lt;a href="http://gembundler.com/"&gt;declare all the libraries&lt;/a&gt; that my project needs, install them all at once, instruct the project to ignore any unlisted library, and package all libraries inside the project itself. I can even &lt;a href="http://bcardarella.com/post/699582642/rvm-gemsets-bundler-awesome"&gt;use Bundler and rvm together&lt;/a&gt; to isolate each project within its own little bubble of libraries. The result comes close to copy-and-run installation from development to production. &lt;a href="http://maven.apache.org/"&gt;Complex library management tools&lt;/a&gt; suddenly feel so last year.&lt;br /&gt;&lt;br /&gt;- The popular Ruby libraries, especially the &lt;a href="http://blog.plataformatec.com.br/2009/10/devise-flexible-authentication-solution-for-rails/"&gt;Rails add-ons&lt;/a&gt; and the testing tools, evolve at a scary pace. Projects like Cucumber release production updates &lt;a href="http://github.com/aslakhellesoy/cucumber/blob/master/History.txt"&gt;faster&lt;/a&gt; than you'll probably care to get them. Still, the tools are remarkably stable (unless you choose to ride beta versions) and &lt;a href="http://hubertlepicki.com/2010/01/09/perfect-solution-for-testing-rails-applications-rspec-cucumber-capybara-selenium-2-0"&gt;play together&lt;/a&gt; nicely. There is something to be learned from a project that releases stable production versions every few days, even taking the time to go through a few large refactorings, and still manages not to break its thousands of clients.&lt;br /&gt;&lt;br /&gt;- I can mix-and-match libraries to get my own ideal environment. Libraries are built to work together by default. I'm now switching a small testing project from &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt;-&lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;+&lt;a href="http://github.com/brynary/webrat"&gt;Webrat&lt;/a&gt;+&lt;a href="http://mechanize.rubyforge.org/mechanize/"&gt;Mechanize&lt;/a&gt; to Cucumber+RSpec+&lt;a href="http://github.com/jnicklas/capybara"&gt;Capybara&lt;/a&gt;+&lt;a href="http://github.com/langalex/culerity"&gt;Culerity&lt;/a&gt;+Mechanize, so that I can test simpler browser interactions in-process and &lt;a href="http://openmonkey.com/articles/2010/04/javascript-testing-with-cucumber-capybara"&gt;switch to a real browser&lt;/a&gt; when I test JavaScript. The community is relentlessly looking for ways to make my life easier.&lt;br /&gt;&lt;br /&gt;- I can deploy my Rails application to the cloud &lt;a href="https://heroku.com/"&gt;with a single command&lt;/a&gt;. The server will &lt;a href="http://blog.heroku.com/archives/2010/2/17/gem_bundler_on_heroku/"&gt;update all its libraries&lt;/a&gt;, tweak my app's configuration to run on its own backend, and generally do everything so that my application  &lt;span style="font-style: italic;"&gt;just works&lt;/span&gt;&lt;sup&gt;©&lt;/sup&gt;.&lt;br /&gt;&lt;br /&gt;Nothing of the above is revolutionary. Taken all together, though, these changes are a great display of the power of simplicity, testing, openness and relentless experimentation. In fact, I think that the development community at large should look hard at the Ruby community for inspiration. Sure, you can wait for the better stuff to &lt;a href="http://ryanlanciaux.com/ryanlanciaux/post/Gherkin-style-BDD-testing-in-NET.aspx"&gt;make&lt;/a&gt; &lt;a href="http://www.lostechies.com/blogs/rssvihla/archive/2009/08/08/introducing-specmaker-rspec-style-bdd-in-c.aspx"&gt;its&lt;/a&gt; &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;way&lt;/a&gt; to your &lt;a href="http://srtsolutions.com/public/item/250835"&gt;environment of choice&lt;/a&gt; - but no matter how good those efforts, you'll be lagging a few steps behind. If you fancy to be in the place where things happen, there is no current replacement for the Ruby community.&lt;br /&gt;&lt;br /&gt;In a world where a standard can take &lt;a href="http://www.ibm.com/developerworks/java/library/j-jtp04247.html"&gt;years&lt;/a&gt; to be discussed, approved, implemented and supported, Ruby standards such as Rack skip from conception to widespread support at blazing speed. Every time I take a peek, the New Ruby Ecosystem seems to have reinvented itself in many different ways. This is inspect-and-adapt taken to new heights, and a wonderful showcase  of the power of emergent design over big up-front design.&lt;br /&gt;&lt;br /&gt;Final disclaimer: As usual, cutting-edge Ruby is not for the faint of heart. In particular, using Ruby on Windows still gives me more headaches than I'd expect, so I'd hesitate to suggest some of the above tools to customers still deeply mired in Windows. If you use the beta versions of all tools, expect your own share of &lt;a href="http://railsforum.com/viewtopic.php?id=34084"&gt;bumps in the road&lt;/a&gt; and &lt;a href="https://rspec.lighthouseapp.com/projects/5645/tickets/1006-error-when-using-integrate_views-in-rails-3-controller-specs"&gt;frustrating error messages&lt;/a&gt;. It will take a few more months until Ruby 1.9, Rails 3, Bundler, RSpec, Cucumber, Heroku and all the related technologies work together without a hitch.&lt;br /&gt;&lt;br /&gt;I know I'll be waiting. With a big smile on my face.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-396630921019766552?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/396630921019766552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/06/new-ruby-ecosystem.html#comment-form' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/396630921019766552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/396630921019766552'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/06/new-ruby-ecosystem.html' title='The New Ruby Ecosystem'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-3645972585490355593</id><published>2010-03-10T12:45:00.000-08:00</published><updated>2010-06-25T03:55:35.186-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Big in Japan</title><content type='html'>I was stunned and delighted to see Metaprogramming Ruby topping the &lt;a href="http://www.amazon.co.jp/gp/bestsellers/english-books/89796011/"&gt;Amazon.co.jp chart&lt;/a&gt; for English-language computer books. At one point, Amazon.co.jp even listed Metaprogramming Ruby amongst the 50 best selling English books &lt;span style="font-style: italic;"&gt;overall&lt;/span&gt;! I could get a good sight of Dan Brown and Harry Potter from there (not to mention a lot of Michael Jackson biographies). It didn't last long, but it was nice to hang around with the big boys for a few hours.&lt;br /&gt;&lt;br /&gt;As a first-time author, I couldn't have asked for more. To all the people in Japan who bought the book: thank you! Stay tuned, because there might be more news for you in a few months...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-3645972585490355593?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/3645972585490355593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/03/big-in-japan.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/3645972585490355593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/3645972585490355593'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/03/big-in-japan.html' title='Big in Japan'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-1854656151783585137</id><published>2010-02-01T05:37:00.000-08:00</published><updated>2010-02-01T05:37:03.235-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>In print and shipping</title><content type='html'>&lt;a target="_blank" class="popup" href="http://www.amazon.com/Metaprogramming-Ruby-Paolo-Perrotta/dp/1934356476%3FSubscriptionId%3D0EYTEJVF8KFKVFCZKS02%26tag%3Dsinkannet-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1934356476"&gt;Metaprogramming Ruby&lt;/a&gt; is &lt;a target="_blank" class="popup" href="http://twitter.com/pragdave/status/8372820383"&gt;back from the printers&lt;/a&gt;. Amazon should get it soon. Thanks to everyone who pre-ordered!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-1854656151783585137?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/1854656151783585137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/02/in-print-and-shipping.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/1854656151783585137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/1854656151783585137'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/02/in-print-and-shipping.html' title='In print and shipping'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-1817905916345704409</id><published>2010-02-01T05:36:00.000-08:00</published><updated>2010-02-01T05:36:19.063-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Incoming...</title><content type='html'>After more than three years of work, &lt;a target="_blank" class="popup" href="http://www.amazon.com/Metaprogramming-Ruby-Paolo-Perrotta/dp/1934356476%3FSubscriptionId%3D0EYTEJVF8KFKVFCZKS02%26tag%3Dsinkannet-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1934356476"&gt;Metaprogramming Ruby: Program Like the Ruby Pros&lt;/a&gt; finally hit the printers. It's time for me to pop open that special bottle.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-1817905916345704409?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/1817905916345704409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/02/incoming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/1817905916345704409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/1817905916345704409'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/02/incoming.html' title='Incoming...'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6608275468089048982.post-812764068527597533</id><published>2010-01-09T14:50:00.000-08:00</published><updated>2010-08-18T08:55:19.388-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Bill is back, in article form!</title><content type='html'>Those of you who read the beta version of &lt;a class="popup" href="http://www.amazon.com/gp/product/1934356476/ref=cm_cd_asin_lnk" target="_blank"&gt;Metaprogramming Ruby&lt;/a&gt; already know Bill, the grumpy old Ruby mentor. If you didn't get enough of him yet, here's a treat for you.&lt;br /&gt;&lt;br /&gt;The January 2010 issue of &lt;a class="popup" href="http://www.pragprog.com/magazines/" target="_blank"&gt;PragPub magazine&lt;/a&gt; contains a &lt;a href="http://www.pragprog.com/magazines/2010-01/much-ado-about-nothing"&gt;short article&lt;/a&gt; where Bill lectures you about the ins and outs of Ruby's nil value. In this article, I also introduce a couple of spells that fell on the cutting room floor as I struggled to make the book shorter: the Null Object spell and the Black Hole spell.&lt;br /&gt;&lt;br /&gt;You can download PragPub for free (in formats suited for &lt;a class="popup" href="http://www.pragprog.com/magazines/download/7.mobi" target="_blank"&gt;Kindles&lt;/a&gt;, &lt;a class="popup" href="http://www.pragprog.com/magazines/download/7.epub" target="_blank"&gt;iPhones&lt;/a&gt; and &lt;a class="popup" href="http://www.pragprog.com/magazines/download/7.pdf" target="_blank"&gt;plain old-fashioned computers&lt;/a&gt;). Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6608275468089048982-812764068527597533?l=ducktypo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ducktypo.blogspot.com/feeds/812764068527597533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ducktypo.blogspot.com/2010/01/bill-is-back-in-article-form.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/812764068527597533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6608275468089048982/posts/default/812764068527597533'/><link rel='alternate' type='text/html' href='http://ducktypo.blogspot.com/2010/01/bill-is-back-in-article-form.html' title='Bill is back, in article form!'/><author><name>Paolo "Nusco" Perrotta</name><uri>http://www.blogger.com/profile/14208201814847358637</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/_lOnlzlozMt4/S2bZULDo7FI/AAAAAAAAACA/OGL3Kj4_ASE/S220/a284d850ada0874f40b35210.L._SL315_.jpg'/></author><thr:total>0</thr:total></entry></feed>
