<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>Sirupsen</title>
 
 <link href="http://sirupsen.github.com/" />
 <updated>2012-02-22T22:15:38-08:00</updated>
 <id>http://sirupsen.github.com</id>
 <author>
   <name>Sirupsen</name>
   <email>sirup@sirupsen.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Sirupsen" /><feedburner:info uri="sirupsen" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>Quotes</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/f7NPhIjY5Aw/quotes" />
   <updated>2011-07-31T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/quotes</id>
   <content type="html">&lt;p&gt;Quotes are beautiful, because beauty is raising curiosity.&lt;/p&gt;

&lt;p&gt;This is my evolving growing list of favorite quotes. Originally I planned to add why I like them, but I&amp;rsquo;ve left them beautiful.&lt;/p&gt;

&lt;p&gt;“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.”
&amp;ndash; Antoine de Saint-Exupery&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Make things as simple as possible but no simpler.&amp;rdquo;
&amp;ndash; Albert Einstein&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Less is more.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Those who are crazy enough to think they can change the world usually do.&amp;rdquo;
&amp;ndash; Steve Jobs&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Don&amp;rsquo;t compare yourself to others. Compare yourself to the progress you&amp;rsquo;ve made.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;&amp;ldquo;The potential of greater good goes right along with the potential for greater evil.&amp;rdquo;
&amp;ndash; Larry Wall&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Humans are allergic to change. They love to say, &amp;lsquo;We&amp;rsquo;ve always done it this way.&amp;rsquo; I try to fight that. That&amp;rsquo;s why I have a clock on my wall that runs counter-clockwise.&amp;rdquo;
&amp;ndash; Grace Hooper&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Great minds discuss ideas. Average minds discuss events. Small minds discuss people.&amp;rdquo;
&amp;ndash; Eleanor Roosevelt&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Everything goes with bacon!&amp;rdquo;
&amp;ndash; Grant Achatz, Alinea&lt;/p&gt;

&lt;p&gt;&amp;ldquo;In theory there is no difference between theory and practice. But, in practice, there is.&amp;rdquo;
&amp;ndash; Jan van de Snepscheut&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Experience is what you get when you didn&amp;rsquo;t get what you wanted.&amp;rdquo;
&amp;ndash; Randy Pausch&lt;/p&gt;

&lt;p&gt;&amp;ldquo;When you don&amp;rsquo;t create things, you become defined by your tastes rather than ability. So create.&amp;rdquo;
&amp;ndash; why&lt;/p&gt;

&lt;p&gt;&amp;ldquo;If you live each day as it was your last, someday you&amp;rsquo;ll most certainly be right.&amp;rdquo;
&amp;ndash; Steve Jobs&lt;/p&gt;

&lt;p&gt;&amp;ldquo;You can&amp;rsquo;t connect the dots looking forward; you can only connect them looking backwards.&amp;rdquo;
&amp;ndash; Steve Jobs&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Stay hungry, stay foolish.&amp;rdquo;
&amp;ndash; Whole Earth Catalog&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Make every detail perfect. Limit the number of details.&amp;rdquo;
&amp;ndash; Jack Dorsey&lt;/p&gt;

&lt;p&gt;&amp;ldquo;If I had asked people what they wanted, they would have said faster horses.&amp;rdquo;
&amp;ndash; Henry Ford&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Pressure makes diamonds"&lt;br/&gt;
&amp;ndash; General George S. Patton&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Change only takes place through action.&amp;rdquo;
&amp;ndash; Dalai Lama&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Bad ideas are just waiting to become bad ass.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Shut the hell up and do it.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;&amp;ldquo;The greatest advantage usually&amp;rsquo;s also the biggest disadvantage.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Experience comes from bad judgement.&amp;rdquo;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/f7NPhIjY5Aw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/quotes</feedburner:origLink></entry>
 
 <entry>
   <title>Paperless with Evernote</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/WH1OE502st0/paperless-with-evernote" />
   <updated>2011-07-26T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/paperless-with-evernote</id>
   <content type="html">&lt;p&gt;As a student, I get tons of paper everyday. The greatest issue with paper is finding the right one once it&amp;rsquo;s needed, without going through every single paper you have. Organizing paper is tedious.&lt;/p&gt;

&lt;p&gt;This is where computers shine. You don&amp;rsquo;t even have to invent fancy directory structures; Spotlight in OS X, or Search in Windows can match you up with the right file with just a few keystrokes.&lt;/p&gt;

&lt;p&gt;That said, paper has great advantages attached, too &amp;mdash; it&amp;rsquo;s brilliant for e.g. sketching and brainstorming. I wouldn&amp;rsquo;t ever leave paper completely behind, I use my Moleskin frequently for these kinds of tasks, but that&amp;rsquo;s about the only paper I use. A hybrid-solution is &lt;a href="http://www.livescribe.com/en-us/"&gt;Livescribe&lt;/a&gt;, I have one, and used it for some time, but eventually ditched it: the pros of writing notes directly on the computer outweighed the pros of using Livescribe, simply because I can type faster on my computer.&lt;/p&gt;

&lt;p&gt;By being paperless you&amp;rsquo;ll use less time searching through your paper stacks, you&amp;rsquo;ll become much more organized, and you&amp;rsquo;ll always have your paper at hand.&lt;/p&gt;

&lt;p&gt;Nowadays I scan everything with my &lt;a href="http://www.getdoxie.com/"&gt;Doxie&lt;/a&gt;, you can use any scanner, of course, if you don&amp;rsquo;t already have one though, get the Doxie. It&amp;rsquo;s compact, portable, scans in good quality and &lt;a href="http://www.getdoxie.com/store/faq_ajax.html#hearts"&gt;has hearts on it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All the scanned documents go to &lt;a href="http://www.evernote.com/about/referrer?code=Simo8188"&gt;Evernote&lt;/a&gt; for four reasons: first being that it&amp;rsquo;s all in the cloud, that means I can access my documents anywhere, which brings me to the second reason: great mobile apps. Third, the search functionality is excellent and that becomes even better due the final reason, OCR &amp;mdash; Optical Character Recognizition &amp;mdash; all my scanned document PDFs are scanned for text, and Evernote&amp;rsquo;s search will search through this text as well.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://f.cl.ly/items/2T3a182G0C1M463K2i46/Screen%20Shot%202011-07-26%20at%2020.51.36%20.png" alt="Picture example of Evernote's OCR" /&gt;&lt;/p&gt;

&lt;p&gt;That means all your papers' text are searchable by Evernote. It even recognizes handwriting. OCR happens in Evernote&amp;rsquo;s cloud and the metadata is synced along with your notes so it&amp;rsquo;ll work everywhere Evernote works.&lt;/p&gt;

&lt;p&gt;Every sunday I scan new paper acquired during the previous week, the Doxie software puts the scanned papers directly into Evernote, I give it a descriptive title, throw out the paper, and I&amp;rsquo;m done. That&amp;rsquo;s it.&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t use tags, special notebooks, or any of Evernote&amp;rsquo;s other fancy organization features. There&amp;rsquo;s simply no need with Evernote&amp;rsquo;s fantastic searching capabilities. I only follow a simple syntax for my notes' titles:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &amp;lt;area&amp;gt; &amp;lt;title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;receipt doxie scanner&lt;/li&gt;
&lt;li&gt;sirupsen.com paperless post&lt;/li&gt;
&lt;li&gt;recipe dad&amp;rsquo;s lasagna&lt;/li&gt;
&lt;li&gt;physics potential energy&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If I want to browse all my receipts, I search for &amp;ldquo;receipt&amp;rdquo;, if I want all notes containing &amp;ldquo;Doxie&amp;rdquo; I search for Doxie, and Evernote would return &amp;ldquo;receipt doxie scanner&amp;rdquo; and &amp;ldquo;sirupsen.com paperless post&amp;rdquo; to me. You should definitely get Evernote premium if you start using it for your scanned documents for prioritized OCR on their servers, more storage and to support an excellent service.&lt;/p&gt;

&lt;p&gt;For quick scans on the go, mostly receipts, I use &lt;a href="http://itunes.apple.com/us/app/jotnot-scanner-pro/id307868751?mt=8"&gt;JotNot Pro&lt;/a&gt; iPhone &amp;mdash; it works great and can throw the pictures directly to the Evernote app.&lt;/p&gt;

&lt;p&gt;In classes I take notes directly in Evernote for several reasons. Typing on the computer is simply heaps faster than writing on paper, the only thing I miss from paper is the ability to make quick, rough illustrations.&lt;/p&gt;

&lt;p&gt;As physics and mathematics are part of my school work I frequently have to put equations into my notes. Evernote has no built-in functionality that lets you do this, but &lt;a href="http://www.chachatelier.fr/latexit/latexit-home.php?lang=en"&gt;LaTeXiT&lt;/a&gt; that comes with the &lt;a href="http://www.tug.org/mactex/2011/"&gt;MacTex&lt;/a&gt; bundle comes with a service that lets you transform LaTeX math to pretty pictures:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://f.cl.ly/items/1j0Z3Q0o0K1g3z082k03/Screen%20Shot%202011-07-26%20at%2020.39.36%20.png" alt="LaTeX equation transforming with LaTeXiT" /&gt;&lt;/p&gt;

&lt;p&gt;Gives you:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://f.cl.ly/items/3t2P2D1m2B1a01451g33/Screen%20Shot%202011-07-26%20at%2020.41.21%20.png" alt="Result picture from LaTeXiT transformagic" /&gt;&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m no pro in Automator, if you happen to know how to create this functionality indepent of LaTeXiT (because LaTeXiT is slow), please contact me and I&amp;rsquo;ll include it here.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/WH1OE502st0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/paperless-with-evernote</feedburner:origLink></entry>
 
 <entry>
   <title>How I get shit done</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/u_RIy56mLfk/how-I-get-shit-done" />
   <updated>2011-05-28T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/how-I-get-shit-done</id>
   <content type="html">&lt;p&gt;Today I decided to ditch my to do list.&lt;/p&gt;

&lt;p&gt;The important tasks will constantly nag me, thus the most important tasks will always be fresh in my head. I never forget the main tasks.&lt;/p&gt;

&lt;p&gt;I do, however, forget the minor, less important tasks. The actually used part of my to do list ended up being a shopping list, and I don&amp;rsquo;t need a full-blown GTD-application to keep track of my errands. The other minor tasks I&amp;rsquo;d forget were 2-minute tasks. Resolved easily by doing the task immediately after thinking of it instead of deferring it.&lt;/p&gt;

&lt;p&gt;The real problem I was trying to solve with my to do list was procrastinating. Every Sunday I now make a list of what I need to do in the coming week, writing down tasks for each day, scattering the major tasks throughout the week. Now when I&amp;rsquo;m done with the day&amp;rsquo;s tasks I can relax feeling confident I&amp;rsquo;m on track for the week. That&amp;rsquo;s real relaxation.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/u_RIy56mLfk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/how-I-get-shit-done</feedburner:origLink></entry>
 
 <entry>
   <title>Stop relying on your ORM and learn SQL</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/zg0nNyQGpVc/stop-relying-on-your-orm-and-learn-sql" />
   <updated>2011-03-02T00:00:00-08:00</updated>
   <id>http:/sirupsen.github.com/stop-relying-on-your-orm-and-learn-sql</id>
   <content type="html">&lt;p&gt;In modern development, and in particular with web frameworks such as Rails that offer and encourage extensive use of database ORM libraries, some developers skip learning SQL in favour of using ORMs. It is as if developers think they no longer need to know SQL when they&amp;rsquo;ve got an ORM. The truth is that we are not this fortunate. You should &lt;em&gt;only&lt;/em&gt; use an ORM if you know exactly what it is generated by the ORM and you are sure that the generated SQL is as well performing as what you could have written by hand.&lt;/p&gt;

&lt;p&gt;Let me go through the most common pitfall I see.&lt;/p&gt;

&lt;p&gt;You have a blog listing a bunch of posts: title, content, author, date and the number of associated comments.&lt;/p&gt;

&lt;p&gt;Typically one would do it like this in Rails:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="erb"&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="vi"&gt;@posts&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;  &amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;  &amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;  &amp;lt;p&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt; posted on &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;comments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt; comments&lt;/span&gt;
&lt;span class="x"&gt;  &amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This looks simple enough, and it is &amp;mdash; the issue here is the query for retrieving the number of comments associated (&lt;code&gt;post.comments.count&lt;/code&gt;) is run for each blog post, although it could easily be included in the main SQL query fetching the posts with a join:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="sql"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;comments_count&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;users&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;comments&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Or in Rails' ORM:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:joins&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:comments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:select&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;posts.*, count(comments.id) as comments_count&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:group&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;posts.id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;For a typical blog an extra 20 count queries are not critical, but once your database reaches a certain size a noticeable, avoidable, delay will occur on that page. Something that could have been avoided with a basic understanding of SQL.&lt;/p&gt;

&lt;p&gt;ORMs are indeed very useful to developers, however you should not neglect learning SQL because you have it.&lt;/p&gt;

&lt;p&gt;Every time you use your ORM you should stop for a moment and think to yourself: &amp;ldquo;Can I be sure the ORM is generating the optimum query possible here?&amp;rdquo;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/zg0nNyQGpVc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/stop-relying-on-your-orm-and-learn-sql</feedburner:origLink></entry>
 
 <entry>
   <title>Improving the Open Source user experience</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/x8bzsdF4tN0/improving-the-open-source-user-experience" />
   <updated>2011-02-25T00:00:00-08:00</updated>
   <id>http:/sirupsen.github.com/improving-the-open-source-user-experience</id>
   <content type="html">&lt;h2&gt;Draft&lt;/h2&gt;

&lt;p&gt;I absolutely love open source, I contribute myself and I use tons of open source software every day. I am attached to the idea that what I use is completely open, I can change everything about it if I want, I can figure out how it works, learn from it, contribute to it. Open source is many things: browsers, databases, operating systems and what not.&lt;/p&gt;

&lt;p&gt;However, there&amp;rsquo;s one thing I always thought could be drastically improved in many open source projects: The User Experience. When I ask a not-so-techinal friend why they don&amp;rsquo;t use &lt;em&gt;some open source project instead of commercial one&lt;/em&gt; many say that &amp;ldquo;it&amp;rsquo;s because ugly&amp;rdquo;. What they mean by ugly is that it&amp;rsquo;s hard to find what you are looking for in the interface, and yeah, it&amp;rsquo;s usually not eye candy either.&lt;/p&gt;

&lt;p&gt;Most open source projects have no designers attached. However, some do, for instance &lt;a href="https://wiki.ubuntu.com/Artwork"&gt;Ubuntu&lt;/a&gt;, most people, again non-techinal people, I know like Ubuntu because it&amp;rsquo;s pretty and easy to use:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;For every % in sales invested in product design, a company&amp;rsquo;s sales and profits rise 3-4% on average.
From &lt;a href="http://www.amazon.com/Whole-New-Mind-Right-Brainers-Future/dp/1594481717"&gt;A Whole New Mind&lt;/a&gt;, p. 78&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This is relevant for open source too; good product design attract users.&lt;/p&gt;

&lt;p&gt;People tend to design for themselves, and generally it just doesn&amp;rsquo;t work when developers create software for non-developers. Even so, developers are taking care of designing and implementing the user interface in the majority of open source projects. Leaving us with an unconsistent, probably not well thought through, interface that is very much hacked together and is something the developers just want to get over with. Most importantly: An interface which may confuse users. Designing interfaces usually is not what developers enjoy doing the most, very much reflected in the finished interface.&lt;/p&gt;

&lt;p&gt;This is where the designers come in; we need designers to help the developers to create amazing frontends for the open source applications.&lt;/p&gt;

&lt;p&gt;There are a couple of problems dragging designers into open source projects, and we can start addressing the reason why it hasn&amp;rsquo;t happened a lot in the past. To put it briefly: Designers are scared of developers. Developers speak a foreign language, they are like aliens. Developers don&amp;rsquo;t package their source code in .zip files, instead we use some scary thing called version control. The frontends typically presuposes a pretty extensive knowledge of the backend, a knowledge the designers simply don&amp;rsquo;t have and will have a pretty tough time getting. Designers don&amp;rsquo;t know how to modify a QT GUI, although they may have a daunting idea on how the interface could be so much better.&lt;/p&gt;

&lt;p&gt;How do we solve this? Communication. Developers need to get in touch with the designers and talk with them about how they can get the designers started contributing. For a web application, a skilled web designer might have an easier time than with a GUI, but communication is still required to understand the interface&amp;rsquo;s needs as well as implementation details in terms of communicating with the back end.&lt;/p&gt;

&lt;p&gt;The designers I have talked to would love to get involved, the motivation is there they get to put this on their portfolio and they enjoy designing &amp;mdash; the crucial thing is communication and getting started. Designers want to have easy access to developers of the project they can ask all kinds of questions, developers that might also help the designer implement the interface change itself. IRC is probably not the designer&amp;rsquo;s favorite communication channel, but it&amp;rsquo;s the only one developers know and it&amp;rsquo;s a great way to perform a group chat, involving the entire community around the project.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/x8bzsdF4tN0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/improving-the-open-source-user-experience</feedburner:origLink></entry>
 
 <entry>
   <title>Setting up Unicorn with Nginx</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/PFqzY0AQkwQ/setting-up-unicorn-with-nginx" />
   <updated>2010-10-22T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/setting-up-unicorn-with-nginx</id>
   <content type="html">&lt;p&gt;Unicorn is a cool new Ruby HTTP server, and &lt;a href="http://tomayko.com/writings/unicorn-is-unix"&gt;we like it because it&amp;rsquo;s Unix&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Unicorn is an HTTP server for Rack applications designed to only serve fast clients on low-latency, high-bandwidth connections and take advantage of features in Unix/Unix-like kernels.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I&amp;rsquo;m going to talk about Unicorn&amp;rsquo;s design, and then I&amp;rsquo;ll walk you through setting it up on your server.&lt;/p&gt;

&lt;h1&gt;Design&lt;/h1&gt;

&lt;p&gt;Its design is Unix:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Do one thing and do it right.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;For instance, load balancing in Unicorn is done by the OS kernel and you manage the processes by sending signals.&lt;/p&gt;

&lt;p&gt;Unicorn has &lt;a href="http://unicorn.bogomips.org/DESIGN.html"&gt;a whole document&lt;/a&gt; dedicated to address its design. Here are some of the things:&lt;/p&gt;

&lt;h2&gt;Load balancing&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;Load balancing between worker processes is done by the OS kernel. All workers share a common set of listener sockets and does non-blocking accept() on them. The kernel will decide which worker process to give a socket to and workers will sleep if there is nothing to accept().&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This is really, really cool. Normally load balancers reverse proxy to the worker that is &lt;em&gt;most likely&lt;/em&gt; to be ready, usually based on when the last request was sent to that worker. But there are a few problems to that method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some requests take longer to complete (e.g. heavy I/O)&lt;/li&gt;
&lt;li&gt;Software fails (and it always does, at 2am if you are a software engineer)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Unicorn uses a shared Unix socket (although it can also use TCP, but Unix domain sockets are faster). When a worker is not currently serving a request, it listens on the Unix socket and fights with the other workers to &lt;code&gt;accept()&lt;/code&gt; connections. This is called &lt;strong&gt;push balancing&lt;/strong&gt;. It&amp;rsquo;s great because it solves the problems from above.&lt;/p&gt;

&lt;h2&gt;Slow clients&lt;/h2&gt;

&lt;p&gt;Some clients are slow. And those clients can slow down everything. Twitter has put this issue nicely in &lt;a href="http://engineering.twitter.com/2010/03/unicorn-power.html"&gt;their blog post&lt;/a&gt; on why they moved to Unicorn:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Every server has a fixed number of workers that handle incoming requests. During peak hours, we may get more simultaneous requests than available workers. We respond by putting those requests in a queue.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Welcome to the (retro)world of evented I/O; here&amp;rsquo;s the catch:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;This is unnoticeable to users when the queue is short and we handle requests quickly, but large systems have outliers. Every so often a request will take unusually long, and everyone waiting behind that request suffers. Worse, if an individual worker&amp;rsquo;s line gets too long, we have to drop requests. You may be presented with an adorable whale just because you landed in the wrong queue at the wrong time.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;And then they continue to talk about supermarket queues, &lt;a href="http://engineering.twitter.com/2010/03/unicorn-power.html"&gt;read the whole thing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unicorn disfavors slow clients. Instead of stacking people up in long queues behind some guy who&amp;rsquo;s connection fails miserably; Unicorn lets that one guy fail. The Unicorn master process knows exactly how long each of its workers has been processing a request, and if it takes longer than &lt;code&gt;timeout&lt;/code&gt; (configured; usually 30s) to finish the request, it kills the worker and immediately forks a new one ready to serve requests. Affected clients are given a 502 error page.&lt;/p&gt;

&lt;h2&gt;Deploying&lt;/h2&gt;

&lt;p&gt;With Unicorn one can deploy with &lt;em&gt;zero&lt;/em&gt; downtime. This is rad stuff:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;You can upgrade Unicorn, your entire application, libraries and even your Ruby interpreter without dropping clients.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The Unicorn master and worker processes &lt;a href="http://unicorn.bogomips.org/SIGNALS.html"&gt;respond&lt;/a&gt; to &lt;code&gt;SIGNALS&lt;/code&gt;. Here&amp;rsquo;s what Github does:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;First we send the existing Unicorn master a &lt;code&gt;USR2 SIGNAL&lt;/code&gt;. This tells it to begin starting a new master process, reloading all our app code. When the new master is fully loaded it forks all the workers it needs. The first worker forked notices there is still an old master and sends it a QUIT signal.&lt;/p&gt;

&lt;p&gt;When the old master receives the QUIT, it starts gracefully shutting down its workers. Once all the workers have finished serving requests, it dies. We now have a fresh version of our app, fully loaded and ready to receive requests, without any downtime: the old and new workers all share the Unix Domain Socket so nginx doesn’t have to even care about the transition.&lt;/p&gt;

&lt;p&gt;We can also use this process to upgrade Unicorn itself.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This behaviour requires a bit of Unicorn-config-fu to achieve, but Github has shared &lt;a href="http://gist.github.com/206253"&gt;their config&lt;/a&gt; with us. There&amp;rsquo;s a handy bash script taking advantage of the &lt;code&gt;SIGNAL&lt;/code&gt; Unicorn API &lt;a href="http://github.com/defunkt/unicorn/blob/master/examples/init.sh"&gt;baked in&lt;/a&gt; with Unicorn.&lt;/p&gt;

&lt;p&gt;Unicorn makes 100% uptime possible.&lt;/p&gt;

&lt;h1&gt;Rails on Unicorns&lt;/h1&gt;

&lt;p&gt;Ready power your app by rainbows?&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;re going to set up &lt;a href="http://nginx.org"&gt;Nginx&lt;/a&gt; in front of Unicorn.&lt;/p&gt;

&lt;h2&gt;Nginx&lt;/h2&gt;

&lt;p&gt;Start by installing &lt;a href="http://nginx.org"&gt;Nginx&lt;/a&gt; via your favorite package manager. Afterwards we need to configure it for Unicorn, we&amp;rsquo;re gonna grab &lt;a href="http://github.com/defunkt/unicorn/blob/master/examples/nginx.conf"&gt;the &lt;code&gt;nginx.conf&lt;/code&gt; example configuration shipped with Unicorn&lt;/a&gt;, the Nginx configuration file is usually located at &lt;code&gt;/etc/nginx/nginx.conf&lt;/code&gt;, so place it there, and tweak it to your likings, read the comments&amp;mdash;they&amp;rsquo;re quite good.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;nginx.conf&lt;/code&gt; you may have stumbled upon this line:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;user nobody nogroup; &lt;span class="c"&gt;# for systems with a &amp;quot;nogroup&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;While this works, it&amp;rsquo;s generally adviced to run as a seperate user for security reasons and increased control. Let&amp;rsquo;s create an Nginx user, and a web group:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;sudo useradd -s /sbin/nologin -r nginx
&lt;span class="nv"&gt;$ &lt;/span&gt;sudo usermod -a -G web nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Configure your static path in &lt;code&gt;nginx.conf&lt;/code&gt; to &lt;code&gt;/var/www&lt;/code&gt;, and give permissions to that folder to the web group:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;sudo mkdir /var/www
&lt;span class="nv"&gt;$ &lt;/span&gt;sudo chgrp -R web /var/www &lt;span class="c"&gt;# set /var/www owner group to &amp;quot;web&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;sudo chmod -R 775 /var/www &lt;span class="c"&gt;# group write permission&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Then add yourself to the web group so you can modify the contents of &lt;code&gt;/var/www&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;sudo usermod -a -G web USERNAME
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Unicorn&lt;/h2&gt;

&lt;p&gt;Time for flying rainbow horses. Start by installing the Unicorn gem:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem install unicorn
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You should now have Unicorn installed: &lt;code&gt;unicorn&lt;/code&gt; (for non-Rails rack applications) and &lt;code&gt;unicorn_rails&lt;/code&gt; (for Rails applications version &gt;= 1.2) should be in your path.&lt;/p&gt;

&lt;p&gt;Time to take it for a spin! (You may wish to re-login with &lt;code&gt;su - USERNAME&lt;/code&gt; if you haven&amp;rsquo;t already, this ensures your permission tokens are set, otherwise you will not have write permission to &lt;code&gt;/var/www&lt;/code&gt;)&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www
&lt;span class="nv"&gt;$ &lt;/span&gt;rails new unicorn
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;There we go, we now have our Unicorn Rails test app in &lt;code&gt;/var/www&lt;/code&gt;! Let&amp;rsquo;s fetch some Unicorn config and start the madness. We&amp;rsquo;re going for the &lt;code&gt;unicorn.conf&lt;/code&gt; example that comes with the Unicorn source:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl -o config/unicorn.rb https://raw.github.com/defunkt/unicorn/master/examples/unicorn.conf.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You might want to tweak a few things:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;APP_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/var/www/unicorn&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;working_directory&lt;/span&gt; &lt;span class="no"&gt;APP_PATH&lt;/span&gt;

&lt;span class="n"&gt;stderr_path&lt;/span&gt; &lt;span class="no"&gt;APP_PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/log/unicorn.stderr.log&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;stdout_path&lt;/span&gt; &lt;span class="no"&gt;APP_PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/log/unicorn.stderr.log&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="no"&gt;APP_PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/tmp/pid/unicorn.pid&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Our Unicorn is ready!&lt;/p&gt;

&lt;h2&gt;Rainbow magic&lt;/h2&gt;

&lt;p&gt;Start the Nginx deamon, how this is done depends on your OS. And then start Unicorn:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;unicorn_rails -c /var/www/unicorn/config/unicorn.rb -D
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;-D&lt;/code&gt; deamonizes it. &lt;code&gt;-c&lt;/code&gt; should be pretty obvious; it specifies the configuration. In production you will probably want to pass &lt;code&gt;-E production&lt;/code&gt; as well to run the app in the production environment.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s it! Visiting &lt;a href="http://localhost"&gt;localhost&lt;/a&gt; should take you to the Rails default page.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/PFqzY0AQkwQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/setting-up-unicorn-with-nginx</feedburner:origLink></entry>
 
 <entry>
   <title>A Rubyist's development environment</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/VF4zupz5xKg/a-rubyists-development-environment" />
   <updated>2010-09-19T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/a-rubyists-development-environment</id>
   <content type="html">&lt;p&gt;I consider myself as a Rubyist and a minimalist. I want my tools to be few, and sharp. That means I only want few tools, but I want to master these tools.
Now it&amp;rsquo;s been about a year since I started programming, this post is supposed to give you a look into my toolbox. I hope it can be of inspiration to you.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve open sourced all my dotfiles &lt;a href="http://github.com/Sirupsen/dotfiles"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Operating System: Linux and Mac&lt;/h2&gt;

&lt;p&gt;My primary development platform is my desktop running &lt;a href="http://sirupsen.com/my-experience-with-arch-linux" title="See my blog post about my experience with Arch Linux"&gt;Arch Linux&lt;/a&gt;. It&amp;rsquo;s a dual screen setup, which I learned to &lt;em&gt;love&lt;/em&gt;. I also own a Macbook, primarily used for schoolwork and field coding.&lt;/p&gt;

&lt;p&gt;As for my desktop setup of noteworthy tools besides my editor, I use bleeding-edge Chromium as my browser. I might switch to &lt;a href="http://www.uzbl.org/"&gt;Uzbl&lt;/a&gt; someday. I use &lt;a href="http://openbox.org/wiki"&gt;Openbox&lt;/a&gt; as my window manager. Sakura as my terminal, simply because it&amp;rsquo;s lightweight, simple to setup and it does its job.&lt;/p&gt;

&lt;p&gt;I have Openbox &lt;a href="http://github.com/Sirupsen/dotfiles/blob/master/.config/openbox/rc.xml"&gt;configured to act like Vim&lt;/a&gt;, and for Chromium I use &lt;a href="https://chrome.google.com/extensions/detail/dbepggeogbaibhgnhhndojpepiihcmeb"&gt;Vimium&lt;/a&gt; to achieve the same Vim behavior. In theory I &lt;em&gt;never&lt;/em&gt; have to touch my mouse.&lt;/p&gt;

&lt;h3&gt;Shell&lt;/h3&gt;

&lt;p&gt;As for my shell I just use &lt;code&gt;bash&lt;/code&gt;. I know the cool kids use &lt;code&gt;zsh&lt;/code&gt;, but I simply haven&amp;rsquo;t bothered to set it up, and I&amp;rsquo;m really quite happy with &lt;code&gt;bash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;My bash configuration is pretty simple. It just defines some default values, source a few things, and add to my &lt;code&gt;$PATH&lt;/code&gt;. It also sets my &lt;code&gt;PS1&lt;/code&gt; which consists of only the current directory. I figured that I &lt;em&gt;already know&lt;/em&gt; my username, and hostname. Furthermore I really don&amp;rsquo;t need to know the entire absolute path of the current directory.&lt;/p&gt;

&lt;h2&gt;Editor: Vim&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;ve been through many editors. Many. Believe me. A little less than a year ago, a friend recommended me Vim. And I started digging into it. In the beginning, it was hard. But he promised me it&amp;rsquo;d be worth it. So I sticked to it. In the start, I felt less productive in Vim, because it was somewhat hard to learn. After a few days in it however, I began taking advantage of the endless sets of commands, this all resulted in a &lt;em&gt;more&lt;/em&gt; productive me. I now love Vim, and nowadays I almost do all of my text-processing in it: I take notes in Vim, I&amp;rsquo;m writing this very blog post in Vim, and I make kickass code in Vim.&lt;/p&gt;

&lt;p&gt;My Vim setup really is nothing special. I use a few plugins, and I have a small configuration file which is just parts stolen and compiled from others. I can&amp;rsquo;t remember who I stole what from, though. So they are not credited. I use Monaco as my Vim (and terminal) font, I simply like this font a lot. &lt;a href="http://imgur.com/IdNuY.png"&gt;Screenshot&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Syncing: Dropbox&lt;/h2&gt;

&lt;p&gt;As I have multiple computers, I sync &lt;em&gt;everything&lt;/em&gt; with Dropbox. This also has the benefit of being (additional, I have everything under &lt;code&gt;git&lt;/code&gt;, too) backup. My Dropbox holds mostly configuration files and code. The rest is in the cloud. With everything in my Dropbox, I make symbolic links from the Dropbox.&lt;/p&gt;

&lt;h3&gt;Configuration between multiple computers&lt;/h3&gt;

&lt;p&gt;As I have multiple computers, I want &lt;a href="http://github.com/Sirupsen/dotfiles"&gt;my configuration files&lt;/a&gt; (&lt;em&gt;dotfiles&lt;/em&gt;) to change on other computers as soon as I have changed it somewhere else. In the beginning I had an ugly Rake task to do all this symbolic linking, but later I discovered &lt;a href="http://github.com/technicalpickles/homesick"&gt;Homesick&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Homesick is sorta like rip, but for dotfiles. It uses git to clone a repository containing dotfiles, and saves them in &lt;code&gt;~/.homesick&lt;/code&gt;. It then allows you to symlink all the dotfiles into place with a single command.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;When you clone a &lt;code&gt;castle&lt;/code&gt;, as they are called in Homesick, it puts the castle in &lt;code&gt;~/.homesick/repos/&amp;lt;repo&amp;gt;&lt;/code&gt;, for instance:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;homesick clone Sirupsen/dotfiles &lt;span class="c"&gt;# goes to ~/homesick/repos/Sirupsen/dotfiles&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Instead of updating the dotfiles with Git via pulling, however, I wanted it to go through Dropbox, so changes are reflected on my other computers instantly. Later, I can commit these changes:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ln -s Dropbox/dotfiles ~/.homesick/repos/
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now I can symlink everything easily:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;homesick symlink dotfiles
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Using dual screen for coding&lt;/h2&gt;

&lt;p&gt;When I work, I usually work on two monitors. A 19", and a 24".&lt;/p&gt;

&lt;p&gt;On my 19" I have Pidgin running. This makes me able to talk to colleagues, or friends while working on my other monitor. I might also shring my windows here, and have another terminal open with tests.&lt;/p&gt;

&lt;p&gt;On my 24" I have my browser running in the right side, taking up about 50% of horizontal space. When i am coding, this is great for documentation and general googling, githubing and ticket managing while coding. I have experimented with fullscreen Vim, however I just don&amp;rsquo;t need more than these 80 columns horizontally, so this setup works great. More vertical space is always nice, I&amp;rsquo;ve heard great things about having a screen that can be turned around to a portrait view for coding. I usually have my terminal running beneath my Vim window, it&amp;rsquo;s super easy to switch between them with my Openbox Vim configuration.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/VF4zupz5xKg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/a-rubyists-development-environment</feedburner:origLink></entry>
 
 <entry>
   <title>Get started right with RVM</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/goPvVslJAAQ/get-started-right-with-rvm" />
   <updated>2010-09-07T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/get-started-right-with-rvm</id>
   <content type="html">&lt;p&gt;I&amp;rsquo;ve always run Ruby, and I&amp;rsquo;ve always used &lt;a href="http://rvm.beginrescueend.com/"&gt;RVM&lt;/a&gt;. But it&amp;rsquo;s not until recently when I attended &lt;a href="http://aarhusrb.dk"&gt;Aarhusrb&lt;/a&gt; and &lt;a href="http://twitter.com/chopmo"&gt;@chopmo&lt;/a&gt; gave a talk on RVM, that I realized how wrong I was using RVM. Basically, I&amp;rsquo;m somewhat always using system Ruby, installing all gems with &lt;code&gt;sudo&lt;/code&gt;. However, digging into RVM I found useful features, such as gemsets, installing gems on a user basis, ..
Thus I realized I ideally should run my entire Ruby environment through RVM, instead of only using RVM for anything not supported by my system install.&lt;/p&gt;

&lt;p&gt;Here are my new discoveries, compiled down to a blog post. Most of this can be found in the great &lt;a href="http://rvm.beginrescueend.com/"&gt;RVM documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Installing RVM&lt;/h2&gt;

&lt;p&gt;If you don&amp;rsquo;t already have RVM installed, you should do it now. It&amp;rsquo;s fairly simple to install:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bash &amp;lt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt; curl http://rvm.beginrescueend.com/releases/rvm-install-head &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;If there are &gt; 1 users on your system wishing to use RVM, you may want to look into a &lt;a href="http://rvm.beginrescueend.com/deployment/system-wide/"&gt;system-wide installation&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And then add what it says to &lt;code&gt;.bashrc&lt;/code&gt;, &lt;code&gt;.bash_profile&lt;/code&gt; or whatever you use.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;[[ -s &amp;quot;$HOME/.rvm/scripts/rvm&amp;quot; ]] &amp;amp;&amp;amp; source &amp;quot;$HOME/.rvm/scripts/rvm&amp;quot;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; .bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;What I hate about installing gems is that it&amp;rsquo;s slow due to &lt;code&gt;ri&lt;/code&gt; and &lt;code&gt;rdoc&lt;/code&gt;. I never use this local documentation anyway, and it&amp;rsquo;s faily easy to disable the generation of it; speeding up your gem installs a great deal. Just put this in your &lt;code&gt;~/.gemrc&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ri&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rdoc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Verify whether the &lt;code&gt;rvm&lt;/code&gt; command works, and use the chance to also check your system notes:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm notes
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Uninstalling all gems in system Ruby (Optional)&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Now this is not required, I just did it to clean my system. Therefore you can safely skip this step.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now that you have RVM installed, you can simply empty the gemset (this&amp;rsquo;ll all make more sense later):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset empty
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Before running this you can take a backup of all your currently installed gems:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset &lt;span class="nb"&gt;export &lt;/span&gt;backup.gems
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This leaves you with a file, desribing all your system&amp;rsquo;s gems. (&lt;a href="http://gist.github.com/568262"&gt;&lt;em&gt;Quite a file, in my case&lt;/em&gt;&lt;/a&gt;). If you at some point need to install all these gems again, it&amp;rsquo;s simply a matter of running:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset import backup.gems
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;We&amp;rsquo;ll talk a bit more about &lt;code&gt;rvm gemset {import,export}&lt;/code&gt; later; why it&amp;rsquo;s as nifty as it is.&lt;/p&gt;

&lt;h2&gt;Installing Rubies&lt;/h2&gt;

&lt;p&gt;Rubies are essentially Ruby versions, let&amp;rsquo;s go ahead and get &lt;code&gt;Ruby 1.9.2&lt;/code&gt; first, and set that as our default interpreter. Afterwards, we&amp;rsquo;ll install &lt;code&gt;Ruby 1.8.6&lt;/code&gt;. And then we&amp;rsquo;ll try to switch between the two environments.&lt;/p&gt;

&lt;p&gt;Installing &lt;code&gt;1.9.2&lt;/code&gt; is very easy, it&amp;rsquo;s simply a matter of issuing:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm install 1.9.2
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;It can take a while to install, since it compiles from source.&lt;br/&gt;
Let&amp;rsquo;s switch to it; verify it all works!&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm 1.9.2
&lt;span class="nv"&gt;$ &lt;/span&gt;ruby -v
ruby 1.9.2p0 &lt;span class="o"&gt;(&lt;/span&gt;2010-08-18 revision 29036&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;i686-linux&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Great!&lt;br/&gt;
We want &lt;code&gt;1.9.2&lt;/code&gt; to be our default interpreter:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm --default 1.9.2
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Restart your shell, and run &lt;code&gt;ruby -v&lt;/code&gt; to verify it&amp;rsquo;s all working as expcted. Let&amp;rsquo;s install &lt;code&gt;1.8.6&lt;/code&gt; along with &lt;code&gt;1.9.2&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm install 1.8.6
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;And then we can switch to it, like we switched to &lt;code&gt;1.9.2&lt;/code&gt; before:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm 1.8.6
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;(Which is a shortcut for &lt;code&gt;rvm use 1.8.6&lt;/code&gt;). You are now up and running with two Ruby environments, congratulations!&lt;/p&gt;

&lt;h2&gt;Gemsets&lt;/h2&gt;

&lt;h3&gt;What?&lt;/h3&gt;

&lt;p&gt;The shortest explanation, is found within the name. Gem-sets.&lt;br/&gt;
RVM&amp;rsquo;s documentation puts it like this:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;RVM gives you compartmentalized independent ruby setups. This means that ruby, gems and irb are all separate and self-contained from system and from each other. &lt;br/&gt;
You may even have separate named gemsets.&lt;br/&gt;
Let&amp;rsquo;s say, for example, that you are testing two versions of a gem with ruby 1.9.2-head. You can install one to the default 1.9.2-head and create a named gemset for the other version and switch between them easily.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Ideally you have a Gemset for each project that you are working on. This keeps your system clean, and eliminates &amp;ldquo;Gem clutter&amp;rdquo;. Also running &lt;code&gt;bundle install&lt;/code&gt; will use the project defined gemset to also store the gems.&lt;/p&gt;

&lt;h3&gt;Creating and using a gemset&lt;/h3&gt;

&lt;p&gt;So let&amp;rsquo;s go ahead and create a gemset:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset create foo &lt;span class="c"&gt;# Create gemset &amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class="s1"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt; gemset created &lt;span class="o"&gt;(&lt;/span&gt;/home/sirup/.rvm/gems/ruby-1.9.2-p0@foo&lt;span class="o"&gt;)&lt;/span&gt;.

&lt;span class="nv"&gt;$ &lt;/span&gt;rvm 1.9.2@foo &lt;span class="c"&gt;# Switch to Ruby 1.9.2 with gemset &amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;gem list &lt;span class="c"&gt;# Lists installed gems&lt;/span&gt;
*** LOCAL GEMS ***
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Let&amp;rsquo;s try to install a few gems in our new gemset, note again, we do shouldn&amp;rsquo;t use &lt;code&gt;sudo&lt;/code&gt; to install gems, as that would install it outside of your gemset:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem install rails
&lt;span class="nv"&gt;$ &lt;/span&gt;gem list
gem list
*** LOCAL GEMS ***

abstract &lt;span class="o"&gt;(&lt;/span&gt;1.0.0&lt;span class="o"&gt;)&lt;/span&gt;
actionmailer &lt;span class="o"&gt;(&lt;/span&gt;3.0.0&lt;span class="o"&gt;)&lt;/span&gt;
actionpack &lt;span class="o"&gt;(&lt;/span&gt;3.0.0&lt;span class="o"&gt;)&lt;/span&gt;
activemodel &lt;span class="o"&gt;(&lt;/span&gt;3.0.0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;..&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Great! Let&amp;rsquo;s switch back to our &lt;code&gt;global&lt;/code&gt; gemset (this is the default gemset, you can also switch to it more explicitly with &lt;code&gt;rvm 1.9.2@global&lt;/code&gt;):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm 1.9.2
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;And &lt;code&gt;gem list&lt;/code&gt; here returns an empty list, as expected since no gems are installed in the global gemset.&lt;/p&gt;

&lt;h3&gt;Dumping and loading gemsets&lt;/h3&gt;

&lt;p&gt;Let&amp;rsquo;s try that export feature, that I previously explained as a backup solution, again:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm 1.9.2@foo
&lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset &lt;span class="nb"&gt;export &lt;/span&gt;rails.gems
&lt;span class="nv"&gt;$ &lt;/span&gt;cat rails.gems
abstract -v1.0.0
actionmailer -v3.0.0
actionpack -v3.0.0
activemodel -v3.0.0
&lt;span class="o"&gt;[&lt;/span&gt;..&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You are then free to send &lt;code&gt;rails.gems&lt;/code&gt; to someone else, and that person would simply import the gemset like so:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm use 1.9.2@rails --create &lt;span class="c"&gt;# Shortcut to create, then switch to it&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset import rails.gems
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Which would install all the gems from &lt;code&gt;rails.gems&lt;/code&gt;, and the exact same versions. This is great when you work in teams, because we all tried messing up the versions..&lt;/p&gt;

&lt;h3&gt;The global and default gemset&lt;/h3&gt;

&lt;p&gt;Two interesting gemsets are the &lt;code&gt;global&lt;/code&gt; (&lt;code&gt;~/.rvm/gemsets/global.gems&lt;/code&gt;) and &lt;code&gt;default&lt;/code&gt; (&lt;code&gt;~/.rvm/gemsets/default.gems&lt;/code&gt;) gemsets.&lt;br/&gt;
Gems in the &lt;code&gt;global gemset&lt;/code&gt;, will be added to the global gemset in &lt;em&gt;every&lt;/em&gt; new Ruby you install. &lt;code&gt;rake&lt;/code&gt; and &lt;code&gt;rdoc&lt;/code&gt; are good examples of handy global gems.&lt;br/&gt;
The &lt;code&gt;default gemset&lt;/code&gt; is the gems included in every new gemset.&lt;/p&gt;

&lt;h2&gt;rvmrc&lt;/h2&gt;

&lt;p&gt;Now there are different kinds of &lt;code&gt;rvmrc&lt;/code&gt; files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System &lt;code&gt;/etc/rvmrc&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;System wide configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;User &lt;code&gt;~/.rvmrc&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;User wide configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Project &lt;code&gt;.rvmrc&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Project wide configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The most interesting one is the project &lt;code&gt;.rvmrc&lt;/code&gt;. Every time you &lt;code&gt;cd&lt;/code&gt;, RVM looks for a file called &lt;code&gt;.rvmrc&lt;/code&gt;. If it finds it, it executes it.&lt;br/&gt;
Ouput from &lt;code&gt;bash&lt;/code&gt; says more than a thousand words:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;rvm 1.8.6@project&amp;quot;&lt;/span&gt; &amp;gt; ~/projects/ruby-1.8.6-project/.rvmrc
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I recieved &lt;a href="http://twitter.com/wayneeseguin/status/24387445101"&gt;a tip&lt;/a&gt; from &lt;a href="http://twitter.com/wayneeseguin"&gt;@wayneeseguin&lt;/a&gt;, that we can be even more sneaky about this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm --create --rvmrc 1.8.6@project
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This will create the gemset, and the &lt;code&gt;.rvmrc&lt;/code&gt; file!&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;~/projects &lt;span class="nv"&gt;$ &lt;/span&gt;ruby -v
ruby 1.9.2p0 &lt;span class="o"&gt;(&lt;/span&gt;2010-08-18 revision 29036&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;i686-linux&lt;span class="o"&gt;]&lt;/span&gt;
~/projects &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ruby-1.8.6-project/
~/projects/ruby-1.8.6-project &lt;span class="nv"&gt;$ &lt;/span&gt;ruby -v
ruby 1.8.6 &lt;span class="o"&gt;(&lt;/span&gt;2010-02-05 patchlevel 399&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;i686-linux&lt;span class="o"&gt;]&lt;/span&gt;
~/projects/ruby-1.8.6-project &lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset name
project
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;My favorite configuration option is &lt;code&gt;rvm_gemset_create_on_use_flag=1&lt;/code&gt;, having this line in &lt;code&gt;/etc/rvmrc&lt;/code&gt; or &lt;code&gt;~/.rvmrc&lt;/code&gt;, gemsets will be automatically created when used:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset list
gemsets &lt;span class="k"&gt;for &lt;/span&gt;ruby-1.9.2-p0 &lt;span class="o"&gt;(&lt;/span&gt;found in /home/sirup/.rvm/gems/ruby-1.9.2-p0&lt;span class="o"&gt;)&lt;/span&gt;

foo
global
&lt;span class="nv"&gt;$ &lt;/span&gt;rvm gemset use foobar
Now using gemset &lt;span class="s1"&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="http://twitter.com/wayneeseguin"&gt;@wayneeseguin&lt;/a&gt; sent in &lt;a href="http://twitter.com/wayneeseguin/status/24387379953"&gt;another tip&lt;/a&gt; about &lt;a href="http://rvm.beginrescueend.com/workflow/completion/"&gt;&lt;code&gt;bash&lt;/code&gt; and &lt;code&gt;zsh&lt;/code&gt; completion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can read more about &lt;code&gt;rvmrc&lt;/code&gt; in &lt;a href="http://rvm.beginrescueend.com/workflow/rvmrc/"&gt;RVM&amp;rsquo;s documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This is all briefly describing what can be found in &lt;a href="http://rvm.beginrescueend.com/"&gt;RVM&amp;rsquo;s (fantastic) documentation&lt;/a&gt;. For basic use, this article should cover the main topics, however, RVM can still do a whole lot more than I adressed here. The goal of this post was simply to get you started well, and right, with RVM.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://news.ycombinator.com/item?id=1686435"&gt;Discuss this on Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/goPvVslJAAQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/get-started-right-with-rvm</feedburner:origLink></entry>
 
 <entry>
   <title>The switch to Github Pages</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/pYfvt2pHMUQ/the-switch-to-github-pages" />
   <updated>2010-07-23T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/the-switch-to-github-pages</id>
   <content type="html">&lt;p&gt;Until recently I&amp;#8217;ve never had my own server; always hosted at friends, for free. Usually limiting me in terms of mobility regarding technologies. One of the first thing which made me stay away from Ruby &amp;#8212; my host would only support &lt;span class="caps"&gt;PHP&lt;/span&gt;. That&amp;#8217;s really an advantage for &lt;span class="caps"&gt;PHP&lt;/span&gt;, in terms of community growth.&lt;/p&gt;
&lt;p&gt;A few months back, I decided to finally buy myself a server. I had been into Ruby for a while, and I wanted to deploy a cool personal site, handling some dynamic features as well like: pulling my Github repositories, and listing them directly at &lt;span class="fixed"&gt;/projects&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;I looked around for a &lt;a href="http://www.lowendbox.com/"&gt;low end box&lt;/a&gt;, since I didn&amp;#8217;t need much power. While not being very server-wise, I still needed some. I had at this point already written &lt;a href="/what-I-wish-a-ruby-programmer-had-told-me-one-year-ago.html"&gt;What I wish a Ruby programmer had told me one year ago&lt;/a&gt; which became quite popular, with something like 20.000 hits the first day. A social media attack like that, requires some server power. Luckily, the server I had my blog hosted on at that point, could easily manage such a load. However, when I wanted to move my blog to a less powerful server, my own, I&amp;#8217;d still need some power in order to handle these attacks. But the major problem here, is that I don&amp;#8217;t want to pay for server power I&amp;#8217;ll rarely take full advantage of, so I had to find  balance between pricing a student could afford, and power.&lt;br /&gt;
I wanted to make the move because I didn&amp;#8217;t want to be limited to Wordpress, or &lt;span class="caps"&gt;PHP&lt;/span&gt;-based stuff. I was set to develop my own little solution, for the fun and learning process of it.&lt;/p&gt;
&lt;p&gt;I ended up buying a &lt;a href="http://bluemile.com"&gt;Fivebean&lt;/a&gt; (they are now called &lt;a href="http://bluemile.com"&gt;bluemile&lt;/a&gt;) node with 256 mb. of ram, and 512 mb. burst. This should do good, and would only be $16/month, which seemed fair. The first month, I used it &lt;strong&gt;a lot&lt;/strong&gt; &amp;#8212; I had never had a server before, so I learned a great deal on this node. I set it up with &lt;a href="http://archlinux.org"&gt;Arch Linux&lt;/a&gt; &amp;#8212; following the philosophy:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For a personal Linux server, use the distro you feel the most comfortable with.&lt;sup class="footnote"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As I&amp;#8217;ve had previous &lt;a href="/my-experience-with-arch-linux.html"&gt;experience with Arch Linux&lt;/a&gt;, I decided to go for it on the server-side too, even though Arch tends to be &lt;a href="http://wiki.archlinux.org/index.php/Arch_Compared_to_Other_Distributions#Slackware"&gt;bleeding edge&lt;/a&gt; &amp;#8212; it worked out just fine. I set the web server up with &lt;a href="http://nginx.org/"&gt;Nginx&lt;/a&gt; which I had heard great things about, mostly it was to try something else than &lt;a href="http://apache.org"&gt;Apache&lt;/a&gt;. I also set up &lt;a href="http://www.modrails.com/"&gt;Passenger&lt;/a&gt; for Ruby/Rack deployment. I even documented this process on the &lt;a href="http://wiki.archlinux.org/index.php/Nginx#Ruby_.28Rack-based_and_Rails.29"&gt;Arch Linux wiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This was all a great experience. I ended up having some issues with &lt;a href="http://bluemile.com"&gt;Fivebean&lt;/a&gt;, in terms of my node being DDOSSed, resulting in poor performance and occasional downtime; about 5 minutes per hour in average. I contacted the support, and they told me they&amp;#8217;d move me &amp;#8212; great! However, issues kept happening so I interpreted it as a sign: try this &lt;a href="http://linode.com"&gt;Linode&lt;/a&gt; thing everyone is buzzing about!&lt;/p&gt;
&lt;p&gt;And I did. Linode is great, and appears fast &amp;#8212; &lt;span class="caps"&gt;SSH&lt;/span&gt; worked much faster than what I had been used to with my Fivebean node. So I kept with Linode, and at their birthday, they even &lt;a href="http://blog.linode.com/2010/06/16/linode-turns-7-big-ram-increase/"&gt;boosted the ram of all slices&lt;/a&gt; &amp;#8212; for free!&lt;/p&gt;
&lt;p&gt;At some point I realised something though: I just hosted static stuff on my site, I barely used it for anything dynamic anymore. I reminded myself &lt;a href="http://github.com"&gt;Github&lt;/a&gt; had a service for just this: &lt;a href="http://pages.github.com"&gt;Github Pages&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The GitHub Pages feature allows you to publish content to the web by simply pushing content to one of your GitHub hosted repositories. There are two different kinds of Pages that you can create: User Pages and Project Pages.&lt;sup class="footnote"&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I had one issue with Pages though: I wanted my host my blog there. Quickly I found that Github already, of course &amp;#8211; had internally developed a RubyGem called &lt;a href="http://github.com/mojombo/jekyll"&gt;Jekyll&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Jekyll is a blog-aware, static site generator in Ruby&lt;sup class="footnote"&gt;&lt;a href="#fn3"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;By formatting your blog posts in either &lt;a href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Textile_(markup_language)"&gt;Textile&lt;/a&gt; or &lt;span class="caps"&gt;HTML&lt;/span&gt;, you could use &lt;a href="http://www.liquidmarkup.org/"&gt;Liquid&lt;/a&gt; to format your pages. Resulting in the perfect environment for any hackers website. I&amp;#8217;m using this right now, to write this post. Having a Textile file, editing it with Vim. Whenever I want to deploy a new post, or change something &amp;#8212; I just push it to my site repository.&lt;/p&gt;
&lt;p&gt;The best thing about Github Pages is, that it has allowed me to cancel my Linode, and I can also redirect my domain here. Furthermore, my blog should be able to handle Social Media attacks just fine now. And all this is for free.  &lt;br /&gt;
If you can see yourself in some of this, I advice you to try out &lt;a href="http://pages.github.com"&gt;Github Pages&lt;/a&gt; &amp;#8212; it&amp;#8217;s been a great experience for me this far.&lt;/p&gt;
&lt;p&gt;If you want to run a blog, and are already using another blog system, like Wordpress, Jekyll has some built in code for &lt;a href="http://wiki.github.com/mojombo/jekyll/blog-migrations"&gt;converting your blog posts for Jekyll&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;My entire site is open source, &lt;a href="http://github.com/sirupsen/sirupsen.github.com"&gt;hosted at Github&lt;/a&gt; &amp;#8212; of course. Perhaps it could help you get started!&lt;/p&gt;




















&lt;p class="footnote" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Own wisdom&lt;/p&gt;
&lt;p class="footnote" id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; &lt;a href="http://pages.github.com"&gt;http://pages.github.com&lt;/a&gt;&lt;/p&gt;
&lt;p class="footnote" id="fn3"&gt;&lt;sup&gt;3&lt;/sup&gt; &lt;a href="http://pages.github.com"&gt;http://github.com/mojombo/jekyll&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/pYfvt2pHMUQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/the-switch-to-github-pages</feedburner:origLink></entry>
 
 <entry>
   <title>A simple Imgur Bash screenshot utility</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/lmq7skaZ7mI/a-simple-imgur-bash-screenshot-utility" />
   <updated>2010-05-10T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/a-simple-imgur-bash-screenshot-utility</id>
   <content type="html">&lt;p&gt;I use screenshots a lot, every day. Mostly when I do instant messaging, they can usually help explain something much quicker than anything else. It&amp;rsquo;s rare that I edit the screenshot, and in these rare occasions, it doesn&amp;rsquo;t bother me all that much having to fire up &lt;a href="http://pinta-project.com/"&gt;Pinta&lt;/a&gt; or &lt;a href="http://www.gimp.org/"&gt;Gimp&lt;/a&gt;&amp;mdash;to make these small changes.&lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;shoot&lt;/code&gt;&amp;rsquo;s dependencies are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;curl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scrot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xclip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;libnotify&lt;/code&gt; (&lt;em&gt;optional&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You probably have those already, if not, install them via your package manager.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;curl http://sirupsen.com/static/misc/shoot &amp;gt; ~/bin/shoot &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; chmod 755 ~/bin/shoot
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Assuming &lt;code&gt;~/bin&lt;/code&gt; is in your &lt;code&gt;$PATH&lt;/code&gt;, you&amp;rsquo;re ready to &lt;code&gt;shoot&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;shoot
&lt;span class="nv"&gt;$ &lt;/span&gt;xclip -selection c -o
http://imgur.com/Z8prG.jpg
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I recommend that you bind the script to a key, so you can easily activate it.&lt;/p&gt;

&lt;h2&gt;Coming up with the script&lt;/h2&gt;

&lt;p&gt;The functionality needed, came down to this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select region and take screenshot of this region&lt;/li&gt;
&lt;li&gt;Upload screenshot to &lt;a href="http://imgur.com"&gt;Imgur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Put direct link to screenshot into the clipboard&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Taking a screenshot of a specified region is quite easy with &lt;code&gt;scrot&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;scrot -s
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Then using &lt;code&gt;curl&lt;/code&gt; to upload the picture, via the Imgur API:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;curl -s -F &lt;span class="s2"&gt;&amp;quot;image=@$1&amp;quot;&lt;/span&gt; -F &lt;span class="s2"&gt;&amp;quot;key=api-key&amp;quot;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
http://imgur.com/api/upload.xml 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This returns some XML containing, among other things, the direct URL to the uploaded screenshot, which we extract from the returned XML with a simple regex:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;grep -E -o &lt;span class="s2"&gt;&amp;quot;&amp;lt;original_image&amp;gt;(.)*&amp;lt;/original_image&amp;gt;&amp;quot;&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
grep -E -o &lt;span class="s2"&gt;&amp;quot;http://i.imgur.com/[^&amp;lt;]*&amp;quot;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now we have the direct link, and then it&amp;rsquo;s simply a matter of putting this all into the clipboard with &lt;code&gt;xclip&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;xclip -selection c 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now this is optional, but quite handy. It uses &lt;code&gt;libnotify&lt;/code&gt; to notify you when the image is uploaded, and ready to be pasted:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;notify-send &lt;span class="s2"&gt;&amp;quot;Clipboard ready!&amp;quot;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;The script&lt;/h2&gt;

&lt;p&gt;And I compiled all this into this simple script (I&amp;rsquo;m aware that this can be a one-liner and everything but this just seems more readable and &lt;em&gt;works&lt;/em&gt;. If you have a better solution, be sure to contact me!):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="k"&gt;function &lt;/span&gt;uploadImage &lt;span class="o"&gt;{&lt;/span&gt;
  curl -s -F &lt;span class="s2"&gt;&amp;quot;image=@$1&amp;quot;&lt;/span&gt; -F &lt;span class="s2"&gt;&amp;quot;key=486690f872c678126a2c09a9e196ce1b&amp;quot;&lt;/span&gt; http://imgur.com/api/upload.xml | grep -E -o &lt;span class="s2"&gt;&amp;quot;&amp;lt;original_image&amp;gt;(.)*&amp;lt;/original_image&amp;gt;&amp;quot;&lt;/span&gt; | grep -E -o &lt;span class="s2"&gt;&amp;quot;http://i.imgur.com/[^&amp;lt;]*&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

scrot -s &lt;span class="s2"&gt;&amp;quot;shot.png&amp;quot;&lt;/span&gt; 
uploadImage &lt;span class="s2"&gt;&amp;quot;shot.png&amp;quot;&lt;/span&gt; | xclip -selection c
rm &lt;span class="s2"&gt;&amp;quot;shot.png&amp;quot;&lt;/span&gt;
notify-send &lt;span class="s2"&gt;&amp;quot;Done&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;That&amp;rsquo;s it. Hopefully you&amp;rsquo;ll enjoy it as much as I do.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/lmq7skaZ7mI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/a-simple-imgur-bash-screenshot-utility</feedburner:origLink></entry>
 
 <entry>
   <title>What I wish a Ruby programmer had told me one year ago</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/O2K4xrP1W6A/what-I-wish-a-ruby-programmer-had-told-me-one-year-ago" />
   <updated>2010-04-28T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/what-I-wish-a-ruby-programmer-had-told-me-one-year-ago</id>
   <content type="html">&lt;strong&gt;Warning:&lt;/strong&gt; Biased content follows.

&lt;p&gt;Scroll down if you just want to skip to my wise words.&lt;/p&gt;

&lt;p&gt;One year ago, I started coding for real again. I dumped wasting times on stupid games and so on. I like building websites, so I started by going back to the roots. HTML &amp;amp; CSS which I had coded when I was about 10, and it didn't take me long before I had moved from tables to div tags and all. I learned myself to hand-code it, and not rely on software like Dreamweaver. Resulting in better, more compact and valid HTML. I had played around with PHP when I was about 11, so I decided to build some stuff in it again.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;I should never have done that, I have realized. I used about 4 months in PHP, picking up  bad habits. At some point, I found myself reaching points where I saw PHP solutions plain stupid. I didn't have experience with any other languages, but I knew there had to be better ways. So I decided to dive into Python, and later look at the Django web framework. So I did.&lt;/p&gt;

&lt;p&gt;After a few days playing around with Python, I felt okay with it. I didn't love Python, but it was fairly simple, and from the simple Django examples I felt confident I was ready to proceed and expand my literacy in Python via Django. After following the basic tutorials, I felt Django was already superior to PHP.&lt;/p&gt;

&lt;p&gt;I had heard about this evil language called Ruby and some framework called Rails, I had not considered it though because of three (stupid) reasons:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Highest ratio of smug fanboys&lt;/li&gt;
	&lt;li&gt;End-statements&lt;/li&gt;
	&lt;li&gt;Ruby had become popular due to Rails, not the other way around as it is with Django&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So a Saturday night, I turned off the light, locked the door and sealed the windows. It was time to check out this Japanese creation. The fanboys all over the web seemed to recommend this fabulous book called &lt;a href="http://en.wikipedia.org/wiki/Why's_(poignant)_Guide_to_Ruby"&gt;Why's (poignant) guide to Ruby&lt;/a&gt;. I installed Ruby, and dove into the book.&lt;/p&gt;

&lt;p&gt;A few hours later, I had forgotten everything about Python. Stupid language. Ruby was where it was at, and I instantly started recommending it to all my code-buddies. It's such an awesome language, why not spread the joy? They said I was a fanboy, and told me to gtfo. And I quickly realized what had happened.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Ruby is evil&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ruby is indeed evil. So evil. Extremely evil. But why so evil? Because it's so &lt;em&gt;beautiful&lt;/em&gt;. The syntax is so elegant, everything are objects. Everything makes sense. The Ruby-way of doing things is so sexy.&lt;/p&gt;

&lt;p&gt;I quickly headed over to #ruby and asked them what I should do to practise my all-so-awesome Ruby skills, and some guy recommended me coding a todo-app. It seemed it was the new semi-advanced-but-no-so-advanced hello world. So I did, and here's the extremely awesome output (be prepared, it's extremely bad code and you should &lt;strong&gt;NEVER&lt;/strong&gt; do something like this in Ruby):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Todo&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@argv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;

    &lt;span class="k"&gt;begin&lt;/span&gt;
      &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@argv&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;TypeError&lt;/span&gt;
      &lt;span class="n"&gt;list&lt;/span&gt;
    &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;NoMethodError&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Command &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@argv&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; not found.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;help&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Lists help information&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;help&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;help&lt;/span&gt;
&lt;span class="sh"&gt;Commands for Todo.rb:&lt;/span&gt;
&lt;span class="sh"&gt;   add [task name] - Add a new task&lt;/span&gt;
&lt;span class="sh"&gt;   list - Lists all tasks&lt;/span&gt;
&lt;span class="sh"&gt;   done [task id] - Complete a task&lt;/span&gt;
&lt;span class="sh"&gt;   help - Prints out this information&lt;/span&gt;
&lt;span class="no"&gt;    help&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Add task&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;
    &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@argv&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Lacking argument [name]&amp;quot;&lt;/span&gt;
      &lt;span class="nb"&gt;exit&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Append task to file&lt;/span&gt;
    &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;todo.td&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;todo.td&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="vi"&gt;@argv&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# List all tasks&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;
    &lt;span class="c1"&gt;# Read content&lt;/span&gt;
    &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;todo.td&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;No tasks&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;

    &lt;span class="c1"&gt;# Show it with ids&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_line&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; - &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Finished a task&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;done&lt;/span&gt;
    &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@argv&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Lacking argument [id]&amp;quot;&lt;/span&gt;
      &lt;span class="nb"&gt;exit&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Put tasks into an array&lt;/span&gt;
    &lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;todo.td&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;No tasks&amp;quot;&lt;/span&gt;
      &lt;span class="nb"&gt;exit&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Completed task: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@argv&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Delete task from array and make string&lt;/span&gt;
    &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@argv&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Update file&lt;/span&gt;
    &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;todo.td&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Todo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Proudly I showed it to the guy who recommended me to create a Todo-app. "Look at this! Ruby is so narwhal!" It took him a while to reply. It would've taken me a while to reply too if somebody showed me such code. It looks like some Bash code, in an object oriented language. Woah.  So this guy, he was very helpful and told me he'd make a skeleton for the app. and make me fill in the holes/methods, it was something like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodoList&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# read the file, create a list, create items, add them&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# write the file, only write the undone items&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@list&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodoItem&lt;/span&gt;
&lt;span class="c1"&gt;# provide reader and setter for name and state&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# store name&lt;/span&gt;
    &lt;span class="c1"&gt;# set state to undone&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ---&lt;/span&gt;
&lt;span class="c1"&gt;# the library will be used like this:&lt;/span&gt;
&lt;span class="c1"&gt;# list = TodoList.load(&amp;quot;todo.td&amp;quot;)&lt;/span&gt;
&lt;span class="c1"&gt;# list[0].done = true&lt;/span&gt;
&lt;span class="c1"&gt;# list.add TodoItem.new(&amp;quot;another cool item&amp;quot;)&lt;/span&gt;
&lt;span class="c1"&gt;# list.write(&amp;quot;todo.td&amp;quot;)&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;So I did. It took a while to adapt from the bad PHP-style, to the Ruby-style. I ended up with &lt;a href="https://gist.github.com/6656de5cc00df7802c5e"&gt;this&lt;/a&gt;. And then I added &lt;a href="https://gist.github.com/94bc0e64442de04deb0b"&gt;an interface.&lt;/a&gt; And then &lt;a href="http://gist.github.com/255203"&gt;meta-programming.&lt;/a&gt; And then I was in love.&lt;/p&gt;

&lt;p&gt;So the title of this post is "What I wish a Ruby programmer had told me one year ago..", and that's quite an intro. Since what I wish a Ruby programmer had told me is not much, but could've saved me 4 months in company with PHP.&lt;/p&gt;

&lt;p&gt;Here's what I'll tell anyone asking me how they should get into programming:&lt;/p&gt;

&lt;p&gt;"First, learn Ruby (buy a book). Play around, create a Todo-app. Create simple programs to handle system tasks for you. But always remember to use classes, and separate the interface from the functionality. In the end this will be pain, you'll always think about making it appear Rubyish, but at some point - it becomes natural. And when it has become natural, you go &lt;a href="http://blog.sirupsen.dk/guides/create-your-first-ruby-gem-and-release-it-to-gemcutter/"&gt;create a Gem&lt;/a&gt;. If you create a big Gem, with much functionality - split it into more Gems, and make it require those. Or use other peoples Gems. If you want to move on with developing web applications, start out simple. Check out a lightweight framework like &lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt;, it's cool and very fun to work with. Move on to Rails if you want, it takes longer to learn, but it is much faster to develop in."&lt;/p&gt;

&lt;p&gt;And perhaps point them towards Linux, if they are up for it:&lt;/p&gt;

&lt;p&gt;"&lt;strong&gt;I&lt;/strong&gt; do not believe Windows is the best development platform in the world for Ruby. I recommend you to try out Linux (or OS X, if you've got the money for it). Start with a simple distribution, like &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;. And then I recommend something like &lt;a href="http://www.archlinux.org/"&gt;Arch Linux&lt;/a&gt; whenever you feel like you are ready for something more advanced, assuming you want to learn more about how Linux works!"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I'm biased. And I know it. Ruby is not a language for everyone, and PHP is not a bad language - it's just not for me. Neither is Python a bad language - it's just not for me. Windows is not a bad operating system - It's just not for me. I advise you to try different languages/operating systems, and eventually find the one you feel at home in.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/O2K4xrP1W6A" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/what-I-wish-a-ruby-programmer-had-told-me-one-year-ago</feedburner:origLink></entry>
 
 <entry>
   <title>Create your first Ruby Gem and release it to Gemcutter</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/sHIM-eItrz0/create-your-first-ruby-gem-and-release-it-to-gemcutter" />
   <updated>2010-04-20T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/create-your-first-ruby-gem-and-release-it-to-gemcutter</id>
   <content type="html">&lt;p&gt;A few days ago I was set off to create my first RubyGem. There are many resources on how to do this, but it took me a good while to gather all the information I figured I&amp;rsquo;d need for my application, so I&amp;rsquo;ve decided to gather my bit of knowledge in this article.&lt;/p&gt;

&lt;p&gt;This article&amp;rsquo;s goal is kick start the creation of your first Gem. To make this experience more enjoyable, I&amp;rsquo;ve chosen to use a gem called &lt;a href="http://github.com/technicalpickles/jeweler"&gt;Jeweler&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I am by no means a &amp;ldquo;ruby-pro&amp;rdquo;. I have only created a single Gem, but I thought this article could be helpful to a lot of people, and thus I wrote it. If you have any corrections, questions, or suggestions please either email me at sirup@sirupsen.dk or comment below.&lt;/p&gt;

&lt;!--more--&gt;


&lt;h2&gt;Preparing&lt;/h2&gt;


&lt;p&gt;.. for world domination!&lt;/p&gt;




&lt;p&gt;I assume you already know a bit of &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt;, that you know what &lt;a href="http://rubygems.org/"&gt;RubyGems&lt;/a&gt; is, and you have already downloaded a few gems, and used some of them in your work. Now your are simply seeking to create your own Gems. You are indeed in for a fun time, coding gems is lots of fun!&lt;/p&gt;




&lt;p&gt;Before we can begin, install the &lt;a href="http://github.com/technicalpickles/jeweler"&gt;Jeweler&lt;/a&gt; gem via RubyGems:&lt;/p&gt;


&lt;pre&gt;$ gem install jeweler&lt;/pre&gt;




&lt;p&gt;Jeweler is a tool to create the basic skeleton for your Gem, as well as managing the gem.&lt;/p&gt;




&lt;h2&gt;Creating your gem&lt;/h2&gt;


&lt;p&gt;.. with your mighty companion &lt;strong&gt;Jeweler&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Once Jeweler is installed, you want to create your Gem skeleton. I'm going to create a simple Hello World gem for the sake of example, and later on explain a bit about how you could manage your own Gem (at the very least my 2 cents about how a gem should be done).&lt;/p&gt;


&lt;pre&gt;$ jeweler helloworld # Should be all small letters&lt;/pre&gt;


&lt;pre&gt;   create  .gitignore
    create  Rakefile
    create  LICENSE
    create  README.rdoc
    create  .document
    create  lib
    create  lib/helloworld.rb
    create  test
    create  test/helper.rb
    create  test/test_helloworld.rb
Jeweler has prepared your gem in helloworld&lt;/pre&gt;




&lt;p&gt;Now your gem skeleton is ready! Let's get in there and check it out.&lt;/p&gt;




&lt;pre&gt;$ cd helloworld
$ ls
&lt;span style="color: #008000;"&gt;&lt;strong&gt;lib/&lt;/strong&gt;&lt;/span&gt;  LICENSE  Rakefile  README.rdoc  &lt;span style="color: #008000;"&gt;&lt;strong&gt;test/&lt;/strong&gt;&lt;/span&gt;&lt;/pre&gt;




&lt;p&gt;This structure might look familiar to you. (Assuming you are like me and have already stalked a few Gems' sources over at &lt;a href="https://github.com/"&gt;Github&lt;/a&gt;) Now I'll attempt to explain what these files and folders are.&lt;/p&gt;




&lt;h3&gt;lib/&lt;/h3&gt;




&lt;p&gt;This is where your application lives, this is where you'll probably spend the most of your time working on your gem. It is common to have a folder inside this folder called whatever your gem is called (in this example, that would be &lt;strong&gt;helloworld&lt;/strong&gt;), in which your app. is split into a few files, for organizations sake. And then have&lt;strong&gt; lib/&amp;lt;gem name&amp;gt;.rb &lt;/strong&gt;require these files (as &lt;strong&gt;/lib/&amp;lt;gem name&amp;gt;.rb &lt;/strong&gt;is what is required by Ruby whenever somebody requires your gem in their own project).&lt;/p&gt;


&lt;h4&gt;&lt;strong&gt;My 2 cents on organizing stuff in here &lt;em&gt;(skippable)&lt;/em&gt;&lt;/strong&gt;&lt;/h4&gt;


&lt;p&gt;As said, I am in no way an expert. But this is how I would do it.&lt;/p&gt;

&lt;p&gt;My first gem is a gem for a file storage service (&lt;a href="http://anyhub.net/"&gt;Anyhub&lt;/a&gt;) which should do two things:&lt;/p&gt;




&lt;ul&gt;
    &lt;li&gt;Create a library for easy Ruby interaction with Anyhub&lt;/li&gt;
    &lt;li&gt;Contain a small CLI for Anyhub based on it's own library&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;So I figured I would have a module, containing a few classes:&lt;/p&gt;




&lt;ul&gt;
    &lt;li&gt;Upload (for uploading files to Anyhub)&lt;/li&gt;
    &lt;li&gt;Account (to manage ones Anyhub account)&lt;/li&gt;
    &lt;li&gt;Runner (to manage the CLI)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The Upload class would simply be able to use the account class, to check if an account was configured in a config file (f.e. &lt;em&gt;account_config.yaml&lt;/em&gt;). If a config file was present, it would upload the file(s) specified in arguments to the script. Otherwise, it would return an error. Runner (the CLI) would respond to this error, allowing the user to type in his details so they could be used for the ongoing upload, as well as any following uploads (by saving the details to &lt;em&gt;account_config.yaml &lt;/em&gt;via the Account class).&lt;/p&gt;




&lt;p&gt;Now, I had made a perfectly good module. The only thing it needed was arguments send to Runner, which would activate it all. By doing a little research I figured if I created the directory &lt;strong&gt;bin/ &lt;/strong&gt;and threw in a file here, this file would automatically be inserted into the installers own bin (f.e. &lt;strong&gt;/usr/bin&lt;/strong&gt; on Linux if installed for all users). So I created the &lt;strong&gt;bin/&lt;/strong&gt; directory, and a file in here called &lt;strong&gt;&lt;a href="http://github.com/Sirupsen/Anyhub/blob/master/bin/anyhub"&gt;anyhub&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;with a Ruby shebang at the top. This file simply instanced the Runner class with ARGV.&lt;/p&gt;




&lt;p&gt;Now this is just my little not-so-fancy gem theory. It's not exactly done this way (yet) because Anyhub didn't have an API at first - so I created the first version without the Account class, so it might not be exactly like this at the Github repo. just yet.&lt;/p&gt;


&lt;p&gt;&lt;a href="http://github.com/Sirupsen/Anyhub"&gt;Anyhub gem @ Github.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;LICENSE&lt;/h3&gt;


&lt;p&gt;Simply a file which contains the license for your project. By default MIT with Jeweler.&lt;/p&gt;




&lt;h3&gt;Rakefile&lt;/h3&gt;


&lt;p&gt;Rake configuration for your project. It is here you can define rake tasks, and configure your project (in terms of the name of it, dependencies, description and similar).&lt;/p&gt;




&lt;h3&gt;Readme.rdoc&lt;/h3&gt;


&lt;p&gt;The Readme file for your project. If you create a Github repo. it'll show up there. It is also "the index" for your Gems' documentation.&lt;/p&gt;




&lt;h3&gt;test/&lt;/h3&gt;


&lt;p&gt;It is here you create your tests.&lt;/p&gt;




&lt;h2&gt;Configuring your Gem&lt;/h2&gt;


&lt;p&gt;Remember a few lines ago, I told you how you could configure your Gem via &lt;strong&gt;Rakefile&lt;/strong&gt;? As you might have already guessed, we're going to open that very file now, to configure our example Gem.&lt;/p&gt;




&lt;p&gt;After &lt;strong&gt;rubygems&lt;/strong&gt; and &lt;strong&gt;rake &lt;/strong&gt;has been required by &lt;strong&gt;Rakefile &lt;/strong&gt;we see some fancy code, and then something which looks like some configuration. This is indeed where we configure our example Gem. You mostly only need to configure the summary and description the first time, I did it like this:&lt;/p&gt;


&lt;pre&gt;begin
  require 'jeweler'
  Jeweler::Tasks.new do |gem|
    gem.name = "helloworld"
    gem.summary = %Q{I'm a helloworld gem! I like to hello the world.}
    gem.description = %Q{This is a fancy little test gem.}
    gem.email = "sirup@sirupsen.dk"
    gem.homepage = "http://github.com/Sirupsen/helloworld"
    gem.authors = ["Sirupsen"]
    gem.add_development_dependency "thoughtbot-shoulda", "&amp;gt;= 0"
    # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/  20 for additional settings
  end
  Jeweler::GemcutterTasks.new
rescue LoadError
  puts "Jeweler (or a dependency) not available. Install it with: gem install   jeweler"
end&lt;/pre&gt;




&lt;h3&gt;A little something more on configuring&lt;/h3&gt;


&lt;p&gt;.. which can be skipped.&lt;/p&gt;




&lt;p&gt;If your gem has any dependencies, you can add them here. Dependencies in this context mean&lt;em&gt; "gems which my gem depends on"&lt;/em&gt;. You &lt;strong&gt;should&lt;/strong&gt; add them, because if you do they are automatically installed along with your Gem whenever somebody tries to install your Gem. If you don't, they'll just get a good ton of errors when they try using your gem.&lt;/p&gt;




&lt;p&gt;Do add dependencies, simply add this to your &lt;strong&gt;Rakefile&lt;/strong&gt;:&lt;/p&gt;


&lt;pre&gt;gem.add_dependency "gem", "version"&lt;/pre&gt;




&lt;p&gt;For example, in my gem I used the &lt;strong&gt;Curb &lt;/strong&gt;Gem, and therefore I added this to my &lt;strong&gt;Rakefile&lt;/strong&gt;:&lt;/p&gt;


&lt;pre&gt;gem.add_dependency "curb", "&amp;gt;= 0"&lt;/pre&gt;


&lt;p&gt;(&lt;strong&gt;&amp;gt;= 0&lt;/strong&gt; just means "I don't care about which version of the Gem it is, as long as it's there", mostly because I couldn't find much version-specific documentation Curb, otherwise I would have done this properly.)&lt;/p&gt;




&lt;h2&gt;Let's add some sample code&lt;/h2&gt;


&lt;p&gt;Now it's time to add some code to our &lt;strong&gt;helloworld &lt;/strong&gt;Gem. I simply open &lt;strong&gt;/lib/helloworld.rb&lt;/strong&gt;, and add these few lines of code:&lt;/p&gt;


&lt;pre&gt;module HelloWorld
  def self.do
    "Hello World from the all mighty helloworld Gem!"
  end
end&lt;/pre&gt;




&lt;p&gt;So &lt;strong&gt;HelloWorld.do&lt;/strong&gt; would return the string &lt;em&gt;"Hello World from the all mighty helloworld Gem!". &lt;/em&gt;Great, so far, so good.&lt;/p&gt;




&lt;h2&gt;Version&lt;/h2&gt;


&lt;p&gt;In order to finish our Gem, we need a version file. Now because Jeweler is so awesome, we don't even need to use our editor to do this, simply execute the following command:&lt;/p&gt;


&lt;pre&gt;$ rake version:write&lt;/pre&gt;




&lt;p&gt;And the VERSION file is created. It's not &lt;em&gt;that&lt;/em&gt; fancy though.&lt;/p&gt;


&lt;pre&gt;$ cat VERSION
0.0.0&lt;/pre&gt;




&lt;p&gt;But that seems correct. This is our first Gem build, so of course, the version is 0.0.0 as of now!&lt;/p&gt;




&lt;h2&gt;Install it!&lt;/h2&gt;


&lt;p&gt;Now you can install the Gem. It's very easy:&lt;/p&gt;




&lt;pre&gt;$ rake install
Password:
(in /home/sirup/Code/Ruby/helloworld)
Generated: helloworld.gemspec
helloworld.gemspec is valid.
WARNING:  no rubyforge_project specified
  Successfully built RubyGem
  Name: helloworld
  Version: 0.0.0
  File: helloworld-0.0.0.gem
Executing "gem install ./pkg/helloworld-0.0.0.gem":
gem install ./pkg/helloworld-0.0.0.gem
Successfully installed helloworld-0.0.0
1 gem installed
Installing ri documentation for helloworld-0.0.0...
Updating class cache with 1983 classes...
Installing RDoc documentation for helloworld-0.0.0...&lt;/pre&gt;




&lt;h2&gt;Moment of truth&lt;/h2&gt;


&lt;pre&gt;irb --simple-prompt
&amp;gt;&amp;gt; require 'helloworld'
=&amp;gt; true
&amp;gt;&amp;gt; HelloWorld.do
=&amp;gt; "Hello World from the all mighty helloworld Gem!"&lt;/pre&gt;




&lt;p&gt;(&lt;strong&gt;Note&lt;/strong&gt;: If you are &lt;strong&gt;not&lt;/strong&gt; using Ruby 1.9, you might need to &lt;em&gt;require 'rubygems'&lt;/em&gt; before requiring &lt;strong&gt;helloworld&lt;/strong&gt;)&lt;/p&gt;




&lt;p&gt;Awesome, it works. I hope this has helped you towards creating your first gem. You are welcome to leave a comment, or contact me if you run into any trouble.&lt;/p&gt;




&lt;h2&gt;Further information&lt;/h2&gt;


&lt;p&gt;You'll find it all if you visit &lt;a href="http://github.com/technicalpickles/jeweler"&gt;Jeweler at Github&lt;/a&gt;. Below is for quick reference.&lt;/p&gt;




&lt;h3&gt;Github&lt;/h3&gt;


&lt;p&gt;I advice you to commit all your code, and push it to Github. Makes it easy for other people to view the source, post issues, and participate in your project.&lt;/p&gt;




&lt;p&gt;Github because it's sort of the standard for Ruby open source projects.&lt;/p&gt;




&lt;h3&gt;Releasing Gem at Gemcutter&lt;/h3&gt;


&lt;p&gt;If you feel like sharing your Gem to the world (and you probably do). Register an account at &lt;a href="http://rubygems.org/"&gt;Gemcutter&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;And now you are ready to release your Gem. Simply run:&lt;/p&gt;


&lt;pre&gt;$  rake gemcutter:release&lt;/pre&gt;




&lt;p&gt;To release your gem. (You can also release it at RubyForge instead if you wish so, see &lt;a href="http://github.com/technicalpickles/jeweler/blob/master/README.markdown"&gt;the Jeweler readme&lt;/a&gt;) You might be asked to sign in to your account, simply do so whenever prompted.&lt;/p&gt;




&lt;h3&gt;Workflow&lt;/h3&gt;


&lt;p&gt;.. taken directly from the &lt;a href="http://wiki.github.com/technicalpickles/jeweler/workflow"&gt;Jeweler Wiki.&lt;/a&gt;&lt;/p&gt;


&lt;ol&gt;
    &lt;li&gt;&lt;code&gt;gem install jeweler&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://wiki.github.com/technicalpickles/jeweler/create-a-new-project"&gt;Create a new project&lt;/a&gt; and customize it, or &lt;a href="http://wiki.github.com/technicalpickles/jeweler/configure-an-existing-project"&gt;configure an existing project&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;Write good code, and commit it&lt;/li&gt;
    &lt;li&gt;Bump the version with one of the rake tasks:
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;rake version:bump:patch&lt;/code&gt; 1.5.3 → 1.5.4&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;rake version:bump:minor&lt;/code&gt; 1.5.3 → 1.6.0&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;rake version:bump:major&lt;/code&gt; 1.5.3 → 2.0.0&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;rake version:write MAJOR=2 MINOR=3 PATCH=6&lt;/code&gt; 1.5.3 → 2.3.6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
    &lt;li&gt;Release it
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;rake release&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Optionally release it to &lt;a href="http://wiki.github.com/technicalpickles/jeweler/rubyforge"&gt;Rubyforge&lt;/a&gt;: &lt;code&gt;rake rubyforge:release&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Optionally release it to &lt;a href="http://wiki.github.com/technicalpickles/jeweler/gemcutter"&gt;Gemcutter&lt;/a&gt;: &lt;code&gt;rake gemcutter:release&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
    &lt;li&gt;Go to #2&lt;/li&gt;

&lt;/ol&gt;



&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/sHIM-eItrz0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/create-your-first-ruby-gem-and-release-it-to-gemcutter</feedburner:origLink></entry>
 
 <entry>
   <title>One terminal, just one</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/RAUnVkl6gb8/one-terminal-just-one" />
   <updated>2010-04-06T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/one-terminal-just-one</id>
   <content type="html">&lt;p&gt;Until not-so-long ago, I always had a million terminals open at the same time. I have this neat keyboard-shortcut (Alt-T) which opens a new terminal. That&amp;#8217;s nice and all, but the problem is, that I can&amp;#8217;t be arsed to alt-tab to my old terminals, leaving a million terminals open, making alt-tabbing between other applications a pain. And I rely quite a bit on Alt-tab, I don&amp;#8217;t have any task bar, since I&amp;#8217;d rather just alt-tab between stuff than clicking on a task bar (which also takes up precious screen space).&lt;/p&gt;
&lt;p&gt;So yes, one day I realised I really had this problem. So I scaled it down, my goal was to: On launch it looks for terminals.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If any terminal is found, this terminal should appear in front of all other windows, instead of launching a new terminal. If, however, no terminals are present, a new one should be launched.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&amp;#8217;s when I realised: &lt;strong&gt;&amp;#8220;How-the-bob am I going to do this?&amp;#8221;&lt;/strong&gt;- Google to the rescue, and I eventually scaled down each problem in the application, and found a neat little application called &lt;span class="fixed-width"&gt;wmctrl&lt;/span&gt; which (apparently) handles Windows. And by looking a bit at this application, I came up with this script, which handles the problem nicely:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="c"&gt;#! /bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;WINTITLE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;sakura&amp;quot;&lt;/span&gt; &lt;span class="c"&gt;# Name of the window (or part of it)&lt;/span&gt;
&lt;span class="nv"&gt;PROGRAMNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;sakura&amp;quot;&lt;/span&gt; &lt;span class="c"&gt;# Name of the program, so it can be opened if there&amp;#39;s no window currently&lt;/span&gt;

&lt;span class="c"&gt;# Lists all windows, if there&amp;#39;s one containing $WINTITLE it&amp;#39;ll return 1, and bring the current instance of the program to the front.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;wmctrl -l | grep -c &lt;span class="s2"&gt;&amp;quot;$WINTITLE&amp;quot;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;    &lt;/span&gt;wmctrl -a &lt;span class="s2"&gt;&amp;quot;$WINTITLE&amp;quot;&lt;/span&gt;
&lt;span class="c"&gt;# Else, it&amp;#39;ll launch a new instance&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="nv"&gt;$PROGRAMNAME&lt;/span&gt; &amp;amp;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# We&amp;#39;re good!&lt;/span&gt;
&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Just change the variables to reflect your environment, it should be rather obvious what to change. So yeah, you just c/p this script to a &lt;span style="fixed-width;"&gt;whatever.sh&lt;/span&gt; file, and put it in your &lt;span style="fixed-width;"&gt;bin&lt;/span&gt; and launch your terminal via this script from now on. It&amp;#8217;s also in my &lt;a href="http://github.com/Sirupsen/Kittybin"&gt;Kittybin&lt;/a&gt;, I might cover some of the other scripts from there in further blog posts. :)&lt;/p&gt;
&lt;p&gt;And there we go. &lt;strong&gt;Problem solved.&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/RAUnVkl6gb8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/one-terminal-just-one</feedburner:origLink></entry>
 
 <entry>
   <title>My experience with Arch Linux</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/BtVzQPZKC0k/my-experience-with-arch-linux" />
   <updated>2010-04-06T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/my-experience-with-arch-linux</id>
   <content type="html">&lt;p&gt;After about 8 months with &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;, I decided it was time for change. I had for a while wanted to switch to some other distribution, not because I did not like Ubuntu, more because I wanted to learn more about Linux, and try something new. And I felt Ubuntu limited me in this direction. Furthermore, I wanted to have a system which I did not feel I had to reinstall whenever new major updates came out, I wanted a system I could improve over time. I wanted a system where I could switch desktop environment/window manager quickly, and without googling myself on how to then remove all the old, now useless, packages. And rolling-release seems to be the solution, to that problem.&lt;/p&gt;

&lt;p&gt;I quickly found a distro. which seemed to fit my requirements, &lt;a href="http://www.archlinux.org/"&gt;Arch Linux&lt;/a&gt;. Arch Linux is lightweight, and simple. I found a quote on the Wiki, which describes it quite well:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&amp;ldquo;Linux, with a nice package manager.&amp;rdquo;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;And my edition:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&amp;ldquo;Linux, with an nice package manager, and a kick-ass Wiki.&amp;rdquo;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;That Wiki seriously provides the best information on everything you&amp;rsquo;ll ever need to know &amp;ndash; I have yet to run into a problem which is not described here.&lt;/p&gt;

&lt;p&gt;With Arch, you basically start with bare-bones Linux, which can boot into a CLI, has the basic stuff like Vi, grep, and these kind of basic Unix tools, that you&amp;rsquo;d have to install anyway, as well as a tool with which you can install packages. From there, you simply start building your system with the &lt;a href="http://wiki.archlinux.org/index.php/Beginners'_Guide"&gt;Arch Linux beginner&amp;rsquo;s guide&lt;/a&gt; (which is extremely well written). You install Vim, Xorg, Drivers, and so on. As it was my first (and hopefully only on this computer) install, I took good time to do each step, to understand what I was installing, and why I was installing it. Once I had Xorg up (I already felt like I had learned a lot more about how Linux works at a lower level. I was already starting to really like Arch Linux.&lt;/p&gt;

&lt;p&gt;At some point when Xorg was set up, I wanted a &lt;a href="http://wiki.archlinux.org/index.php/Window_manager"&gt;Window Manager&lt;/a&gt;. And it&amp;rsquo;s really a dungeon there. There are hundreds of different Window Managers, tiling, not-tiling, and these big desktop environments (Gnome, KDE). I had already decided I didn&amp;rsquo;t want to go for a desktop environment, since then I&amp;rsquo;d have loads of gui-configuring-tools, and not learn exactly where configuration files are located (&lt;em&gt;oh how I search the knowledge&lt;/em&gt;). I quickly figured out that &lt;a href="http://openbox.org/wiki/Main_Page"&gt;Openbox&lt;/a&gt; was very popular on the Arch Linux forums. So I decided to install it, and found the neat &lt;a href="http://rent0n86.deviantart.com/art/Arkid-148937983"&gt;Arkid theme&lt;/a&gt;, somebody had posted it in a screenshot thread on the Arch Linux forums. I&amp;rsquo;ve found Openbox to be great, and fit my needs.&lt;/p&gt;

&lt;p&gt;From there, it was just a matter of setting up all the stuff I usually set up when I install Ubuntu: Vim, Chrome, Pidgin, a music player, Dropbox, and so on. And Pacman (the Arch Linux package manager) made this a pleasing experience. I ran into a few packages which I could not install with Pacman however. But, I quickly figured there was something called &lt;a href="http://aur.archlinux.org/"&gt;AUR&lt;/a&gt; (the Arch User Repository), in which I have yet to not find a package, this helps me get minimum headaches, since the AUR packages usually compile OTB, running the right &lt;strong&gt;./configure&lt;/strong&gt; etc. And of course, my fellow Arch Linux users have also provided me with tools which allows easy installation from AUR. I found a tool called &lt;a href="http://bbs.archlinux.org/viewtopic.php?id=91860"&gt;Clyde&lt;/a&gt;, which works great. Basically a layer on Pacman with &lt;a href="http://bbs.archlinux.org/viewtopic.php?id=91860"&gt;AUR&lt;/a&gt; support.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve been running this system for a few weeks (as of this update, months), and I feel at home. I love it really. If you are looking to try something new, and already got some Linux experience, then you should defiantly go and try Arch Linux! Should you run into issues you have trouble addressing the people at #archlinux on chat.freenode.net are helpful.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s a screenshot of my Archbox, because everyone loves screenshots.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://img202.imageshack.us/img202/8011/201004050121043200x1080.png"&gt;&lt;img src="http://img202.imageshack.us/img202/8011/201004050121043200x1080.png" alt="" width="1152" height="389" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/BtVzQPZKC0k" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/my-experience-with-arch-linux</feedburner:origLink></entry>
 
 <entry>
   <title>Slow internet under Ubuntu or Linux</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/6ovIyWhwBk8/slow-internet-under-ubuntu-or-linux" />
   <updated>2009-10-31T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/slow-internet-under-ubuntu-or-linux</id>
   <content type="html">&lt;h2&gt;Fix one: &lt;span class="caps"&gt;DNS&lt;/span&gt; issue&lt;/h2&gt;
&lt;p&gt;Ever since I started using Linux, I&amp;#8217;ve run into issues regarding internet performance; it was unstable &amp;#8211; it would take it several seconds, sometimes 10-20, to look up the host for most sites. Overall, it was very unstable &amp;#8211; and rather unusable for a heavy surfer like me.&lt;/p&gt;
&lt;p&gt;Download speed, and basically everything but the browser worked fine. Thus, I concluded that it could have something to do with the &lt;span class="caps"&gt;DNS&lt;/span&gt; &amp;#8211; and I was right. I switched to &lt;a href="http://www.opendns.com/"&gt;OpenDNS&lt;/a&gt;, and it was running normally &amp;#8211; here&amp;#8217;s [the guide from &lt;a href="https://store.opendns.com/setup/device/ubuntu/"&gt;OpenDNS&lt;/a&gt; on configuring OpenDNS on Ubuntu, should you be using another Linux distro., simply Google something like &lt;strong&gt;linux-distro opendns&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I also stumbled upon &lt;a href="http://code.google.com/p/namebench/"&gt;Namebench&lt;/a&gt; in the process, which is a little Python application that attempts to find the fastest &lt;span class="caps"&gt;DNS&lt;/span&gt; for you &amp;#8211; which you can use to optimize performance further.&lt;/p&gt;
&lt;h2&gt;Fix two: IPV6&lt;/h2&gt;
&lt;p&gt;Currently, the standard for IPs is IPV4 &amp;#8211; the thing is, that there&amp;#8217;s always a limit towards to maximum number of IP-adresses available. We&amp;#8217;re nearing this limit rapidly with IPV4, and therefore IPV6 is set to replace the old IPV4. &lt;sup class="footnote"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt; However, some providers doesn&amp;#8217;t support IPV6 yet, and Linux might attempt to use IPV6, conclude it fails, and then use IPV4 &amp;#8211; each time it connects. This can be result in bad performance. Luckily, you can disable the IPV6 kernel  module, which fixes this.&lt;/p&gt;
&lt;h3&gt;Fixing on Debian-based systems&lt;/h3&gt;
&lt;p&gt;I don&amp;#8217;t know for sure, if this is the routine on anything non-debian based. I know this is not the way to go on e.g. Arch Linux. Debian-based systems include Linux Mint and Ubuntu.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You should be able to disable IPv6 by adding &lt;span class="fixed-width"&gt;ipv6.disable=1&lt;/span&gt; to kernel boot parameters (editing Grub config in &lt;span class="fixed-width"&gt;/boot/grub/menu.lstand&lt;/span&gt; running &lt;span class="fixed-width"&gt;sudo update-grub&lt;/span&gt; as instructed for example here). &lt;sup class="footnote"&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Other distros&lt;/h3&gt;
&lt;p&gt;Again, use Google and you&amp;#8217;ll probably be geared towards a Wiki, or forum thread for your specific distro.&lt;/p&gt;
&lt;p class="footnote" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;a href="http://en.wikipedia.org/wiki/IPv6"&gt;http://en.wikipedia.org/wiki/IPv6&lt;/a&gt;&lt;/p&gt;
&lt;p class="footnote" id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; &lt;a href="http://superuser.com/questions/67921/slow-website-loading-on-ubuntu-karmic"&gt;http://superuser.com/questions/67921/slow-website-loading-on-ubuntu-karmic&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/6ovIyWhwBk8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/slow-internet-under-ubuntu-or-linux</feedburner:origLink></entry>
 
 <entry>
   <title>Become a Dropbox ninja!</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/gkzx-nQw8Ss/become-a-dropbox-ninja" />
   <updated>2009-10-31T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/become-a-dropbox-ninja</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve known &lt;a href="http://dropbox.com"&gt;Dropbox&lt;/a&gt; for very long. I&amp;#8217;ve already found it to be an extremely cool service, however &amp;#8211; I like to have things automated, the little programmer inside all of us. I didn&amp;#8217;t want to &amp;#8220;Drop&amp;#8221; my files manually into the Dropbox folder all the time. That was time consuming, and I would forget to do it &amp;#8211; sort of eliminating the purpose.&lt;/p&gt;
&lt;p&gt;I wanted Dropbox to sync everything automatically across all my machine, I wanted to still have my files where they would originally be on my Desktop. On my Laptop, that didn&amp;#8217;t matter &amp;#8211; since I only use it for browsing the web, sometimes I program a bit on it, though. On my Desktop, I have all my Photos, configuration files, and code. I wanted to have these files available everywhere, anytime.&lt;/p&gt;
&lt;p&gt;The solution to this was simple, very simple because of symbolic links, under Linux (my desktop, and main computer) I&amp;#8217;d just download Dropbox, and place the special folder in my &lt;span class="fixed"&gt;~&lt;/span&gt;, then start throwing symbolic links in. First of, my photos.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ln -s Photos Dropbox/Photos
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then all my local code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ln -s /var/www Dropbox/Programming
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then my &lt;span class="fixed"&gt;Dumper&lt;/span&gt; which is basically anything else than videos, photos, music and programming:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ln -s Dumper Dropbox/Dumper
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In my dumper I even did symbolic links to some of the configuration directories (e.g. &lt;span class="fixed"&gt;Vim&lt;/span&gt; configuration, &lt;span class="fixed"&gt;.bashrc&lt;/span&gt; etc.)&lt;/p&gt;
&lt;p&gt;It started syncing, and now the magic of Dropbox is a lot more tempting to me. I now have everything, and the most recent version of it, available everywhere (iPhone, Laptop, Web), and it&amp;#8217;s securely backed up.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/dropbox.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;If Dropbox seems tempting to you (now?), be sure to sign up at &lt;a href="http://dropbox.com"&gt;Dropbox.com&lt;/a&gt; If you&amp;#8217;d like to help me, and yourself, you can signup via &lt;a href="https://www.getdropbox.com/referrals/NTgzODk4OTk"&gt;my referral link&lt;/a&gt; and you&amp;#8217;ll get (and give) 250 mb extra to the 2gb default free limit!&lt;/p&gt;
&lt;p&gt;Furthermore, Dropbox has &lt;a href="http://wiki.getdropbox.com/"&gt;a great wiki&lt;/a&gt; with &lt;a href="http://wiki.getdropbox.com/DropboxAddons"&gt;various addons&lt;/a&gt; and &lt;a href="http://wiki.getdropbox.com/TipsAndTricks"&gt;tips &amp;amp; and tricks&lt;/a&gt; . They even have a &lt;span class="caps"&gt;CLI&lt;/span&gt; to Dropbox, which I use nowadays on Arch Linux when I&amp;#8217;m without &lt;span class="fixed"&gt;Nautilus&lt;/span&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/gkzx-nQw8Ss" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/become-a-dropbox-ninja</feedburner:origLink></entry>
 
 <entry>
   <title>Starting with Git!</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/WHaPrfS4Tz4/starting-with-git" />
   <updated>2009-09-12T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/starting-with-git</id>
   <content type="html">&lt;p&gt;The purpose of this&lt;strong&gt; guide&lt;/strong&gt; or &lt;strong&gt;tutorial&lt;/strong&gt; is to give a brief overview of how to work with Git, even for people who've &lt;strong&gt;never&lt;/strong&gt; had any experience with version controlling. This guide anticipates that you:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Have &lt;strong&gt;a bit&lt;/strong&gt; experience with working in the terminal&lt;/li&gt;
	&lt;li&gt;Common sense&lt;/li&gt;
&lt;/ul&gt;
I will teach you how to:
&lt;ul&gt;
	&lt;li&gt;Set up a Github repository&lt;/li&gt;
	&lt;li&gt;Upload content to your Github repository&lt;/li&gt;
	&lt;li&gt;Work with Git&lt;/li&gt;
	&lt;li&gt;Simple collaboration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A lot of people still believe SVN is much better than Git. However, this is not the case. SVN's way of handling repositories is bad, it means everyone pushes to the same master "repository". In Git &lt;span style="background-color: #ffffff;"&gt;everyone has their own, which is a lot smarter. I'm not going to go in depth about the difference, since a lot of people, with &lt;strong&gt;much&lt;/strong&gt; more knowledge about Git and SVN than me, already did that. So you can Google your way to that.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;With that in shape, let's get started!&lt;/p&gt;

&lt;!--more--&gt;
&lt;h2&gt;Installing Git&lt;/h2&gt;
&lt;p&gt;Before starting this guide, you should have Git installed locally. You can download Git &lt;a title="Download git" href="http://git-scm.com/download"&gt;here.&lt;/a&gt; If you run Linux, there's a good chance that you can install it via your favorite package manager. For Ubuntu's package manager (Aptitude) the terminal command is:&lt;/p&gt;

&lt;pre&gt;sudo aptitude install git-core&lt;/pre&gt;

&lt;p&gt;You should most likely be able to type: "git" in the terminal, and it would give you the instructions on how to install it. This guide is not to cover the installation, but to teach the usage of Git. If you have troubles with installing, try to Google your way around!&lt;/p&gt;

&lt;a href="http://img33.imageshack.us/img33/2483/275300x159.png"&gt;&lt;img class="alignright" title="Github Project" src="http://img33.imageshack.us/img33/2483/275300x159.png" alt="A sample project at Github" width="300" height="159" /&gt;&lt;/a&gt;
&lt;h2 style="font-size: 1,5em;"&gt;&lt;strong&gt;Github&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;It has a lot of features, including graphs for your project, issue tracker and a wiki for your project.&lt;/p&gt;

Before you start on the next step, please register at&lt;a href="http://github.com/"&gt; Github&lt;/a&gt;.

&lt;h2&gt;Creating your first Repository&lt;/h2&gt;

&lt;p&gt;Our goal is to make a new repository, and upload a few files to it. Before we can do this though, we need to set up Git, so that Github knows who you are when you push things to their server.&lt;/p&gt;

&lt;h3&gt;Configuring Git&lt;/h3&gt;
&lt;p&gt;Configuring Git is very important, I used the first couple of hours with Git having headaches about Github not recognizing me, when I pulled stuff from my repositories at Github. However, it's pretty straight forward to configure.&lt;/p&gt;

&lt;p&gt;We need to do two things:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Create an SSH-key&lt;/li&gt;
	&lt;li&gt;Provide this SSH-key to Git&lt;/li&gt;
	&lt;li&gt;Introduce ourselves to Git!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is no reason for me to reinvent the wheel, Github has already done this. First, read their guide about &lt;a href="http://github.com/guides/providing-your-ssh-key"&gt;Providing your SSH Key&lt;/a&gt;, then go ahead and &lt;a href="http://github.com/guides/tell-git-your-user-name-and-email-address"&gt;Tell git your user name and email address&lt;/a&gt;.&lt;/p&gt;

&lt;a href="http://github.com/repositories/new"&gt;&lt;img class="size-medium wp-image-34 alignleft" style="padding-left: 5px;" title="Create a new Project" src="http://img197.imageshack.us/img197/2483/275300x159.png" alt="The dialog to create a new project" width="300" height="159" /&gt;&lt;/a&gt;

&lt;h3 style="font-size: 1,17em;"&gt;Creating the Repository&lt;/h3&gt;
&lt;p&gt;Creating our own repository is pretty straight forward. Go to Github, login and you'll be at your dashboard. At the right you should see &lt;a href="/repositories/new"&gt;(create a new one)&lt;/a&gt;. Click it, and it'll take you to the page where you can create your project.&lt;/p&gt;

&lt;p&gt;Fill out the fields as you like, I'll call my project "Test". Hit submit. Now you've created your online Git repository!&lt;/p&gt;

&lt;img class="size-medium wp-image-35 alignright" style="padding-left: 5px;" title="Github new Repository" src="http://img197.imageshack.us/img197/7453/276300x289.png" alt="Here's the new repository I created" width="300" height="289" /&gt;

&lt;p&gt;You'll be taken to your new project, and you'll notice Github provides you a small guide on how to upload the first files to your project! Again, let's just follow Github's guide once again.&lt;/p&gt;

&lt;p&gt;The first step is the Global setup step, we don't need to do this though, but because you followed the guides before, this is already done! I find it weird though, it doesn't tell you to provide your SSH key. Ignore this step.&lt;/p&gt;

&lt;p&gt;However, we can follow the next steps:&lt;/p&gt;

&lt;p&gt;Fire up a terminal, and type (replace Test with the name of the name of the repository you created on Github):&lt;/p&gt;
&lt;pre&gt; mkdir Test&lt;/pre&gt;

&lt;p&gt;Afterwards, navigate into this new directory by typing:&lt;/p&gt;
&lt;pre&gt; cd Test&lt;/pre&gt;

&lt;p&gt;Instance Git inside this directory by typing:&lt;/p&gt;
&lt;pre&gt; git init&lt;/pre&gt;

&lt;p&gt;Create a new file by typing:&lt;/p&gt;
&lt;pre&gt; touch README&lt;/pre&gt;

&lt;p&gt;Add this file to the repository by typing:&lt;/p&gt;
&lt;pre&gt; git add README&lt;/pre&gt;

&lt;p&gt;Now, let's make a change to this file, by writing something to it:&lt;/p&gt;
&lt;pre&gt; echo "Hello, is this on Github?!" &amp;gt; README&lt;/pre&gt;

&lt;p&gt;Now, we need to commit. Committing is a small message of what you just did (we'll cover more about that later):&lt;/p&gt;
&lt;pre&gt; git commit -m 'Initial upload'&lt;/pre&gt;
&lt;img class="size-medium wp-image-38 alignleft" style="padding-left: 5px;" title="README File" src="http://img197.imageshack.us/img197/8923/277300x170.png" alt="README file on Github" width="300" height="170" /&gt;

&lt;p&gt;Next, we need to add the online Github repository (the origin), this is done by adding a remote origin (notice that you'll need to change "Sirupsen" and "Test" to reflect your own user, and repository):&lt;/p&gt;
&lt;pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;"&gt; git remote add origin git@github.com:Sirupsen/Test.git&lt;/pre&gt;
And finally, let's push it to Github.
&lt;pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;"&gt; git push origin master&lt;/pre&gt;
&lt;p&gt;(This means we push the commits to the origin (master repository), at the master branch)&lt;/p&gt;

&lt;p&gt;Now, go to your Github repository and you should notice a file named "README", if you open it you should see whatever you echoed into that file.&lt;/p&gt;

&lt;p&gt;Now you've added your first file to Github! Continue to learn more about how to work with Git.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Working with Git&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Now you know how to do the most basic stuff with Git, and Github:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Creating a local folder to represent your Git repository&lt;/li&gt;
	&lt;li&gt;Committing changes to a file&lt;/li&gt;
	&lt;li&gt;Update this on the server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this, you can do the most basic stuff with Git. Now I will introduce you to some of the more exciting features of Git.&lt;/p&gt;
&lt;h2&gt;Pulling changes from the origin&lt;/h2&gt;
&lt;a href="http://blog.kirth.be/wp-content/uploads/2009/09/279.png"&gt;&lt;img class="alignright" style="padding-left: 5px; border: 0px initial initial;" title="Edit File on Github" src="http://img195.imageshack.us/img195/8963/279300x126.png" alt="Click Edit to edit the file" width="300" height="126" /&gt;&lt;/a&gt;

&lt;p&gt;But, what if I change something online. And would like to apply these updates on my local copy of the repository? That's what we're going to do now. First, let's go to our Github repository. Click on the file you'd like to edit (you'll probably only have your README file currently). When your viewing the file, you can chose edit to edit it.&lt;/p&gt;

&lt;p&gt;Now you can edit your file. Make a few changes - create a small commit message, then hit commit.&lt;/p&gt;

&lt;a href="http://blog.kirth.be/wp-content/uploads/2009/09/280.png"&gt;&lt;img class="size-medium wp-image-40 alignleft" style="padding-left: 5px;" title="Editting a file on Github" src="http://img195.imageshack.us/img195/7143/280300x179.png" alt="Editing a file on Github" width="300" height="179" /&gt;&lt;/a&gt;

&lt;p&gt;Now, when you've added some stuff to your README file, it's time to pull the changes to your local repository. Open up the terminal where you arranged yourself into the Test directory, and pull from the origin:&lt;/p&gt;
&lt;pre&gt; git pull origin master&lt;/pre&gt;

&lt;p&gt;Try to open the README file again, and you should see the changes you made on Github! Another way to check the output is by writing:&lt;/p&gt;
&lt;pre&gt; cat -A README&lt;/pre&gt;

&lt;p&gt;Which will output the contents of the file directly in the terminal.&lt;/p&gt;
&lt;h2 style="font-size: 1,5em;"&gt;Cloning a repository&lt;/h2&gt;

&lt;p&gt;Instead of making a directory, adding the origin, and pulling, each time you&lt;span style="background-color: #ffffff;"&gt;need a copy of your repository. You can simply use the clone command, which clones the repository to your machine. Let's try it. First, delete your local copy of the repository.&lt;/span&gt;&lt;/p&gt;

&lt;a href="http://img195.imageshack.us/img195/1087/281300x44.png"&gt;&lt;img class="alignright" style="padding-left: 5px; border: 0px initial initial;" title="Github Repository Information" src="http://img195.imageshack.us/img195/1087/281300x44.png" alt="Github repository informations" width="300" height="44" /&gt;&lt;/a&gt;

&lt;p&gt;Next, go to your Github repository, and on the top locate your private clone URL (see picture to the right). &lt;span style="background-color: #ffffff;"&gt;Copy it, and go to your terminal and type (replace my URL, with your own private clone URL):&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt; git clone git@github.com:Sirupsen/Test.git&lt;/pre&gt;

&lt;p&gt;And then you should have a fresh copy of your repository!&lt;/p&gt;
&lt;h2&gt;Deleting files from your repository&lt;/h2&gt;
&lt;p&gt;Sometimes you may need to delete files permanently from your Git repository. The command for this is almost the same as the basic delete command ("rm"), we just need to have git in front of it. This command will both remove the file form your harddrive, as well as remove it from the git repository.&lt;/p&gt;

&lt;p&gt;For instance, I've added a file called "INSTALL". But I ended up just adding this text to the README file. I already added the content of the INSTALL file to the README file, and committed these changes - but now I want to delete the INSTALL file, as it serves no purpose anymore.&lt;/p&gt;

&lt;p&gt;To delete the file, we type:&lt;/p&gt;
&lt;pre&gt; git rm INSTALL&lt;/pre&gt;

&lt;p&gt;And then we need to commit the changes:&lt;/p&gt;
&lt;pre&gt; git commit -m 'Removed INSTALL file, due to content having been appended to the README file'&lt;/pre&gt;

&lt;p&gt;Finally, push it to Github:&lt;/p&gt;
&lt;pre&gt; git push origin master&lt;/pre&gt;

&lt;p&gt;Simple, right?&lt;/p&gt;
&lt;h2&gt;The Difference&lt;/h2&gt;

&lt;p&gt;At some point you might have just cleaned up a few files, and totally forgot about commiting.  Its ok if you don't even remember which files you edited. To find the difference from the Github repository, and your local copy simply type:&lt;/p&gt;
&lt;pre&gt; git diff&lt;/pre&gt;

&lt;p&gt;And it'll show what is different. As it might be a bit pain to add each individual file like this:&lt;/p&gt;
&lt;pre&gt; git add file1 file2 file3 file4&lt;/pre&gt;

&lt;p&gt;And then give them a shared commit, there's an easier way:&lt;/p&gt;
&lt;pre&gt; git commit -a -m 'Cleaned up files'&lt;/pre&gt;

&lt;p&gt;This takes all the files which are different from the main repository (Github), and gives them the commit entered after -m. This is also good when you are editing a single file, because instead of:&lt;/p&gt;
&lt;pre&gt; git add file&lt;/pre&gt;
&lt;pre&gt; git commit -m 'Added function to calculate average'&lt;/pre&gt;
You can do:
&lt;pre&gt; git commit -a -m 'Added function to calculate average'&lt;/pre&gt;
&lt;p&gt;It automatically picks up the changed file(s), and then commits them. Cool, right?&lt;/p&gt;

&lt;h2&gt;Workflow&lt;/h2&gt;
&lt;p&gt;Now you know all the basic commands of git, and you know how to work with Github. Let's take a quick look at an example of how our workflow could be like now:&lt;/p&gt;

&lt;p&gt;I create a file, and call it index.php, I've already added some stuff to it. Now, I want to push it to Github:&lt;/p&gt;
&lt;pre&gt; git add index.php&lt;/pre&gt;
&lt;pre&gt; git commit -m 'Added index file'&lt;/pre&gt;
You might ask now, why don't we use:
&lt;pre&gt; git commit -a -m 'Added index file'&lt;/pre&gt;
-a will not add new files to the repository, you'll have to do that with add the first time.
Alright, now I've added the file. I make some more changes to the file, and I commit it:
&lt;pre&gt; git commit -a -m 'Added a menu'&lt;/pre&gt;
Now I think it's good enough, to be pushed to Github:
&lt;pre&gt; git push origin master&lt;/pre&gt;
These 3 commands are by far the ones which you are going to use the most.
&lt;ul&gt;
	&lt;li&gt;Commit&lt;/li&gt;
	&lt;li&gt;Add&lt;/li&gt;
	&lt;li&gt;Push&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As I said  before, it's very important that you commit every time you can rinse up what you've done in one sentence. Commit messages must be short, and precise. You should maybe use some time on your first commits, but over time you should learn creating small informative and useful commits. That's all for now, we might come around collaboration in Git in a later post. The best way to learn is always trying out, and if you don't know how to do something, use Google!&lt;/p&gt;

&lt;p&gt;For further reading go to Git's official website, and &lt;a href="http://git-scm.com/"&gt;read the documentation.&lt;/a&gt; Github also has &lt;a href="http://github.com/guides/home"&gt;several amazing articles on Git! &lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/WHaPrfS4Tz4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/starting-with-git</feedburner:origLink></entry>
 
 <entry>
   <title>Dual booting Windows and Linux</title>
   <link href="http://feedproxy.google.com/~r/Sirupsen/~3/8JxvA5nNE3o/dual-booting-windows-and-linux" />
   <updated>2009-09-12T00:00:00-07:00</updated>
   <id>http:/sirupsen.github.com/dual-booting-windows-and-linux</id>
   <content type="html">&lt;p&gt;When I for the first time wanted to try out Linux, I couldn't at first glance find a simple guide on how to dual-boot Windows and Linux. So I decided to write a quick simple guide for you, to give an overview of how to create your own dual boot system. You should have the following stuff solved before you try this out:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Windows CD
&lt;ul&gt;
	&lt;li&gt;Be sure you have a valid serial for it, and so on&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Linux CD
&lt;ul&gt;
	&lt;li&gt;Ubuntu, Fedora, Mint or whatever you might prefer&lt;/li&gt;
	&lt;li&gt;Check out &lt;a href="http://distrowatch.com/"&gt;distrowatch&lt;/a&gt; if you have yet to decide&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Backup of &lt;strong&gt;all&lt;/strong&gt; your important files
&lt;ul&gt;
	&lt;li&gt;Also configuration files are handy to have&lt;/li&gt;
	&lt;li&gt;.. and plugins!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When this is solved, you should be ready to get started.&lt;/p&gt;

&lt;p&gt;What you do when you want two operation systems, is basically you have a partition for each. Linux requires an additional swap partition, Windows requires only one partition for the entire system. You can even share a partition between both operation systems. However, if you want Windows to be able to read it, you'll need it to be FAT32 (both Windows and Linux handles this filesystem fine!), and you need to create the shared partition, when you install Windows. (I.e. if you have Windows installed now, and would like to have an extra shared drive with Linux, you can't create it when you install Linux, since then Windows won't find it).&lt;/p&gt;

&lt;p&gt;You might not know what a partition is, but it's quite simple. Imagine you have your harddisk, and you split it into smaller chunks, and store stuff here. As humans remember, and learn better by illustrations, I made one (bear with me, I'm bad at drawing):&lt;/p&gt;

&lt;a href="http://img42.imageshack.us/img42/6572/partitions.png"&gt;&lt;img style="border: 0px initial initial;" title="Paritions" src="http://img42.imageshack.us/img42/6572/partitions.png" alt="" width="500" height="200" /&gt;&lt;/a&gt;

&lt;p&gt;Imagine partition 1 being Windows, partition 2 Linux and partition 3 the shared drive. (I didn't include the swap one here, as it would be pretty small on the scale, but&lt;strong&gt; it is&lt;/strong&gt; a partition like the other ones)&lt;/p&gt;

&lt;p&gt;Now, you should decide how your partition scheme should be like. There's tons of options, for this example (to keep it simple) we'll go with this, please check the comments for other ways to do it:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Windows partition (partition we install Windows on) [NTFS]&lt;/li&gt;
	&lt;li&gt;Linux Partition (partition we install Linux on) [EXT4]
&lt;ul&gt;
	&lt;li&gt;Swap partition (partition we install swap for linux on) [swap]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Shared Partition (partition we want Linux and Windows to share) [FAT]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alright, let's get to it. For this "guide" I assume we are working on a 500 gb harddrive (plan how you partition your own harddrive). And we want a shared partition between the two systems. This should give a basic knowledge of what you need to do.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Boot from Windows CD
&lt;ul&gt;
	&lt;li&gt;If you happen to not being able to boot from it, go into your BIOS and set CD as first for boot priority
&lt;ul&gt;
	&lt;li&gt;Should you have trouble doing this, google your way around for it. There's &lt;strong&gt;plenty&lt;/strong&gt; of articles on that subject&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Create two partitions in Windows partition manager
&lt;ul&gt;
	&lt;li&gt;Partition to install Windows on [100 GB]&lt;/li&gt;
	&lt;li&gt;Partition we share between Linux and Windows, which we format to Fat32 later [300 GB]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Install Windows on the first partition
&lt;ul&gt;
	&lt;li&gt;Format it with NTFS (not quick, since quick doesn't examine for bad stuff)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Now wait a while for Windows to install
&lt;ul&gt;
	&lt;li&gt;Enter your valid serial when prompted&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;When your done it should boot&lt;/li&gt;
	&lt;li&gt;Install your drivers
&lt;ul&gt;
	&lt;li&gt;You'll probably have to restart a few times&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Go to "My Computer", and open the D:/ drive (the shared partition)
&lt;ul&gt;
	&lt;li&gt;It'll ask you to format&lt;/li&gt;
	&lt;li&gt;Do so, and pick FAT32 as the filesystem&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Boot up in Windows, and take out the Windows CD
&lt;ul&gt;
	&lt;li&gt;Then put in the Linux CD (Ubuntu, Fedora or whatever distroration you picked)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Restart your computer&lt;/li&gt;
	&lt;li&gt;Now, there's two kind of installation cd's:
&lt;ul&gt;
	&lt;li&gt;LiveCD: (Fedora has this), it'll boot into the Fedora system. On the desktop there will be a shortcut named something like "Install on your system", click this and you'll get into the installation&lt;/li&gt;
	&lt;li&gt;Normal: (Ubuntu has this), you'll be greeted by a screen where you can pick install, check disc etc. Pick install.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Now you should be taken through some installation stuff, time, location, etc.&lt;/li&gt;
	&lt;li&gt;At some point, you'll be at a partition manager.
&lt;ul&gt;
	&lt;li&gt;Ubuntu (Maybe Mint, and other ubuntu based systems too, not sure): You have an option to install the system side by side with the Windows system, do this. Does all the partitioning stuff for you! This will take the rest of the space, ~ 100 GB.&lt;/li&gt;
	&lt;li&gt;Fedora (And probably any other system): Create a new partition named: "/" (this is the Linux system) [93 GB]. And a "/boot" partition [200 mb] (This is probably for Fedora only, never tried any other system than Ubuntu and Fedora, check your systems installation guide). And then you need the swap one, just pick swap from the dropdown of filesystems. To figure your size, follow this guideline [6 GB for me, as I have 4 GB ram]:&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style="padding-left: 1,6em; list-style-image: url(http://docs.fedoraproject.org/install-guide/f11/en-US/html/Common_Content/images/dot.png); list-style-type: circle;"&gt;
	&lt;li style="line-height: 1,29em; padding-top: 0px; margin-top: 0em; padding-bottom: 0px; margin-bottom: 0,4em;"&gt;
&lt;div style="line-height: 1,29em; padding-top: 0px; margin-top: 0em; padding-bottom: 0px; margin-bottom: 0,3em;"&gt;M = Amount of RAM in GB, and S = Amount of swap in GB:&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style="padding-left: 1,6em; list-style-image: url(http://docs.fedoraproject.org/install-guide/f11/en-US/html/Common_Content/images/dot.png); list-style-type: circle;"&gt;
	&lt;li style="line-height: 1,29em; padding-top: 0px; margin-top: 0em; padding-bottom: 0px; margin-bottom: 0,4em;"&gt;
&lt;pre style="line-height: 1,29em; font-family: 'liberation mono', 'bitstream vera mono', 'dejavu mono', monospace; display: block; background-color: #eeeeee; margin-bottom: 0,3em; padding-top: 0,5em; padding-right: 1em; padding-bottom: 0,5em; padding-left: 1em; white-space: pre-wrap; word-wrap: break-word;"&gt;If M &amp;lt; 2
	S = M *2
Else
	S = M + 2&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Follow the last configuration&lt;/li&gt;
	&lt;li&gt;Now, your system restarts and you should see a list of different systems to choose from (remember to take our your CD, so you don't boot the installation CD again), when you boot (i.e. Windows and Linux distroration):
&lt;ul&gt;
	&lt;li&gt;Try to boot Windows
&lt;ul&gt;
	&lt;li&gt;Test shared drive&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;Restart&lt;/li&gt;
	&lt;li&gt;Boot Linux
&lt;ul&gt;
	&lt;li&gt;Test shared drive&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
	&lt;li&gt;And everything should be working great! You should be able to access the shared drive on both systems!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I can &lt;strong&gt;not&lt;/strong&gt; take any responsibility for &lt;strong&gt;any&lt;/strong&gt; damage you may cause to your system, while following this guide. It's written only to give a overview of what you need to do, in order to create a dual boot system.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/Sirupsen/~4/8JxvA5nNE3o" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://sirupsen.github.com/dual-booting-windows-and-linux</feedburner:origLink></entry>
 
</feed>

