<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>It is the Confession, not the Priest that gives us absolution</description><title>Larrikinism</title><generator>Tumblr (3.0; @larikin)</generator><link>http://rxvl.in/</link><item><title>GSOC 2011: ssc Week 10</title><description>&lt;p&gt;Tasks completed this week:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Implemented checkout of an existing appliance from Studio. &lt;code&gt;ssc checkout --appliance-id=APPLIANCE_ID&lt;/code&gt; now works.&lt;/li&gt;
&lt;li&gt;Integration tests for the appliance, package and repository handlers. (Currently at about 50% test coverage).&lt;/li&gt;
&lt;li&gt;Completed the refactoring and migration to the New DirectoryManager module.&lt;/li&gt;
&lt;li&gt;Added the build and build_status commands&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Schedule for next week:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Improving test coverage and removing all the deprecated and unused methods.&lt;/li&gt;
&lt;li&gt;Writing unit tests for the helper modules.&lt;/li&gt;
&lt;li&gt;Writing usage examples for the app to help new users.&lt;/li&gt;
&lt;/ul&gt;</description><link>http://rxvl.in/post/8339259286</link><guid>http://rxvl.in/post/8339259286</guid><pubDate>Mon, 01 Aug 2011 18:56:47 +0530</pubDate><category>gsoc</category><category>ssc</category></item><item><title>GSOC 2011: ssc Week 9</title><description>&lt;p&gt;Tasks completed this week:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;p&gt;Replacing of &lt;code&gt;ArgumentParser&lt;/code&gt; with &lt;code&gt;Thor&lt;/code&gt;. I&amp;#8217;d given a mid-week update about this [1] on the mailing list. Please check there for complete details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementing the general commands (&lt;code&gt;checkout&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;status&lt;/code&gt;). As a direct consequence of using thor for the command line parsing, we get to use the &lt;code&gt;invoke&lt;/code&gt; method to call other actions. This made writing these commands quite easy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Started on refactoring the &lt;code&gt;DirectoryManager&lt;/code&gt; module. The &lt;code&gt;NewDirectoryManager&lt;/code&gt; is currently in use in the general commands and will gradually replace the older version which is a mess of helper functions right now. There will be separate classes for handling each of the local storage files (for software, repositories and files) deriving from a parent &lt;code&gt;LocalStorageFile&lt;/code&gt; class which implements the generic &lt;code&gt;#read&lt;/code&gt; and &lt;code&gt;#save&lt;/code&gt; methods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The gem is now hosted on rubygems.org . So, you can install it with &lt;code&gt;gem install ssc&lt;/code&gt;. Use the fantastic thor generated usage instructions to help you use the app.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;The tasks for next week are:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Write integration tests&lt;/li&gt;
&lt;li&gt;Implement a command to get information about installed packages from the currently run system.&lt;/li&gt;
&lt;li&gt;Commands for Appliance building and build status reporting.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;If you have any suggestions for features. Please do write in on the studio-users mailing list.&lt;/p&gt;

&lt;p&gt;[1] &lt;a href="http://lists.opensuse.org/opensuse-project/2011-07/msg00098.html"&gt;http://lists.opensuse.org/opensuse-project/2011-07/msg00098.html&lt;/a&gt;&lt;/p&gt;</description><link>http://rxvl.in/post/7967401920</link><guid>http://rxvl.in/post/7967401920</guid><pubDate>Sat, 23 Jul 2011 17:13:00 +0530</pubDate><category>gsoc</category><category>ssc</category></item><item><title>GSOC 2011: ssc Week 6</title><description>&lt;p&gt;Most of the work this week has gone into the File Handler. Adding and removing files in appliances has been implemented although there is a lot of work left to be done to make this robust. Right now its pretty basic. However I&amp;#8217;m going to ease up on adding functionality right now to make the app more robust and usable. The mid-term evaluations are coming up and the plan is to have a usable app that is community tested by then. Not to say that new features won&amp;#8217;t be added over the next two weeks, but it will be a second priority. In making the app more stable, the following things will be addressed:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Ruby 1.8.7 (backward) compatibility&lt;/li&gt;
&lt;li&gt;Extended test-suite including integration tests which require a network connection&lt;/li&gt;
&lt;li&gt;Better error handling.&lt;/li&gt;
&lt;li&gt;A method to roll back changes in case of failure.&lt;/li&gt;
&lt;li&gt;Documentation.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;That will be the focus over the next two weeks building up to the mid-term evaluation. Thank you for reading. As always you can check out the core &lt;a href="http://gitorious.org/ssc/ssc"&gt;here&lt;/a&gt;&lt;/p&gt;</description><link>http://rxvl.in/post/7219106912</link><guid>http://rxvl.in/post/7219106912</guid><pubDate>Mon, 04 Jul 2011 11:05:09 +0530</pubDate><category>gsoc</category><category>ssc</category></item><item><title>GSOC 2011: ssc - Week 4</title><description>&lt;p&gt;The &lt;code&gt;DirectoryManager&lt;/code&gt; module has been polished and it now handles duplicate entries in the software and repositories files. The app now handles errors better and crashes more gracefully with meaningful error messages. As for functionality, I&amp;#8217;ve added package banning and unbanning. Also package importing has been included in the current release.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve started work on the file handling of the app. Currently it works similar to the packages or repositories with the difference that the file in question is copied over to &lt;code&gt;&amp;lt;appliance_directory&amp;gt;/files&lt;/code&gt;. Adding and removing these files will be simple enough within the current framework. And with some work time-stamp information can be incorporated to do more efficient syncs. I hope to have that done by next week and follow up with a basic implementation of the commit command in the week after that so that we can have a first usable version of the client.&lt;/p&gt;

&lt;p&gt;If you want to check out the application now, you can take it for a spin using &lt;a href="http://dl.dropbox.com/u/546252/ssc_releases/ssc-0.1.0.gem"&gt;the gem&lt;/a&gt;. Use with caution, and all that. It shouldn&amp;#8217;t do anything catastrophic, but, I wouldn&amp;#8217;t use it with anything other than a test appliance at this point. Download it from &lt;a href="http://dl.dropbox.com/u/546252/ssc_releases/ssc-0.1.0.gem"&gt;here&lt;/a&gt;. Install it with &lt;a href="http://rubygems.org"&gt;rubygems&lt;/a&gt; (&lt;code&gt;gem install ssc-0.1.0.gem&lt;/code&gt;) and run &lt;code&gt;ssc help&lt;/code&gt; to see the usage instructions.&lt;/p&gt;</description><link>http://rxvl.in/post/6688635893</link><guid>http://rxvl.in/post/6688635893</guid><pubDate>Sun, 19 Jun 2011 20:00:00 +0530</pubDate><category>gsoc</category><category>ssc</category></item><item><title>GSOC 2011: ssc - Week 3</title><description>&lt;p&gt;This week I was working on the local storage feature of the client. As proposed we were going to add and remove packages, repositories and files with a git-like workflow. i.e. &lt;code&gt;ssc package add gnuchess&lt;/code&gt; would make a local record of the intention to add that package and on &lt;code&gt;ssc commit&lt;/code&gt; the changes would actually be pushed.&lt;/p&gt;

&lt;p&gt;In order to facilitate this I&amp;#8217;m abstracting all the directory management to a DirectoryManager module. Which abstracts methods to save, read and diff from local sources. Right now the syntax I&amp;#8217;ve chosen is YAML. For instance the &lt;code&gt;software&lt;/code&gt; file in the appliance directory - which catalogues the changes made to the appliance&amp;#8217;s software - stores names of installed packages. Unless the ssc command is invoked with the &lt;code&gt;-r | --remote&lt;/code&gt; option, it will display the packages in that file. In addition when &lt;code&gt;ssc package add gnuchess&lt;/code&gt; is run with out the -r option, it will make and addition &lt;code&gt;add gnuchess&lt;/code&gt; to the software file. Similarly for remove. I am having some problems figuring out how to integrate patterns into this architecture so any help on that front would be appreciated.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s it for this week. I&amp;#8217;m going to be working on pretty much the same thing next week. Extending and refactoring this functionality. So hopefully we will have a more usable version then.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;</description><link>http://rxvl.in/post/6481353758</link><guid>http://rxvl.in/post/6481353758</guid><pubDate>Mon, 13 Jun 2011 11:59:08 +0530</pubDate><category>ssc</category><category>gsoc</category></item><item><title>GSOC 2011: ssc - Week 2</title><description>&lt;p&gt;In terms of user functionality, searching for software, templates, appliances and packages has been implemented this week. The actual api calls are performed by handler classes like SSC::Handler::Appliance which exposes public methods like list, show, repositories and installed_software. I&amp;#8217;m trying to follow a template that allows any command of the type ssc &amp;lt;class&amp;gt; &amp;lt;action&amp;gt; &amp;lt;arguments&amp;gt; to map directly to Class#action(arguments) with minimum modification along the way. The command line arguments (&amp;#8212;option value) are parsed into an options hash that keeps getting passed down the stack and used as necessary. Right now I&amp;#8217;m not happy about exposing data that is unnecessary for certain functions via this hash but it makes sense to have the checking of data in the handler action rather than at the top level which makes that inevitable.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s been some abstraction and refactoring to make way for having the .sscrc file what will hold the appliance configuration in the appliance directory. Right now there isn&amp;#8217;t a lot of validation of options and the parser merely merges options from .sscrc and the command line to pass into the various handlers.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;One tiny useful takeaway from this week has been learning about the Method class. Its very useful in meta-programming. For instance when calling methods with the Class#send method it would be useful to make sure that you&amp;#8217;re passing the correct number of arguments. The Method#arity method can be used to check the number of arguments that a method takes before passing arguments to it.&lt;/p&gt;
&lt;p&gt;Next week I&amp;#8217;m going to be focusing on the structure of the appliance directory and handling those commands that work locally.&lt;/p&gt;</description><link>http://rxvl.in/post/6175434117</link><guid>http://rxvl.in/post/6175434117</guid><pubDate>Sat, 04 Jun 2011 19:39:28 +0530</pubDate><category>ssc</category><category>gsoc</category><category>ruby</category></item><item><title>GSOC 2011: ssc - Week 1</title><description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My proposal for a command-line client for Suse Studio has been accepted for this year&amp;#8217;s Google Summer of Code. You can see the full proposal &lt;a href="http://www.google-melange.com/gsoc/proposal/review/google/gsoc2011/ratan/1"&gt;here&lt;/a&gt;. In short, the project is pretty self-evident from the title. In case you don&amp;#8217;t know what Suse Studio is, its a web service that allows you to design custom ISOs of linux distributions. As you can imagine, designing a custom variant of a linux distro will involve a lot of configuration. This tool aims to ease the hassles involved with using the web interface to make these customisations. The most common use case for this tool as I see it will be modifying default configuration files. The tool will allow you to make all the modifications you want locally in an appliance directory and push the changes when you&amp;#8217;re ready. If you want a more thorough view of how it will work please do read the &lt;a href="http://www.google-melange.com/gsoc/proposal/review/google/gsoc2011/ratan/1"&gt;complete proposal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Project Details:&lt;/strong&gt;&lt;br/&gt;Now that the introduction is out of the way, some updates about my implementation of this proposal. The coding period started a couple of days back. The code is going to be hosted on gitorious, &lt;a href="https://www.gitorious.org/ssc/ssc"&gt;here&lt;/a&gt;. I&amp;#8217;ll be pushing there almost daily and when we have a relatively stable version we&amp;#8217;ll push to the &lt;a href="http://gitorious.org/suse-studio/ssc"&gt;upstream repo&lt;/a&gt;. The rough timeline that I hope to follow is as outlined in the proposal:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;May 24th - Jun 5th: Create the framework for the command line  client. Get the option parsing working and implement some of the basic  search functionality.&lt;/li&gt;
&lt;li&gt;Jun 6th - Jun 19th: Implement the appliance directory management features.&lt;/li&gt;
&lt;li&gt;Jun 20th - 26th: Release a first alpha version for testing and reviews&lt;/li&gt;
&lt;li&gt;Jun 27th - Jul 11th: Tidy up, refactor code. Raise test coverage. Fix Bugs.&lt;/li&gt;
&lt;li&gt;Jul 12th - Jul 17th: Mid-Term Review&lt;/li&gt;
&lt;li&gt;Jul 17th - Jul 31st: Implement the commit, update and status commands.&lt;/li&gt;
&lt;li&gt;Aug 1st - Aug 15th: More testing, bug fixing and community review.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;High level documentation will be maintained on the &lt;a href="http://en.opensuse.org/openSUSE:SUSE_Studio_command_line_client#Google_Summer_of_Code"&gt;openSuse wiki&lt;/a&gt;. Once there is substantial code, the class/method level documentation will be hosted at rdoc.info.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Work Update:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ssc uses the studio_api gem to make API calls to Studio. While trying out the gem in preparation for this project, I made a small but important(at least I think so :)) &lt;a href="https://github.com/jreidinger/studio_api/issues/3"&gt;bug fix&lt;/a&gt; contribution to the project. It probably required someone with a crappy internet connection like mine to discover this.&lt;/p&gt;
&lt;p&gt;So far the code written is mostly framework stuff. There&amp;#8217;s an ArgumentParser that does the command line parsing. I&amp;#8217;m using mocha and shoulda for testing. I decided to bump the oh-so-cool rspec/cucumber frameworks for simple test unit. I&amp;#8217;ve used rspec in most of my projects and other than syntactical niceness I don&amp;#8217;t see what test unit lacks. I&amp;#8217;d like to try out that theory here.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;That&amp;#8217;s it for now I think. Not a lot, I know but hopefully, I will have more for you next time. Thanks for reading.&lt;/p&gt;</description><link>http://rxvl.in/post/5826361873</link><guid>http://rxvl.in/post/5826361873</guid><pubDate>Wed, 25 May 2011 11:38:27 +0530</pubDate><category>gsoc</category><category>opensuse</category><category>ssc</category></item><item><title>Bye Bye NerdTree. Hello CommandT</title><description>&lt;p&gt;CommandT is an awesome vim plugin made by  Wincent Colaiuta of &lt;a href="http://wincent.com"&gt;http://wincent.com&lt;/a&gt; . Its been around for a while but I wasn&amp;#8217;t able to use it earlier since it requires vim complied with ruby support which the standard Ubuntu vim package lacks. I tried compiling it from source but after a couple of hours of struggling to meet dependencies, I gave it up. Recently, I heard that v1.0 of the plugin had been released and figured the time was ripe for another attempt. Turns out what I had to do was crazy simple. On Ubuntu 10.04 just&lt;/p&gt;
&lt;p&gt;sudo apt-get install vim-gtk&lt;/p&gt;
&lt;p&gt;For some reason vim-ruby which is the only package you need is a virtual package included in vim-gtk, vim-nox or vim-gnome. So just install one of them, grab the &lt;a title="Command T" target="_blank" href="https://wincent.com/products/command-t"&gt;vba&lt;/a&gt;, open it up in vim and so :so %.&lt;/p&gt;
&lt;p&gt;This is way better than NerdTree and FuzzyFinder for file navigation for obvious reasons: It doesn&amp;#8217;t take up screen real estate, files are fewer key taps away and its blazingly fast. Enjoy using it.&lt;/p&gt;</description><link>http://rxvl.in/post/2308808766</link><guid>http://rxvl.in/post/2308808766</guid><pubDate>Tue, 14 Dec 2010 09:52:01 +0530</pubDate><category>vim</category><category>linux</category></item><item><title>node.js+ mogodb+ websockets </title><description>&lt;p&gt;Now there&amp;#8217;s an amazingly buzz-word laden title, if I  ever saw one. Anyway, if you, like me, have been hearing more and more  about of these terms floating around the interwebs in additions to  things like &amp;#8216;coffee script&amp;#8217;, &amp;#8216;nosql&amp;#8217;, &amp;#8216;event driven programming&amp;#8217;,  &amp;#8216;document-oriented databases&amp;#8217; etc. etc. read on for a gentle  introduction to new paradigms of programming, new server architectures  and new persistence layers.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve always found that the best way to get started with a new technology is to start writing code using it. Of course this &lt;em&gt;has&lt;/em&gt; to be followed by very in depth reading about the topic, but it helps  if you&amp;#8217;ve actually done something to follow along with what people are  writing. So in my quest to understand node.js, mongodb and HTML5  websockets, I chose to implement a very basic EtherPad( used in &lt;a href="http://typewith.me/"&gt;typewith.me&lt;/a&gt; ) &lt;a href="http://github.com/rjsvaljean/node-notepad"&gt;clone&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The components:&lt;/h2&gt;
&lt;h3&gt;&lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;From what I&amp;#8217;d heard about it, its a blazingly fast web server written in JavaScript running on &lt;a href="http://code.google.com/p/v8/"&gt;Google&amp;#8217;s V8 engine&lt;/a&gt;. I still haven&amp;#8217;t gotten to a stage where I can benchmark the code myself. But the benchmarks provided &lt;a href="http://debuggable.com/posts/node_js:4ab4d9d7-b788-41d4-85c0-1b51cbdd56cb"&gt;here&lt;/a&gt; looked really exciting. &lt;a href="http://nodejs.org/"&gt;Installing&lt;/a&gt; node was a cinch on my ubuntu system. The usual:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          $ wget http&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="com"&gt;//nodejs.org/dist/node-v0.1.99.tar.gz&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          $ tar xfz node&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="pln"&gt;v0&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="lit"&gt;1.99&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;tar&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;gz&lt;br/&gt;          $ &lt;/span&gt;&lt;span class="pun"&gt;./&lt;/span&gt;&lt;span class="pln"&gt;configure&lt;br/&gt;          $ make&lt;br/&gt;          $ sudo make install&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Brownie points to the node team for making the make tool give pretty output.&lt;/p&gt;
&lt;p&gt;The exciting, game-changing thing about node.js is of course &lt;a href="http://rxvl.in/post/en.wikipedia.org/wiki/Asynchronous_I/O"&gt;Evented I/O&lt;/a&gt;. The presentation below is the best explanation of the concept, that I&amp;#8217;ve come across so far.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a title="Evented I/O based web servers, explained using bunnies" href="http://www.slideshare.net/simon/evented-io-based-web-servers-explained-using-bunnies"&gt;Evented I/O based web servers, explained using bunnies&lt;/a&gt;&lt;/strong&gt; View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/simon"&gt;Simon Willison&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;&lt;a href="http://jashkenas.github.com/coffee-script"&gt;Coffee Script&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Since I was going to be writing JavaScript, I thought  I&amp;#8217;d kill two birds with one stone and look into Coffee Script which  helps you avoid JS&amp;#8217;s ugly ugly syntax. I would definitely recommend  investing the extra time learning this useful tool if you&amp;#8217;re going to be  developing for node.js or any JS library for that matter. Also as a  bonus you can run node.js apps directly using &lt;code&gt;coffee app.js&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;&lt;a href="http://rxvl.in/post/github.com/visionmedia/express"&gt;express&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;In three words this is: Sinatra for JS. Being a big fan  of the simplicity and transparency that sinatra offers, I pounced on  this particular framework for my app. The framework for node.js scene  had erupted recently with lots of exciting developments, including: A  standard base for frameworks to be built on (similar to ruby&amp;#8217;s rack): &lt;a href="http://rxvl.in/post/github.com/extjs/Connect"&gt;connect&lt;/a&gt;. Being developed by the fabulous guys behind &lt;a href="http://rxvl.in/post/www.sencha.com/products/js/"&gt;ExtJS&lt;/a&gt; (now Sencha). Connect is still however in its infancy and does not have much support.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;get&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'/'&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            &lt;/span&gt;&lt;span class="str"&gt;'Node says, Hello world!'&lt;/span&gt;&lt;span class="pln"&gt;  &lt;br/&gt;          &lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;a href="http://rxvl.in/post/github.com/visionmedia/kiwi"&gt;kiwi&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Pakage management for node.js libraries based on rubygems.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          $ kiwi install express&lt;br/&gt;          $ kiwi list&lt;br/&gt;          $ kiwi remove express&lt;br/&gt;          etc&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt; etc&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;I must add here that node.js is still at version 0.1.99  which is infancy compared to most software projects. And is by far not  the only server to incorporate Event-driven I/O and to be written in  JS(see the end of this article). It has however made sure that those  idioms extremely popular and has fostered development along those lines  in the ruby community and beyond as well. Think: &lt;a href="http://rxvl.in/post/rubyeventmachine.com"&gt;EventMachine&lt;/a&gt; and all &lt;a href="http://github.com/igrigorik/em-websocket"&gt;the&lt;/a&gt; &lt;a href="http://github.com/tmm1/em-mysql"&gt;em-*&lt;/a&gt; &lt;a href="http://github.com/igrigorik/async-rails"&gt;libraries&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://rxvl.in/post/www.mongodb.org"&gt;mongodb&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;So I needed a persistence layer for the app and wanting to use a &lt;a href="http://rxvl.in/post/en.wikipedia.org/wiki/NoSQL"&gt;NoSQL&lt;/a&gt; DB. I went for mongo coz&amp;#8217; &amp;#8230; well &amp;#8230; how do you not look into  something named mongo. Anyway mongo is a great place to start your  jouney to the Dark Side of The Moon, the moon being the database  implementations landscape.&lt;/p&gt;
&lt;p&gt;To get started playing with mongo, &lt;code&gt;sudo apt-get install mongodb&lt;/code&gt;.  This gives you a rather limiting mongo REPL where you can try stuff  out. When migrating from an RDBMS to mongo there are some changes in  vocabulary that you will have to embrace. Tables are collections and  rows/records are documents(hence document oriented db). I won&amp;#8217;t go into a  tutorial about mongodb as there are &lt;a href="http://www.mongodb.org/display/DOCS/Tutorial"&gt;quite&lt;/a&gt; &lt;a href="http://rxvl.in/post/try.mongodb.org"&gt;a&lt;/a&gt; &lt;a href="http://rxvl.in/post/www.mongodb.org/display/DOCS/Ruby+Tutorial"&gt;few&lt;/a&gt; of those out there. But, I&amp;#8217;ll try and cover some of the benefits.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;Dynamic Queries like:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;db&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;users&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;find&lt;/span&gt;&lt;span class="pun"&gt;({&lt;/span&gt;&lt;span class="pln"&gt;address&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;/[D|d]elhi/&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; age&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt; $lt &lt;/span&gt;&lt;span class="lit"&gt;25&lt;/span&gt;&lt;span class="pun"&gt;}).&lt;/span&gt;&lt;span class="pln"&gt;sort&lt;/span&gt;&lt;span class="pun"&gt;({&lt;/span&gt;&lt;span class="pln"&gt;name&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="lit"&gt;1&lt;/span&gt;&lt;span class="pun"&gt;})&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;That&amp;#8217;s right, I just queried a db with a regex. And chained  queries! Stuff, I could only do with an ORM that would ineffeciently  translate that into SQL.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;Neat JSON-like language for queries called &lt;a href="http://bsonspec.org/"&gt;BSON&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Embed has-many associations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          db&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;users&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;insert&lt;/span&gt;&lt;span class="pun"&gt;({&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            name&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'Ratan'&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            notes&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;              &lt;/span&gt;&lt;span class="pun"&gt;{&lt;/span&gt;&lt;span class="pln"&gt;content&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'The Daily Show is awesome ...'&lt;/span&gt;&lt;span class="pun"&gt;},&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;              &lt;/span&gt;&lt;span class="pun"&gt;{&lt;/span&gt;&lt;span class="pln"&gt;content&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'Jon Stewart is awesome ...'&lt;/span&gt;&lt;span class="pun"&gt;}&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            &lt;/span&gt;&lt;span class="pun"&gt;]&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="pun"&gt;})&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;No unnecessary  tables for holding strictly hierarchical data.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m sure there are many more but there are the ones  that I encountered within 2 days of using it. Another thing that I  should add here is the scalability promise of NoSQL DBs. Many users(me  included) are drawn to NoSQL by its horizontal scalability. This &lt;a href="http://jamesgolick.com/2010/3/29/most-nosql-dbs-are-not-scalable.html"&gt;article&lt;/a&gt; seems to debunk that, so i would advise further research before relying on that promise.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not in the best position to debate the pros and cons of &lt;a href="http://en.wikipedia.org/wiki/Document-oriented_database"&gt;document-oriented DBs&lt;/a&gt; vs. the traditional RDBMS. But I do think I can propose a rule of thumb  to decide between the two if your data fits well into either of the  models:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;use&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;NoSQL&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;if&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="kwd"&gt;no&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt; of objects central to your app&lt;/span&gt;&lt;span class="pun"&gt;)/(&lt;/span&gt;&lt;span class="kwd"&gt;no&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt; of small&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; supporting &lt;/span&gt;&lt;span class="kwd"&gt;and&lt;/span&gt;&lt;span class="pln"&gt; dependent objects&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="lit"&gt;1&lt;/span&gt;&lt;span class="pln"&gt;  &lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href="http://rxvl.in/post/dev.w3.org/html5/websockets/"&gt;websockets&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One of the most awaited aspects of HTML5 this  revolutionary protocol will make all the hackery featuring flashsockets  and jssockets to create real-time web apps  obsolete. Support is limited  to only chrome and safari currently but that is because the spec for  the protocol is not finalised yet. Firefox, waiting for the spec to be  finalised, will support it in Firefox 4 and IE &amp;#8230; well&amp;#8230; First  impressions of websockts are that its is extremely easy to use and will  be one of the prime uses for node.js apps. Writing your server and  client in JS gives the feeling of just on complete library connected by  passing JSON messages to each other.&lt;/p&gt;
&lt;p&gt;I used the extremely simple &lt;a href="http://github.com/ncr/node.ws.js"&gt;ws.js&lt;/a&gt; on the server side and &lt;a href="http://plugins.jquery.com/project/ws"&gt;jquery.ws.js&lt;/a&gt; on the client side. If you want a bit more power and flexibility, check out &lt;a href="http://rxvl.in/post/github.com/LearnBoost/Socket.IO-node"&gt;Socket.IO&lt;/a&gt; which comes with its own &lt;a href="https://github.com/LearnBoost/Socket.IO"&gt;client library&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;&lt;p&gt;Hope this cleared the air about a couple of these web dev  buzz words and encourages you to look further into it. While writing  this article a tweet from DHH brought &lt;a href="http://www.gmosx.com/blog/agVnbW9zeHIPCxIHQXJ0aWNsZRjh2gEM/"&gt;this&lt;/a&gt; to my attention. Clearly there is a lot out there beyond the  technologies out lined here and there are just current-popular  implementations of philosophies and ideas that have been around for a  while.&lt;/p&gt;</description><link>http://rxvl.in/post/2053806885</link><guid>http://rxvl.in/post/2053806885</guid><pubDate>Mon, 01 Nov 2010 06:16:00 +0530</pubDate><category>nosql</category><category>node.js</category><category>websockets</category></item><item><title>rxvl: The making of </title><description>&lt;p&gt;I&amp;#8217;ve been meaning for some time to write my own blogging  engine and now that I finally got the time I went for it. It was meant  to be a learning excercise so I tried to use tools and libraries that  I&amp;#8217;d never used before. I ended up chosing Sinatra for the framework to  write it in with an SQLite DB and using DataMapper as the ORM. Also, I  intended to host it on Heroku. In this article I&amp;#8217;ve described everything  from setting up my development environment for sinatra to finally  deploying it on Heroku. Enjoy!&lt;/p&gt;
&lt;h3&gt;Setting up&lt;/h3&gt;
&lt;p&gt;Our first goal is to get a basic, &amp;#8220;Hello World!&amp;#8221; Sinatra  app running with passenger and apache. You most probably have apache  and passenger setup, so feel free to skip the next bit. For those who  don&amp;#8217;t, you should. Setting up passenger is the easiest thing. I&amp;#8217;ve  written about it                 &lt;a href="http://rxvl.in/posts/passenger-guide"&gt; here &lt;/a&gt; .                 Set up a VirtualHost to point to a directory named  public in the directory where we&amp;#8217;re going to have our sinatra app  (/path/to/app/public). Create this empty directory. No special  configuration is required in the apcache config file just treat it like a  normal rails app. Now in /path/to/app lets create the sinatra app in  the file app.rb. For a basic Hello World! application it&amp;#8217;ll include  something like this:&lt;/p&gt;
&lt;pre class="ruby prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;get&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'/'&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;do&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            &lt;/span&gt;&lt;span class="str"&gt;"Hello World!"&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Next we need the rackup file, Sinatra being a rack framework. This is my config.ru:&lt;/p&gt;
&lt;pre class="ruby prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;require&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'sinatra'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;require&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'app.rb'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          root_dir&lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;File&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;dirname&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;__FILE__&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          ENV&lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;'RACK_ENV'&lt;/span&gt;&lt;span class="pun"&gt;]&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;||=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'development'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;set&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;environment&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; ENV&lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;'RACK_ENV'&lt;/span&gt;&lt;span class="pun"&gt;].&lt;/span&gt;&lt;span class="pln"&gt;to_sym&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;set&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;root&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; root_dir&lt;br/&gt;          disable &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;run&lt;br/&gt;          run &lt;/span&gt;&lt;span class="typ"&gt;Sinatra&lt;/span&gt;&lt;span class="pun"&gt;::&lt;/span&gt;&lt;span class="typ"&gt;Application&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;#8217;s it. Point your browser to the ServerName that  you&amp;#8217;d specified in that VirtualHost config and you should see Hello  World!&lt;/p&gt;
&lt;h3&gt;DataMapper&lt;/h3&gt;
&lt;p&gt;Now lets start writing the actual app. We start as with a  normal rails app with the models. As you can imagine, we&amp;#8217;d need a post  model. You would also usually use a comments model but I want to use  Disqus for my commenting system so I&amp;#8217;ll demonstrate inter-model  relationships with a category model. Post and Category have a has and  belongs to many relationship. I&amp;#8217;ll show you how to do that with  DataMapper. So first the migrations. Create db directory and create the  following migrations.rb file:&lt;/p&gt;
&lt;pre class="ruby prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="typ"&gt;DataMapper&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;setup&lt;/span&gt;&lt;span class="pun"&gt;(:&lt;/span&gt;&lt;span class="kwd"&gt;default&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; ENV&lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;'DATABASE_URL'&lt;/span&gt;&lt;span class="pun"&gt;]&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;||&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;"sqlite3:///home/sapna/src/testing/db/datastore.sqlite3"&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;Post&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           include &lt;/span&gt;&lt;span class="typ"&gt;DataMapper&lt;/span&gt;&lt;span class="pun"&gt;::&lt;/span&gt;&lt;span class="typ"&gt;Resource&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           property &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;id&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;Serial&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           property &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;title&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;String&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;required &lt;/span&gt;&lt;span class="pun"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;true&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           property &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;slug&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;String&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           property &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;file_name&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;String&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;required &lt;/span&gt;&lt;span class="pun"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;true&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           property &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;created_at&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;DateTime&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           has n&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;categorizations&lt;br/&gt;           has n&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;categories&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;through &lt;/span&gt;&lt;span class="pun"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;categorizations&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;Category&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           include &lt;/span&gt;&lt;span class="typ"&gt;DataMapper&lt;/span&gt;&lt;span class="pun"&gt;::&lt;/span&gt;&lt;span class="typ"&gt;Resource&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           property &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;id&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;Serial&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           property &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;name&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;String&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           has n&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;categorizations&lt;br/&gt;           has n&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;posts&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;through &lt;/span&gt;&lt;span class="pun"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;categorizations&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;Categorization&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           include &lt;/span&gt;&lt;span class="typ"&gt;DataMapper&lt;/span&gt;&lt;span class="pun"&gt;::&lt;/span&gt;&lt;span class="typ"&gt;Resource&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;           property &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;id&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;Serial&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;br/&gt;           belongs_to &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;category&lt;br/&gt;           belongs_to &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;post&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The explanation:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt; The first line defines the link to the database.  I&amp;#8217;ve used an sqlite database here. Setting up a connection to a mysql or  postgres DB should be no different. the ENV[&amp;#8216;DATABASE_URL&amp;#8217;] bit is for  heroku. My local database is the datastore.sqlite3 file. Once this is  delpoyed it&amp;#8217;ll get the information of the DB URL from heroku.                     &lt;strong&gt; DataMapper::Resource &lt;/strong&gt; is a module that you will have to include in all  your model classes. Since the migration is the first time I&amp;#8217;m defining  the model class Post I&amp;#8217;m including it there. &lt;/li&gt;
&lt;/ul&gt;&lt;li&gt; Next the                   &lt;strong&gt; property &lt;/strong&gt; lines. These as you might have guessed are used to  define the feilds of the post. Since I&amp;#8217;m defining a blogging engine to  read the post from a file rather than a database there are some  differences between the design here and a conventional Post. &lt;/li&gt;
&lt;li&gt; Note here that unlike ActiveRecord the id field isn&amp;#8217;t  automatically created for you you&amp;#8217;ll have to define it with the type  Serial. DataMapper takes care of the automatic updation of the field if  its of type Serial. Now coming to the HABTM relationship. Category as  you can see has only one field: name. Categorization is the mapping  table. it has only one property which is the id. Now relationships are  defined with the has and belongs_to methods. If you&amp;#8217;d wanted to define a  one to many relationship from post to category the post class would  have &lt;/li&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;has n &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;categories&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;and the Category class would have&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;belongs_to &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;post&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Extending the principle, you can see how what is shown  above would work. This gives you Category.new.posts and  Post.new.categories.&lt;/p&gt;</description><link>http://rxvl.in/post/2053772405</link><guid>http://rxvl.in/post/2053772405</guid><pubDate>Thu, 21 Oct 2010 06:13:00 +0530</pubDate><category>sinatra</category><category>ruby</category></item><item><title>Stuff I learnt writing Rubycious </title><description>&lt;p&gt;Day before yesterday, I released my del.icio.us API wrapper gem &lt;a href="http://github.com/rjsvaljean/rubycious"&gt;rubycious&lt;/a&gt;. There are a couple of things I learnt while writing it that I&amp;#8217;d like to share here. To give you a heads up on what&amp;#8217;s inside:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Meta-Programming&lt;/li&gt;
&lt;li&gt;class_eval&lt;/li&gt;
&lt;li&gt;self.included&lt;/li&gt;
&lt;li&gt;method_missing&lt;/li&gt;
&lt;li&gt;Documentation with YARD&lt;/li&gt;
&lt;li&gt;Publishing a gem&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;If that&amp;#8217;s piqued your curiousity &lt;a href="http://rxvl.in/post/stuff-i-learnt-writing-rubycious"&gt;click&lt;/a&gt; on through.&lt;/p&gt;
&lt;h3&gt;Meta-Programming&lt;/h3&gt;
&lt;p&gt;Before I go any further, I must warn you that some of  the choices I&amp;#8217;d made, design-wise weren&amp;#8217;t exactly the smartest and I  know that. But given those choices, I was faced with certain problems  that had to be solved and I&amp;#8217;m glad that it led me to learn about some  cool Ruby meta-programming.&lt;/p&gt;
&lt;h4&gt;class_eval&lt;/h4&gt;
&lt;p&gt;This is a class method which any object of type Class  has(by that I mean, of course, any ruby Class (Ain&amp;#8217;t ruby grand!)). It  takes a block and dynamically puts the contents of that block inside  your class. Now this is only useful if you have to dynamically add stuff  to your class. One oft-used use case of this facility is in conjunction  with self.included. Trivially though the following should illustrate  what class_eval can do&lt;/p&gt;
&lt;pre class="ruby prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; A&lt;br/&gt;            &lt;/span&gt;&lt;span class="kwd"&gt;def&lt;/span&gt;&lt;span class="pln"&gt; do_something&lt;br/&gt;              something&lt;br/&gt;            &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;br/&gt;          A&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;class_eval &lt;/span&gt;&lt;span class="kwd"&gt;do&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            &lt;/span&gt;&lt;span class="kwd"&gt;def&lt;/span&gt;&lt;span class="pln"&gt; something&lt;br/&gt;              puts &lt;/span&gt;&lt;span class="str"&gt;"Hello World!"&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Now there are a couple of other methods in the &lt;em&gt;eval&lt;/em&gt; family, namely, &lt;em&gt;instance_eval&lt;/em&gt;&lt;a href="http://ruby-doc.org/core/classes/Object.html#M000334"&gt;(1)&lt;/a&gt;&lt;a href="http://toolmantim.com/thoughts/instance_eval_brings_sexy_back"&gt;(2)&lt;/a&gt;, &lt;em&gt;module_eval&lt;/em&gt;(just an alias for class_eval) and just &lt;em&gt;eval&lt;/em&gt;&lt;a href="http://blog.jayfields.com/2006/07/ruby-eval-with-binding.html"&gt;(1)&lt;/a&gt;. They&amp;#8217;re equally cool and useful and to pretty much the same thing so I&amp;#8217;ll leave it to you to discover more about them.&lt;/p&gt;
&lt;h4&gt;self.included&lt;/h4&gt;
&lt;p&gt;This is basically a call_back defined for any module.  When it gets included in a class this method is run. The reason I&amp;#8217;m  calling it &lt;em&gt;self&lt;/em&gt;.included is usually its usage goes something like this:&lt;/p&gt;
&lt;pre class="ruby prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;module&lt;/span&gt;&lt;span class="pln"&gt; B&lt;br/&gt;            &lt;/span&gt;&lt;span class="kwd"&gt;def&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;self&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;included&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="kwd"&gt;base&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;              puts &lt;/span&gt;&lt;span class="kwd"&gt;base&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;However the really interesting use case, like I  mentioned earlier comes up when I put it together with class_eval like I  did in Rubycious &lt;a href="http://github.com/rjsvaljean/rubycious/blob/master/lib/client_helper.rb"&gt;here&lt;/a&gt;.  The module ClientHelper was meant to be included in any class that was a  client and I didn&amp;#8217;t want to redefine some of the httparty declarations  in each of these classes.&lt;/p&gt;
&lt;h4&gt;method_missing&lt;/h4&gt;
&lt;p&gt;This one is pretty basic and chances are you probably  know about this one. If not you really should. Basically method_missing  is the method called when a method called on an object is not found. It  takes a symbol which contains the name of the missing method and and  array of the arcuments passed to that method. The great thing about  method missing is that it can be used to generate an arbitrary number of  methods. See more &lt;a href="http://ruby-doc.org/core/classes/Kernel.html#M005925"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Documentation with YARD&lt;/h3&gt;
&lt;p&gt;YARD has emerged as the standard for documenting ruby projects of late, taking over from rdoc, and after using it to &lt;a href="http://rdoc.info/projects/rjsvaljean/rubycious"&gt;document rubycious&lt;/a&gt;,  I can see why. YARD uses a tagging based approach to documentation. It  uses directives like @param, @return, @see, @author etc. to structure  your documentation and give nicely readable docs in a variety of  formats. Read more about why you should use YARD &lt;a href="http://github.com/lsegal/yard"&gt;here&lt;/a&gt;. Here is an example of code documented with YARD from rubycious:&lt;/p&gt;
&lt;pre class="ruby prettyprint"&gt;&lt;span class="pln"&gt;                &lt;/span&gt;&lt;span class="com"&gt;# Use for searching all URLs&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# NOTE: Use Sparingly. Call the update function to see if you need to fetch this at all.&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @todo Look into caching these results&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# check the last update time before performing&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @param [Hash] options for searching for the URL (all optional)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @option options [String] :tag |optional| "ruby"&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @option options [String] :start |optional| Integer: Start returning posts this&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# many results into the set&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @option options [String] :results |optional| Integer: Return these many results&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @option options [String] :fromdt |optional| Format: Time#iso8601: On this date or later&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @option options [String] :todt |optional| Format: Time#iso8601: On this date or earlier&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @option options [String] :meta |optional| yes/no: Include change detection signatures&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# on each item in a 'meta' attribute. Clients wishing to maintain a&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# synchronized local store of bookmarks should retain the&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# value of this attribute - its value will change when any&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# significant field of the bookmark changes.&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @return [Array&amp;lt;:post&amp;gt;]&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="com"&gt;# @see Time#iso8601&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="kwd"&gt;def&lt;/span&gt;&lt;span class="pln"&gt; find&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;options&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                  response&lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; handle_errors &lt;/span&gt;&lt;span class="pun"&gt;{&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;self&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;get&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'/all'&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt;query &lt;/span&gt;&lt;span class="pun"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt; options&lt;/span&gt;&lt;span class="pun"&gt;)}&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                  response&lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;"posts"&lt;/span&gt;&lt;span class="pun"&gt;][&lt;/span&gt;&lt;span class="str"&gt;"post"&lt;/span&gt;&lt;span class="pun"&gt;].&lt;/span&gt;&lt;span class="pln"&gt;collect&lt;/span&gt;&lt;span class="pun"&gt;{|&lt;/span&gt;&lt;span class="pln"&gt;i&lt;/span&gt;&lt;span class="pun"&gt;|&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;Rubycious&lt;/span&gt;&lt;span class="pun"&gt;::&lt;/span&gt;&lt;span class="typ"&gt;Post&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;new&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;i&lt;/span&gt;&lt;span class="pun"&gt;)}&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;                &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;See more &lt;a href="http://github.com/rjsvaljean/rubycious/blob/master/lib/client.rb"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Publishing a Gem&lt;/h3&gt;
&lt;p&gt;I used &lt;a href="http://github.com/fauna/echoe"&gt;echoe&lt;/a&gt; for packaging and releasing the gem. Basically echoe creates a bunch of  rake tasks for you that take you through the process of creating a gem.  So, first you need to define a couple of defaults in your Rakefile:&lt;/p&gt;
&lt;pre class="ruby prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;require&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'rubygems'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;require&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'rake'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;require&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'echoe'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;br/&gt;          &lt;/span&gt;&lt;span class="typ"&gt;Echoe&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;new&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'rubycious'&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'0.1.1'&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;do&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;|&lt;/span&gt;&lt;span class="pln"&gt;p&lt;/span&gt;&lt;span class="pun"&gt;|&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            p&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;description &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;"Ruby wrapper to the del.icio.us API"&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            p&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;url &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;"http://github.com/rjsvlajean/rubycious"&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            p&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;author &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;"Ratan Sebastian"&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            p&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;email &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;"rjsvaljean@gmail.com"&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            p&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;ignore_pattern &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;"tmp/*"&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;"script/*"&lt;/span&gt;&lt;span class="pun"&gt;]&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            p&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;development_dependencies &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;"httparty"&lt;/span&gt;&lt;span class="pun"&gt;]&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;end&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;br/&gt;          &lt;/span&gt;&lt;span class="typ"&gt;Dir&lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;"/tmp/tasks/*.rake"&lt;/span&gt;&lt;span class="pun"&gt;].&lt;/span&gt;&lt;span class="pln"&gt;sort&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;each &lt;/span&gt;&lt;span class="pun"&gt;{&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;|&lt;/span&gt;&lt;span class="pln"&gt;ext&lt;/span&gt;&lt;span class="pun"&gt;|&lt;/span&gt;&lt;span class="pln"&gt; load ext &lt;/span&gt;&lt;span class="pun"&gt;}&lt;/span&gt;&lt;span class="pln"&gt; e&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Next assuming that all your code is in your lib directory and you have a file having the same name as your gem in there, run:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          $ rake manifest&lt;br/&gt;          $ rake build_gemspec&lt;br/&gt;          $ gem build rubycious&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="lit"&gt;0.1&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="lit"&gt;1.gemspec&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          $ gem push rubycious&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="lit"&gt;0.1&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="lit"&gt;1.gem&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;#8217;s about it for now. I plan on doing a  rewrite with a bit of a better design soon but for now Rubycious is  pretty stable for those using basic auth. I&amp;#8217;ll add oauth support soon in  a couple of days and I&amp;#8217;ll document the procedure here.&lt;/p&gt;</description><link>http://rxvl.in/post/2053782300</link><guid>http://rxvl.in/post/2053782300</guid><pubDate>Mon, 04 Oct 2010 06:13:00 +0530</pubDate><category>ruby</category><category>gem</category><category>rubycious</category></item><item><title>vim tips</title><description>&lt;h2&gt;vim tips&lt;/h2&gt;
&lt;p&gt;So, I&amp;#8217;ve been using vim for my ruby/rails dev of late  and I thought I&amp;#8217;d share a few things I picked up along the way. Another  tool that I&amp;#8217;ve begun relying on heavily is GNU screen. It didn&amp;#8217;t make  sense to put that in a separate post so I&amp;#8217;m going to include some of my  screen setup here as well. This is primarily aimed at people who&amp;#8217;ve  already begun with vim and are looking for examples of development  setups.&lt;/p&gt;
&lt;h2&gt;The Tools:&lt;/h2&gt;
&lt;h3&gt;vim&lt;/h3&gt;
&lt;p&gt;One of the core features of vim that you&amp;#8217;ll find  amazingly useful is the split screen. Incredibly useful when dealing  with multiple files that you constantly have to refer to(while writing  tests for instance). For more about some handy core features have a look  at my &lt;a href="http://github.com/rjsvaljean/vim_config/blob/master/vimrc"&gt;.vimrc&lt;/a&gt;.               Of course the real power of vim is in its amazing  repository of plugins(advantage of being a nearly 20 year old project).  Some of the ones that I find indispensible are:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt; &lt;a href="http://rxvl.in/post/ls.vim.tpope.net"&gt;rails.vim&lt;/a&gt;: The most basic plugin that you &lt;em&gt;will&lt;/em&gt; need for rails development.&lt;/li&gt;
&lt;li&gt; &lt;a href="http://www.vim.org/scripts/script.php?script_id=1657"&gt;NERD_tree&lt;/a&gt;: File browser.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://wincent.com/products/command-t/"&gt;command-t&lt;/a&gt;: File finder&lt;/li&gt;
&lt;li&gt; &lt;a href="http://rxvl.in/post/github.com/tpope/vim-fugitive"&gt;fugitive&lt;/a&gt;: git integration done right&lt;/li&gt;
&lt;li&gt; &lt;a href="http://www.vim.org/scripts/script.php?script_id=2286"&gt;specky&lt;/a&gt;: makes specs your friend again.&lt;/li&gt;
&lt;li&gt; &lt;a href="http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/"&gt;irb_slime.vim&lt;/a&gt;: For integrating irb and vim through screen&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;For my complete .vim folder clone &lt;a href="http://github.com/rjsvaljean/vim_config"&gt;git://github.com/rjsvaljean/vim_config.git&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;screen&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://rxvl.in/post/www.gnu.org/software/screen"&gt;GNU&lt;/a&gt; &lt;a href="http://www.delorie.com/gnu/docs/screen/screen_toc.html"&gt;screen&lt;/a&gt; is one of those tools, that, once you&amp;#8217;re exposed to will become  essential to any sort of terminal intensive work that you do. I like to  think of it as a window manager for your terminal. It basically hosts a  bunch of terminals in different windows(tabs) and makes sure that you  never have to Alt-Tab again. But of course its much more than that the  killer feature is that ability to detach screen sessions. I do most of  my development on a laptop which I almost never shutdown. So I&amp;#8217;m working  in my screen for project A, when I need to switch, I don&amp;#8217;t need to  worry about shutting down the various programs safely. I just need to  detach the session and re-attach when I need it. This way I get back to  work with no interuptions. It nicely allows you to keep all the terminal  based programs that you run with a particular project in one place.&lt;/p&gt;
&lt;h2&gt;Bringing it all together&lt;/h2&gt;
&lt;p&gt;As I&amp;#8217;d put in the list of plugins &lt;a href="http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/"&gt;this&lt;/a&gt; ties vim, irb and screen together nicely. Next master fugitive(which is  alarmingly simple to use) and you&amp;#8217;ve got SCM integration in your  editor. Its starting to look more like an IDE, isn&amp;#8217;t it? Now sugar coat  the whole deal by opening vim up in your project directory within a  screen session. But of course development seldom involves just your  editor so go ahead and open a bung of windows for your REPL, your test  running window, IRC client etc. etc. But you don&amp;#8217;t want ot keep  repeating this every time you start a screen session of a different  project. What I do is create a project specific .screenrc which in my  project root directory with a bunch of &lt;code&gt;screen -t&lt;/code&gt; declarations to open the windows that I need for that project and add an alias to my &lt;code&gt;~/.bashrc.&lt;/code&gt; Something like:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="kwd"&gt;alias&lt;/span&gt;&lt;span class="pln"&gt; work&lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="str"&gt;"screen -c .screenrc"&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;This I find works pretty well. Additionally the  irb_slime plugin I&amp;#8217;d mentioned eariler requires you to specify the  screen session name and the name of the window where your REPL is  running. You only have to do this the first time but its still pretty  annoying. To automate things further do the following in your .screerc&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          screen &lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="pln"&gt;t vim &lt;/span&gt;&lt;span class="lit"&gt;0&lt;/span&gt;&lt;span class="pln"&gt; vim &lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="pln"&gt;c &lt;/span&gt;&lt;span class="str"&gt;'let g:screen_sessionname=session'&lt;/span&gt;&lt;span class="pun"&gt;\&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="pln"&gt;c &lt;/span&gt;&lt;span class="str"&gt;'let g:screen_windowname=repl'&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;That makes sure that once you execute work in your project directory you&amp;#8217;re all ready to start hacking.&lt;/p&gt;
&lt;p&gt;Hope this helps!&lt;/p&gt;</description><link>http://rxvl.in/post/2053757576</link><guid>http://rxvl.in/post/2053757576</guid><pubDate>Wed, 22 Sep 2010 06:11:00 +0530</pubDate><category>vim</category><category>linux</category></item><item><title>passenger + apache + NameVirtualHosts</title><description>&lt;p&gt;Everyone knows how to setup passenger and apache on a  linux box. But if you have multiple apps, its a pain keeping track of  all the localhost port numbers that point to each of them. In this  article I discuss you can have addresses like myapp.mybox.lan to point  ot specific apps. I&amp;#8217;ve written this for a linux system but it should  work just as well for a Mac. Also, I haven&amp;#8217;t tried this out with ngnix.  I&amp;#8217;ve also gone through the setting up of Passenger for those of you who  still use script/server.&lt;/p&gt;
&lt;h3&gt;Setting up Passenger&lt;/h3&gt;
&lt;p&gt;Installing the passenger apache modules is as easy as:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          $ gem install passenger&lt;br/&gt;          $ passenger&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="pln"&gt;install&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="pln"&gt;apache2&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="kwd"&gt;module&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt; That will download and compile passenger&amp;#8217;s apache  modules. Once compiled the installer will give you instructions to load  these modules using apache configuration directives. You&amp;#8217;ll probably  have to edit your apache configuration file for that. If you&amp;#8217;re on  linux, these will probably be in /etc/apache2/[apache2.conf|httpd.conf].  Just append the three lines that the installer gives you to this file.  They&amp;#8217;ll look something like this:&lt;/p&gt;
&lt;pre class="ruby prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="typ"&gt;LoadModule&lt;/span&gt;&lt;span class="pln"&gt; passenger_module &lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;home&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;rjsvaljean&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;dev&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ruby&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;lib&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ruby&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;gems&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="lit"&gt;1.8&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;gems&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;passenger&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="lit"&gt;2.2&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="lit"&gt;11&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ext&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;apache2&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;mod_passenger&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;so&lt;br/&gt;          &lt;/span&gt;&lt;span class="typ"&gt;PassengerRoot&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;home&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;rjsvaljean&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;dev&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ruby&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;lib&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ruby&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;gems&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="lit"&gt;1.8&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;gems&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;passenger&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="lit"&gt;2.2&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="lit"&gt;11&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="typ"&gt;PassengerRuby&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;home&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;rjsvaljean&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;dev&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ruby&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;bin&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ruby&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;Creating the domains&lt;/h3&gt;
&lt;p&gt;Once that&amp;#8217;s done lets create our rails app in  /path/to/app/blog. In order to demonstrate how to create different  addresses for different apps create another app at  /path/to/app/todolist. Say that we want those two apps accessible at  blog.lan and todolist.lan. Notice that I&amp;#8217;ve use the TLD .lan but that&amp;#8217;s  completely aribitrary. You can use anything that you want. Now comes the  bit where we tell your computer to got to localhost when you point your  browser to blog.lan. For this we need to edit our                 &lt;strong&gt; /etc/hosts &lt;/strong&gt; file. You&amp;#8217;ll need to be root to edit it. Add the following two lines:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="lit"&gt;127.0&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="lit"&gt;0.1&lt;/span&gt;&lt;span class="pln"&gt;    blog&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;lan&lt;br/&gt;          &lt;/span&gt;&lt;span class="lit"&gt;127.0&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="lit"&gt;0.1&lt;/span&gt;&lt;span class="pln"&gt;    todolist&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;lan&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;Creating &amp;#8216;NameVirtualHost&amp;#8217;s&lt;/h3&gt;
&lt;p&gt;Now we need to instruct apache where to look when it  gets a request for blog.lan. Open up the config file once more. First  you need to declare that Named VirtualHosts are running on post 80 -  your default port for http requests. To do that:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="typ"&gt;NameVirtualHost&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;*:&lt;/span&gt;&lt;span class="lit"&gt;80&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Now define your VirtualHost sections:&lt;/p&gt;
&lt;pre class="xml prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;VirtualHost&lt;/span&gt;&lt;span class="pln"&gt; *:80&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            ServerName blog.lan&lt;br/&gt;            DocumentRoot /path/to/app/blog/public&lt;br/&gt;          &lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;VirtualHost&lt;/span&gt;&lt;span class="pln"&gt; *:80&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;            ServerName todolist.lan&lt;br/&gt;            DocumentRoot /path/to/app/todolist/public&lt;br/&gt;          &lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Now reload apache with &amp;#8216;/etc/init.d/apache2 reload&amp;#8217; and  you&amp;#8217;re done. Pointing your browser to blog.lan or todolist.lan whould  show you the default rails page for a new app.&lt;/p&gt;</description><link>http://rxvl.in/post/2053746802</link><guid>http://rxvl.in/post/2053746802</guid><pubDate>Thu, 09 Sep 2010 06:10:00 +0530</pubDate><category>apache</category><category>linux</category><category>passenger</category><category>rails</category></item><item><title>Some notes on cron, whenever and rake</title><description>&lt;p&gt;I recently had to set up some cron jobs from an app that I  was writing. I learned a couple of things so I thought I&amp;#8217;d put them  here. I&amp;#8217;ve covered setting up precisely fortnightly cron jobs, setting  up the whenever gem and how I tackled some of the errors that I came up  against while trying to set it up.&lt;/p&gt;
&lt;h2&gt;Fortnightly Jobs&lt;/h2&gt;
&lt;p&gt;Setting up precisely fortnightly jobs that need to run  on every other monday is quite easy. You don&amp;#8217;t have to settle for just  running the jobs on the 1st and the 15th. Set your job to run onw  whichever day of the week that you want it to and set it to run every  week. Include this in the actual command to be run:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;expr &lt;/span&gt;&lt;span class="str"&gt;`date +\%W`&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;\%&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="lit"&gt;2&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;/dev/&lt;/span&gt;&lt;span class="kwd"&gt;null&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;||&lt;/span&gt;&lt;span class="pln"&gt; fortnightly_script&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;sh&lt;/span&gt;&lt;/pre&gt;
&lt;h2&gt;Whenever&lt;/h2&gt;
&lt;p&gt;Whenever(                 &lt;a href="http://github.com/javan/whenever"&gt; github link &lt;/a&gt; ) is a nifty gem that you can use to modify your crontab  easily from your application using some sort of capistrano recipie of  rake task. First off install the gem with&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          $ gem install whenever&lt;br/&gt;          $ wheneverize  &lt;/span&gt;&lt;span class="com"&gt;# Excute this inside your app to setup the necessary files&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Now edit the schedule.rb file where you can easily  define your jobs in plain ruby. Now you can run the binary whenever  &amp;#8212;update-crontab to update your crontab cleanly from your capistrano  recipies. When I tried to run the command however I ran into some  difficulties. Read on &amp;#8230;&lt;/p&gt;
&lt;h2&gt;Error: Rakefile: undefined method `importâ€™ for main:Object (NoMethodError)&lt;/h2&gt;
&lt;p&gt;I ran into this error while trying to use the whenever  gem in my app. Whenever I tried to run the whenever command I got this  error:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pln"&gt;          &lt;/span&gt;&lt;span class="pun"&gt;./&lt;/span&gt;&lt;span class="typ"&gt;Rakefile&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="lit"&gt;3&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="kwd"&gt;undefined&lt;/span&gt;&lt;span class="pln"&gt; method &lt;/span&gt;&lt;span class="str"&gt;`import' for main:Object (NoMethodError)&lt;br/&gt;          from /opt/ruby-enterprise-1.8.7-2009.10/lib/ruby/gems/1.8/gems/whenever-0.4.1/lib/whenever.rb:5:in `&lt;/span&gt;&lt;span class="pln"&gt;load&lt;/span&gt;&lt;span class="str"&gt;'&lt;br/&gt;          from /opt/ruby-enterprise-1.8.7-2009.10/lib/ruby/gems/1.8/gems/whenever-0.4.1/lib/whenever.rb:5&lt;br/&gt;          from /opt/ruby-enterprise-1.8.7-2009.10/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br/&gt;          &lt;/span&gt;&lt;span class="kwd"&gt;from&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;opt&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ruby&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="pln"&gt;enterprise&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="lit"&gt;1.8&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="lit"&gt;7&lt;/span&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="lit"&gt;2009.10&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;lib&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;ruby&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;site_ruby&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="lit"&gt;1.8&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;rubygems&lt;/span&gt;&lt;span class="pun"&gt;/&lt;/span&gt;&lt;span class="pln"&gt;custom_require&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;rb&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="lit"&gt;31&lt;/span&gt;&lt;span class="pun"&gt;:&lt;/span&gt;&lt;span class="kwd"&gt;in&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;`require'&lt;br/&gt;          from /opt/ruby-enterprise-1.8.7-2009.10/lib/ruby/gems/1.8/gems/whenever-0.4.1/bin/whenever:7&lt;br/&gt;          from /opt/ruby-enterprise-1.8.7-2009.10/bin/whenever:19:in `&lt;/span&gt;&lt;span class="pln"&gt;load&lt;/span&gt;&lt;span class="str"&gt;'&lt;br/&gt;          from /opt/ruby-enterprise-1.8.7-2009.10/bin/whenever:19'''''&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt; I fixed this by adding&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="kwd"&gt;require&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'rake'&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;at the beginning of my Rakefile. I&amp;#8217;m still not sure what  exactly the problem was and how that line solved it. Maybe some of you  more knowledgeable netizens could clear it up.&lt;/p&gt;</description><link>http://rxvl.in/post/2053733875</link><guid>http://rxvl.in/post/2053733875</guid><pubDate>Fri, 06 Aug 2010 06:09:00 +0530</pubDate><category>ruby</category><category>rake</category><category>error</category></item></channel></rss>

