<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Intertube Traveller</title><atom:link href="http://arnklint.com/feed.xml" rel="self" type="application/rss+xml" /><link>http://arnklint.com</link><description>How To Node is a blog featuring projects and tutorials relating to the Node.js project.</description><pubDate>Fri, 16 Aug 2013 16:07:48 +0000</pubDate><generator>http://github.com/creationix/wheat</generator><language>en</language><item><title>5 Useful Browser Extensions for Web Developers</title><link>http://arnklint.com/useful-extensions-for-programmers</link><comments>http://arnklint.com/useful-extensions-for-programmers#disqus_thread</comments><pubDate>Sun, 15 Jul 2012 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/useful-extensions-for-programmers</guid><description>&lt;p&gt;jsonview, stylish, 1password&lt;/p&gt;

&lt;p&gt;On the theme of productivity and effiecency... I´d like to share the extensions I use daily to get more productive
and do less stuff, while achieving even more.&lt;/p&gt;

&lt;p&gt;Most extensions that I´ve installed tend to fade away and never gets
used. These are the grain of gold of browser extensions for programmers
that has stayed with me.&lt;/p&gt;

&lt;h2&gt;Web Developer&lt;/h2&gt;

&lt;p&gt;Available in Chrome and Firefox, Chris Pederick´s browser extension &lt;a href=&quot;http://chrispederick.com/work/web-developer/&quot;&gt;Web
Developer&lt;/a&gt; is a perfect
multi tool for developing the web. Easily disable cookies, images or JavaScript. One click to clear browser cache and validate everything from CSS to HTML. In short, a must have if you do client side programming.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://lastpass.com/&quot;&gt;LastPass&lt;/a&gt; and &lt;a href=&quot;http://keepass.info/&quot;&gt;keepass&lt;/a&gt; can be considered as good alternatives also providing browser extensions for the same problem. &lt;/p&gt;

&lt;h2&gt;JSONView&lt;/h2&gt;

&lt;p&gt;Whenever doing an AJAX call or browsing an API through HTTP GET´s in the
browser 
&lt;a href=&quot;https://chrome.google.com/webstore/detail/chklaanhfefbnpoihckbnefhakgolnmc&quot;&gt;JSONView&lt;/a&gt;
really comes in handy, formatting and making json more readable in the browser.&lt;/p&gt;

&lt;h2&gt;Stylish&lt;/h2&gt;

&lt;p&gt;Easily style any site the way you want and persist that style. Sort of like
Greasemonkey/Userscripts (which works out of the box in Chrome), but for CSS. Create and manage CSS rules for
matching URLs. Useful when performing repetetive tasks without
scripting on a site. Removing noisy elements on sites that is used
often, or trying out (persistant) styles on a project of yours, without
deploying any code.&lt;/p&gt;

&lt;h2&gt;1Password&lt;/h2&gt;

&lt;p&gt;This is not just an extension, but also a great app for storing and
managing passwords securely. It is a paid app and browser extension that
comes to handy whenever i use a browser.
I´ve used &lt;a href=&quot;https://agilebits.com/onepassword&quot;&gt;1Password&lt;/a&gt; since their
launch, but mostly since they launched the Chrome extension. This is not
solely aimed at programmers of course, but a must have for security
reasons for everyone.&lt;/p&gt;

&lt;h2&gt;Vimium&lt;/h2&gt;

&lt;p&gt;Being a bit of a geek when it comes to IDE´s/Text Editors, VIM is and
has been my first choice the last couple of years. Since faster navigation is
one of the pros using VIM, the same keystrokes and navigation methods
can be applied in the browser. The usual HJKL is implemented as well
as Insert mode and find. Give
&lt;a href=&quot;https://chrome.google.com/webstore/detail/dbepggeogbaibhgnhhndojpepiihcmeb&quot;&gt;VIMium&lt;/a&gt; a go!&lt;/p&gt;

&lt;h2&gt;Tips appreciated&lt;/h2&gt;

&lt;p&gt;I´ve only touched on the surface of browser extensions for Web
Developers. The less extensions I´m dependent on, the more I can focus
on stuff that matters. It tends to be the same for me when it comes to
programming or developing products.&lt;/p&gt;

&lt;p&gt;However, those few golden grains in your toolbox can be hugely valuable
and stay with you forever. So, please tell me which extensions I´m
missing here.&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>What makes a good Web API?</title><link>http://arnklint.com/inspiration-building-an-api</link><comments>http://arnklint.com/inspiration-building-an-api#disqus_thread</comments><pubDate>Mon, 07 May 2012 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/inspiration-building-an-api</guid><description>&lt;p&gt;Building a great API is a hard task. There are many pitfalls to avoid to
succeed and since (hopefully) your API will be a dependency for many
systems, you will want to try to hit it hard right from the start.&lt;/p&gt;

&lt;p&gt;During &lt;a href=&quot;http://www.infoq.com/QConSanFrancisco2011;jsessionid=7A62B0CEAF7F879FE1CEF0EC1AAFC986&quot;&gt;QCon San Francisco
2011&lt;/a&gt; &lt;a href=&quot;http://twitter.com/#!/emcooke&quot;&gt;Evan Cooke&lt;/a&gt;, co founder of Twilio presents a &lt;a href=&quot;http://www.infoq.com/presentations/Building-a-Great-Web-API&quot;&gt;great talk&lt;/a&gt; involving Web API's and how to make them awesome.&lt;/p&gt;

&lt;h2&gt;This makes a good API&lt;/h2&gt;

&lt;p&gt;In the talk Evan cites &lt;a href=&quot;http://en.wikipedia.org/wiki/Joshua_Bloch&quot;&gt;Joshua
Bloch&lt;/a&gt; from Google who suggests that these
points makes a great API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to learn&lt;/li&gt;
&lt;li&gt;Easy to use - even without documentation&lt;/li&gt;
&lt;li&gt;Hard to misuse&lt;/li&gt;
&lt;li&gt;Easy to maintain the code that uses the API&lt;/li&gt;
&lt;li&gt;Powerful enough to satisfy the requirements&lt;/li&gt;
&lt;li&gt;Easy to extend&lt;/li&gt;
&lt;li&gt;Appropriate to audience&lt;/li&gt;
&lt;/ul&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Continuation</title><link>http://arnklint.com/continue-the-path</link><comments>http://arnklint.com/continue-the-path#disqus_thread</comments><pubDate>Fri, 04 May 2012 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/continue-the-path</guid><description>&lt;p&gt;We are working hard to get to &lt;a href=&quot;http://revrise.com&quot;&gt;Form Analytics&lt;/a&gt; out of the door into the real world. Early
mornings and late nights. We put a large part of our life into something
we cannot physically touch or hold in our hands. We are creating
something new that &lt;em&gt;hopefully&lt;/em&gt; brings a huge value to our customers. Every now
and then, a bit of doubt comes knocking at our door, while happiness and satisfaction comes knocking the next day. Creating something innovative is an emotional rollercoster.&lt;/p&gt;

&lt;h2&gt;Blind folded&lt;/h2&gt;

&lt;p&gt;Sometimes when working on the same product hour after hour, you tend to
stop seeing the real value it actually provides to the world. You
stop seeing the benefits of using it. You might even start doubting
about its existence and all the hours you put into it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://instagr.am/p/PQyv8/&quot;&gt;&lt;img src=&quot;/continuation/kastajerallee.jpg&quot; alt=&quot;Cafe working in Berlin&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what I believe just a sign of pure sanity. It is perfectly
normal to doubt. Just as long as you stay with it and continue the long
path to happy users and a great product.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You can doubt as much as you want as long as you continue building an amazing product.
  ~ J.A.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are humans and when building something innovative, ground breaking
never seen before kind of product you should embrace the fact that this
is a journey. A long lasting journey towards more satisfaction and a better world to live in.&lt;/p&gt;

&lt;h2&gt;Please do continue&lt;/h2&gt;

&lt;p&gt;I've had some minor previous success with a couple of projects, but they
tended to fade out and I lost motivation for them. I doubted, I beleived
in better ideas, I started seeing new opportunities.&lt;/p&gt;

&lt;p&gt;Those were the exact reasons to why those projects failed in the end. I
lost motivation and stopped working on them. The continuation was gone.&lt;/p&gt;

&lt;p&gt;Lets face it. The only way to not succeed in something is to give up and
stop making it happen. This goes for all of us. Whether you are a
creator, inventor, developer, employee, boss or a baby bird in its nest.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/continuation/startup-curve.png&quot; /&gt;
Most &lt;a href=&quot;http://www.avc.com/a_vc/2012/03/the-startup-curve.html&quot;&gt;fellow entrepreneurs&lt;/a&gt; experience the same, so don't be afraid.&lt;/p&gt;

&lt;p&gt;So my advice to myself and to you, fellow creator, inventor and human;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have doubts, be happy, be sad. Feel fear for failure, opportunity for success.&lt;/strong&gt;&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Using VIM Buffers</title><link>http://arnklint.com/using-vim-buffers</link><comments>http://arnklint.com/using-vim-buffers#disqus_thread</comments><pubDate>Mon, 23 Apr 2012 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/using-vim-buffers</guid><description>&lt;p&gt;Thinking of buffers in vim as tabs when using Textmate just made so much
sense. So much sense that I wanted to write down the basics for me to
come back to. Here are some few tips on how to use them to work
efficient in VIM.&lt;/p&gt;

&lt;h2&gt;Buffers?&lt;/h2&gt;

&lt;p&gt;I think of buffers as references to the files you are working with
currently. Try visualizing opening a file in a Textmate project. It
becomes a tab and when opening another file, that too becomes another
tab. So for me buffers in VIM is like tabs in Textmate, but not as
visible or noisy.&lt;/p&gt;

&lt;h3&gt;List buffers&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;:ls - list all buffers&lt;/li&gt;
&lt;li&gt;:b [tab] - display all buffers&lt;/li&gt;
&lt;li&gt;:b my[tab] - display buffers whos filename starts with ´my´&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Navigate between buffers&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;:e#5 - go to buffer 5&lt;/li&gt;
&lt;li&gt;:b5 - go to buffer 5&lt;/li&gt;
&lt;li&gt;:b# - Switch between two buffers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Delete buffers&lt;/h3&gt;

&lt;p&gt;If you want to delete a buffer in vim (like closing a tab in TextMate
eg):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;:bdelete [buffernumber or filename]&lt;/li&gt;
&lt;li&gt;:bd - a shorter version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next I´ll try to figure out how bookmarks works.&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Prowl Node.js API</title><link>http://arnklint.com/prowl-node-api</link><comments>http://arnklint.com/prowl-node-api#disqus_thread</comments><pubDate>Sat, 21 Apr 2012 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/prowl-node-api</guid><description>&lt;p&gt;PUSH notifications are all good and all. But do our products in
&lt;a href=&quot;http://revrise.com&quot;&gt;RevRise&lt;/a&gt; really need them? We´re in the middle of
making the last couple of changes to Form Analytics and I´m evaluating a
couple of additions to it.&lt;/p&gt;

&lt;h2&gt;Testing PUSH notifications in a prototype/early stage product&lt;/h2&gt;

&lt;p&gt;When evaluating stuff, you might want a cost effective and quick to
setup solution. Let´s realize that you don´t code an iPhone app to test
the behaviour/response of PUSH notifications IRL. No you don´t. However, there is actually an
app for that.&lt;/p&gt;

&lt;p&gt;I quickly stumbled upon &lt;a href=&quot;http://www.prowlapp.com/&quot;&gt;Prowl&lt;/a&gt; which is like
Growl, but for iPhone. Through its HTTP REST(ful) API you can send PUSH notifications to iPhone/iPad with the prowl app on them.&lt;/p&gt;

&lt;p&gt;Since the biggest part of our stack rely on JavaScript, I decided to
make a sweet little Node.js library for sending PUSH notifications via
Prowl.&lt;/p&gt;

&lt;h2&gt;Meet node-prowl - the Node.js lib for Prowl&lt;/h2&gt;

&lt;p&gt;It´t super easy to use:&lt;/p&gt;

&lt;p&gt;var prowl = new Prowl('MY-API-KEY');
  prowl.push('YO, this is awesomez!', 'My app', function( err, remaining ){
    if( err ) throw err;
    console.log( 'I have ' + remaining + ' calls to the api during current hour. BOOM!' );
  });&lt;/p&gt;

&lt;p&gt;Install it by:&lt;/p&gt;

&lt;p&gt;npm install node-prowl&lt;/p&gt;

&lt;p&gt;It's as simple as that!&lt;/p&gt;

&lt;p&gt;Find the docs and source in its
&lt;a href=&quot;https://github.com/arnklint/node-prowl&quot;&gt;repository&lt;/a&gt;.&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Tagging version in Git</title><link>http://arnklint.com/tagging-in-git</link><comments>http://arnklint.com/tagging-in-git#disqus_thread</comments><pubDate>Wed, 18 Apr 2012 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/tagging-in-git</guid><description>&lt;p&gt;As the work with the Node.js &lt;a href=&quot;https://github.com/arnklint/revrise-node&quot;&gt;wrapper&lt;/a&gt; for our public API at &lt;a href=&quot;http://revrise.com&quot;&gt;RevRise&lt;/a&gt; has got on, I just realized that tagging versions in git is super important in the aspect of package managers.&lt;/p&gt;

&lt;h2&gt;How to tag versions in Git&lt;/h2&gt;

&lt;p&gt;This is my first public node package, that is already used by a number
of clients and therefore it is extra important to keep it versioned.&lt;/p&gt;

&lt;p&gt;Let´s get going:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git tag -a v0.0.3 -m &quot;Bumping version&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;View tags by:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git describe --tags
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And show the actual commit by:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git show v0.0.3
&lt;/code&gt;&lt;/pre&gt;

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

&lt;pre&gt;&lt;code&gt;$ git push --tags
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Voila!&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Decision Making</title><link>http://arnklint.com/decisions</link><comments>http://arnklint.com/decisions#disqus_thread</comments><pubDate>Wed, 21 Mar 2012 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/decisions</guid><description>&lt;p&gt;Everybody have to make them, we make them all the time, some turn out to
be the right ones and other do not. Decisions are there to make them.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p&gt;Decisions! Can't make them. Can't not make them. Can't not not make them.&lt;/p&gt;&amp;mdash; Eric Wahlforss (@ericw)
&lt;a
href=&quot;https://twitter.com/twitterapi/status/164061748234682369&quot;
data-datetime=&quot;2011-11-07T20:21:07+00:00&quot;&gt;November 7,
2011&lt;/a&gt;&lt;/blockquote&gt;

&lt;script src=&quot;//platform.twitter.com/widgets.js&quot;
charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;h2&gt;Different types of decisions&lt;/h2&gt;

&lt;p&gt;There are different types of decisions to be made in your life. Those
that don´t matter, those that really matter. Those that take time and
those that don't take any time at all to make. &lt;/p&gt;

&lt;p&gt;Wether deciding your meal at the restaurant or choosing city to live in
the next couple of years, they have one thing in common. You do have to
make them. So lets make them fast, trust our instincts and learn from
the wrong decisions you will make.&lt;/p&gt;

&lt;p&gt;Most of my friends tends to spend more time comparing different meals on
a restaurant than buying that expensive pair of jeans, which is kind of
strange when looking at what resources (money) that you spend in either
case.&lt;/p&gt;

&lt;h2&gt;How to make decisions&lt;/h2&gt;

&lt;p&gt;The people I know that have been successful in one way or another, tend
to make fast decisions. They decide based on current situation and
context and then simply move on. If it turns out to be the wrong
decision, they choose a different path. The important thing is to make
them and move on.&lt;/p&gt;

&lt;p&gt;Thinking about it made me realize that&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Most decisions do not turn out to be right or wrong until after you
 made them. &lt;/li&gt;
&lt;li&gt;Humans think all decisions matter equaly. That's not true. Think
 of this the next time ordering food or choosing walking path in the woods.&lt;/li&gt;
&lt;li&gt;In most cases you are able to change your decision after some time.&lt;/li&gt;
&lt;li&gt;Think of it as A/B testing. Try one path and change if it you have
 to later on.&lt;/li&gt;
&lt;li&gt;Do, Fail, Iterate. The worst thing that will happen is that you
 learn from it and gain experience.&lt;/li&gt;
&lt;/ol&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>The Nine Month Entrepreneur</title><link>http://arnklint.com/the-nine-month-entrepreneur</link><comments>http://arnklint.com/the-nine-month-entrepreneur#disqus_thread</comments><pubDate>Wed, 22 Feb 2012 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/the-nine-month-entrepreneur</guid><description>&lt;p&gt;Today exactly one year ago I was on the same flight as I am now, meeting
up with the same friend down in Stockholm as I was then, on the same
trip to Chamonix, France as I was then. There is only two major
differences from one year ago. I'm staying in Chamonix and my friend has
just made his first exit.&lt;/p&gt;

&lt;h2&gt;The bet (exit before 30)&lt;/h2&gt;

&lt;p&gt;There is this Jazz bar in central Chamonix, France where me and my very
good friend just had had a couple of beers and sat down talking about
life and the future. We were there on a much needed vacation from work
and every day life. On friday, this was exactly one year ago. &lt;/p&gt;

&lt;h2&gt;One year ago&lt;/h2&gt;

&lt;p&gt;Since I started consulting five years ago, I've always had ideas and a
hard time not thinking about them. I've had my own company since 2004
and think of myself as one who solves problems and make life easier for
other people. 
I was constantly on hacker news, or reading about startups, tech and
opportunities to do just that. Solve problems. Even during vacation.
Because I loved it.&lt;/p&gt;

&lt;p&gt;My friend was completely the other way around. He never thought about
the latest javascript framework or tools that could help you solve
problems. He had ideas, but no urge to execute them. He had always been
an employee but was a bit tired of being one.
I don't know how many times during that week he told me to chill out,
stop browsing Hacker News and read a book...&lt;/p&gt;

&lt;p&gt;The local beer in chamonix is a lighter one with a taste that my friend
loves. After a day in the slopes those taste just great. &lt;/p&gt;

&lt;p&gt;There is a jazz/funk bar in central chamonix where we went one night
drinking a couple of those white beers. A common theme of discussion for
this trip was our future lives and entrepreneurship. I had just had a
life changer and my friend was just about to get over his. 
I remember how we spoke jokingly about how great it would be to live in
Chamonix and how your quality of life would increase. How you would wake
up in the morning looking out from the balcony into a horizon filled
with mountains and peaks. We could ski during daytime only on days when
the weather conditions were perfect and the snow was of highest quality.
And during the rest of the days and during night time, we could work
from a small office in central Chamonix. Hacking away on our next big
saas-app. What a way to live your life!&lt;/p&gt;

&lt;p&gt;That evening in the bar we also made jokes about who was going to be the
first one of us doing an exit. We asked ourselves how our lives would be
different in just one year.&lt;/p&gt;

&lt;p&gt;And here we are, exactly one year later. My friend is in the middle of
making his first exit, which in total has taken him nine months from an
idea to a product used by numerous client mainly in Scandinavia. His
team has not only executed beautifully and built the product, they are
actually selling it already! &lt;/p&gt;

&lt;p&gt;I'm living in a chalet on top of that very same jazz/funk bar in
Chamonix. Hacking away during night time and skiing during the day. I've
incorporated a startup around e-commerce and web analytics which has
just seen some of its first traction!&lt;/p&gt;

&lt;p&gt;Sometimes you have got to take one step back, to get a clear view of
life from another perspective than you always look through and make
bigger &lt;a href=&quot;/decisions&quot;&gt;decisions&lt;/a&gt; about how you really want to live it. Say no, don't be
afraid of variation because usually that is only healthy. Don't be
afraid to combine life style with your startup because if you want to
continue doing the things you love, health, motivation and fun will be
key.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: I got their press release which you'll read
&lt;a href=&quot;http://episerver.com/About-Us/Press-Room/Press-Releases/EPiServer-Acquires-200OK-AB-an-Enterprise-Search-Solution-Provider/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Saying No</title><link>http://arnklint.com/saying-no</link><comments>http://arnklint.com/saying-no#disqus_thread</comments><pubDate>Wed, 25 Jan 2012 15:14:14 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/saying-no</guid><description>&lt;blockquote&gt;
  &lt;p&gt;The hardest thing is, when you think about focusing, is saying no.&lt;/p&gt;
  
  &lt;p&gt;~ Steve Jobs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some may have realized this a long time ago. But I know quite a few freelancers in my business having a hard time keeping a balance of work load. This includes me.&lt;/p&gt;

&lt;p&gt;Keeping work load down and having a balanced schedule is key to keep happiness, health and well being.&lt;/p&gt;

&lt;h2&gt;Greediness&lt;/h2&gt;

&lt;p&gt;Sure, saying no can be really hard. I find that most of the times I say yes to work it’s about greediness. You just want more and more money or credit for something you create. In some ways this can be a good thing that maybe motivates you, allthough life would indeed be dull if the only thing that keeps you motivated was money.&lt;/p&gt;

&lt;h2&gt;Fear&lt;/h2&gt;

&lt;p&gt;Strangely fear has struck me when making desicions about work. I’m really afraid that if I say no this time, the client will never hire me again. Thinking this way will soon burn you out. The imminent likelyhood of you doing a good job somewhere and word of mouth begin spreading while you keep saying ‘yes’ will force you to work long hours, having less fun at work, evolving slower and so on. This is wrong.&lt;/p&gt;

&lt;p&gt;Saying no to something just allows you to spend time and focus on more important stuff.&lt;/p&gt;

&lt;h2&gt;Never too late&lt;/h2&gt;

&lt;p&gt;A great friend of mine once told me that “It’s never too late to say no”. Soon thereafter I took on a job with a lot of risk which eventually resulted in a complete failure.&lt;/p&gt;

&lt;p&gt;If I could have said no even a week in or two, I’m sure the client and myself would have been a lot more happier with the end result than we are now. I won’t go into details, but hey, we all make mistakes right.&lt;/p&gt;

&lt;p&gt;Even if you have already said ‘yes’, you can always say no.&lt;/p&gt;

&lt;h2&gt;Creating Quality is About Focus&lt;/h2&gt;

&lt;p&gt;It takes a great amount of effort to create something of great quality. It also takes a lot of focus. Since I started consulting about four years ago, I’ve always tended to have lots of ideas and a lot of different duties, working on two or three projects in parallel.&lt;/p&gt;

&lt;p&gt;This is really good if you want to produce work of low quality but on a greater scale. You’ll never become an expert if you do this. You’ll only keep struggleing when planning your days and get lots of interruptions that will cost you even more focus and time.&lt;/p&gt;

&lt;p&gt;Promise yourself to dare saying no. Increase your hourly rate if money is an issue, but make sure to produce good stuff. That is what will differentiate you from the others.&lt;/p&gt;

&lt;p&gt;So before I go and say no to a big deal, this sums up my thoughts on the issue quite well:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;We’re always thinking about new markets we could enter, but it’s only
  by saying no that you can concentrate on the things that are really
  important.&lt;/p&gt;
  
  &lt;p&gt;~ Steve Jobs, Business Week (12 October 2004)&lt;/p&gt;
&lt;/blockquote&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>'load' vs 'require' in Ruby</title><link>http://arnklint.com/ruby-load-vs-require</link><comments>http://arnklint.com/ruby-load-vs-require#disqus_thread</comments><pubDate>Fri, 26 Aug 2011 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/ruby-load-vs-require</guid><description>&lt;p&gt;Another 'note to self'. This time it's about Ruby.&lt;/p&gt;

&lt;h2&gt;load 'file.rb'&lt;/h2&gt;

&lt;p&gt;This needs the extension to be supplied, reads the file's content each time it is loaded, no matter how many times it is. And you can load a file from another directory simply by providing a relative or absolute path;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;load '../file.rb'
load '/home/deploy/file.rb'
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;require 'file'&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;No file extension should be supplied&lt;/li&gt;
&lt;li&gt;Only reads the target files content the first time.&lt;/li&gt;
&lt;/ul&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Minimal Rake Deploy Task</title><link>http://arnklint.com/minimal-deploy-task</link><comments>http://arnklint.com/minimal-deploy-task#disqus_thread</comments><pubDate>Sun, 10 Jul 2011 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/minimal-deploy-task</guid><description>&lt;p&gt;A great professor that I had during my studies at &lt;a href=&quot;http://jth.se&quot;&gt;JTH&lt;/a&gt;
always said that while a Volvo kept on running smoothly, a Ferrari would
need service every 500 kilometer just because of its refined design of
the engine and other parts. &lt;/p&gt;

&lt;p&gt;I think the same goes for code. Basically, whenever you bring in an
extra third party library or a &lt;a href=&quot;http://rubygems.org&quot;&gt;gem&lt;/a&gt; as we, ruby
people, might call them, you tend to add complexity and dependencies.&lt;/p&gt;

&lt;h2&gt;Skipping capistrano for small projects&lt;/h2&gt;

&lt;p&gt;Take &lt;a href=&quot;https://github.com/capistrano/capistrano&quot;&gt;Capistrano&lt;/a&gt; for
instance. A great gem for deploying apps to remote servers. It has a ton
of support for different scm's and stuff and does a great job doing what
it is supposed to do. However, when analysing what I tend to use it for
nowadays, I realized that I basically only push production code to a
bunch of servers. I never rollback, as all the apps I'm dealing with has
staging environments, where those issues will be noticed first.&lt;/p&gt;

&lt;p&gt;So why not skip capistrano and go with good old Rake instead? This even saves you
time on each deploy:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;desc &quot;Deploy the application&quot;
task :deploy do
  commands = [
    &quot;cd /apps/my_app&quot;,
    &quot;git fetch&quot;,
    &quot;git reset --hard origin/production&quot;,
    &quot;git submodule init&quot;,
    &quot;git submodule update&quot;,
    &quot;mkdir -p tmp&quot;,
    &quot;touch tmp/restart.txt&quot;
  ]
  exec &quot;ssh deploy@server.remote '#{commands.join(&quot; &amp;amp;&amp;amp; &quot;)}'&quot;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Put that in your &lt;code&gt;Rakefile&lt;/code&gt; and you're good to go. Simple, elegant,
flexible - just the way you want it!&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Autocompiling Coffeescript on Save in VIM</title><link>http://arnklint.com/autocompile-coffeescript-vim</link><comments>http://arnklint.com/autocompile-coffeescript-vim#disqus_thread</comments><pubDate>Sun, 03 Jul 2011 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/autocompile-coffeescript-vim</guid><description>&lt;p&gt;There are two problems with keeping a &quot;daemon&quot; compiling coffeescript
and those are error handling and always having to initialize that
daemon. However, there is a simpler way.&lt;/p&gt;

&lt;h2&gt;Changing .vimrc&lt;/h2&gt;

&lt;p&gt;Keeping some kind of long running process just to compile
&lt;a href=&quot;http://jashkenas.github.com/coffee-script/#language&quot;&gt;Coffeescript&lt;/a&gt; running doesn't really seem like the right solution. Since VIM has great
support for modding and making your custom scripts and commands in
.vimrc, I decided to find a solution for autocompiling on save instead:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;autocmd BufWritePost,FileWritePost *.coffee :silent !coffee -c &amp;lt;afile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pretty simple, right? Add parameters according to the &lt;a href=&quot;http://jashkenas.github.com/coffee-script/&quot;&gt;Coffeescript
documentation&lt;/a&gt; to customize the compilation. For example, I don't want to
wrap all my separate files with Coffeescripts own wrapper, so I'll add
--no-wrap:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;autocmd BufWritePost,FileWritePost *.coffee :silent !coffee --no-wrap -c &amp;lt;afile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Tada! The simple way to compile Coffeescript on save in VIM!&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>File Type Icons for Links with CSS</title><link>http://arnklint.com/css-link-icons</link><comments>http://arnklint.com/css-link-icons#disqus_thread</comments><pubDate>Wed, 29 Sep 2010 07:09:01 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/css-link-icons</guid><description>&lt;p&gt;First of all, there is a &lt;a href=&quot;https://github.com/arnklint/Hyperlink-icons-with-CSS&quot;&gt;github
repo&lt;/a&gt; which I'm
referring mostly referring to down below. There is all you need to
install this CSS module.&lt;/p&gt;

&lt;p&gt;This is a &quot;plugin&quot; essentially consisting of an image (a sprite image) and a stylesheet for you to add nice little icons to the right of hyperlinks that lead to a file with a certain extension. Like &lt;a href=&quot;#untitled.pdf&quot;&gt;my non-existing pdf-file&lt;/a&gt; for example. &lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;For production, simply use the hyperlink_icons.css as a stylesheet and make sure that it is referencing the sprite.gif image correctly. This should make links look like the examples below:&lt;/p&gt;

&lt;h3&gt;Extensions&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.rtf&quot;&gt;.rtf&lt;/a&gt; &lt;a href=&quot;#untitled.doc&quot;&gt;.doc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.txt&quot;&gt;.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.pdf&quot;&gt;.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.xls&quot;&gt;.xls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.xpi&quot;&gt;.xpi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.atom&quot;&gt;.atom&lt;/a&gt; &lt;a href=&quot;#untitled.rss&quot;&gt;.rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.opml&quot;&gt;.opml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.vcard&quot;&gt;.vcard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.exe&quot;&gt;.exe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.app&quot;&gt;.app&lt;/a&gt; &lt;a href=&quot;#untitled.dmg&quot;&gt;.dmg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.pps&quot;&gt;.pps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.ical&quot;&gt;.ical&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.eps&quot;&gt;.eps&lt;/a&gt; &lt;a href=&quot;#untitled.jpg&quot;&gt;.jpg&lt;/a&gt; &lt;a href=&quot;#untitled.gif&quot;&gt;.gif&lt;/a&gt; &lt;a href=&quot;#untitled.png&quot;&gt;.png&lt;/a&gt; &lt;a href=&quot;#untitled.bmp&quot;&gt;.bmp&lt;/a&gt; &lt;a href=&quot;#untitled.svg&quot;&gt;.svg&lt;/a&gt; &lt;a href=&quot;#untitled.eps&quot;&gt;.eps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.fla&quot;&gt;.fla&lt;/a&gt; &lt;a href=&quot;#untitled.swf&quot;&gt;.swf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.css&quot;&gt;.css&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.m4a&quot;&gt;.m4a&lt;/a&gt; &lt;a href=&quot;#untitled.mp3&quot;&gt;.mp3&lt;/a&gt; &lt;a href=&quot;#untitled.wav&quot;&gt;.wav&lt;/a&gt; &lt;a href=&quot;#untitled.ogg&quot;&gt;.ogg&lt;/a&gt; &lt;a href=&quot;#untitled.wma&quot;&gt;.wma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.ace&quot;&gt;.ace&lt;/a&gt; &lt;a href=&quot;#untitled.zip&quot;&gt;.zip&lt;/a&gt; &lt;a href=&quot;#untitled.rar&quot;&gt;.rar&lt;/a&gt; &lt;a href=&quot;#untitled.gzip&quot;&gt;.gzip&lt;/a&gt; &lt;a href=&quot;#untitled.bzip&quot;&gt;.bzip&lt;/a&gt; &lt;a href=&quot;#untitled.ace&quot;&gt;.ace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.ttf&quot;&gt;.ttf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.mpg&quot;&gt;.mpg&lt;/a&gt; &lt;a href=&quot;#untitled.mov&quot;&gt;.mov&lt;/a&gt; &lt;a href=&quot;#untitled.wmv&quot;&gt;.wmv&lt;/a&gt; &lt;a href=&quot;#untitled.mp4&quot;&gt;.mp4&lt;/a&gt; &lt;a href=&quot;#untitled.avi&quot;&gt;.avi&lt;/a&gt; &lt;a href=&quot;#untitled.mpg&quot;&gt;.mpg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.phps&quot;&gt;.phps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#untitled.torrent&quot;&gt;.torrent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;e-Mail/Messaging URI schemes&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;mailto:somebody@somedomain.tld&quot;&gt;mailto:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;callto:USERNAME&quot;&gt;callto:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;msnim:USERNAME&quot;&gt;msnim:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;xmpp:USERNAME&quot;&gt;xmpp:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;aim:USERNAME&quot;&gt;aim:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.icq.com/0123456789&quot;&gt;ICQ Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://edit.yahoo.com/config/send_webmesg?.target=USERNAME&amp;amp;.src=pg&quot;&gt;YIM! Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;skype:USERNAME&quot;&gt;skype:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;gg:USERNAME&quot;&gt;gg:&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Compatibility&lt;/h3&gt;

&lt;p&gt;This CSS module has been successfully tested in &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Firefox&lt;/em&gt; (Mac &amp;amp; PC) &lt;/li&gt;
&lt;li&gt;&lt;em&gt;Camino&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Safari&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Opera&lt;/em&gt; (Mac &amp;amp; PC)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Internet Explorer 7&lt;/em&gt; (6 doesn't work)&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;Icons by &lt;a href=&quot;http://famfamfam.com/&quot;&gt;famfamfam&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This work is licensed under a &lt;a href=&quot;http://creativecommons.org/licenses/by/2.5/&quot;&gt;Creative Commons Attribution License&lt;/a&gt;.&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Git Submodule Guide</title><link>http://arnklint.com/git-submodules</link><comments>http://arnklint.com/git-submodules#disqus_thread</comments><pubDate>Sat, 11 Sep 2010 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/git-submodules</guid><description>&lt;p&gt;Sometimes you may have to keep third party libraries included in you
project up to date in an easy way. Submodules in Git makes this as
simple as a pimple. &lt;/p&gt;

&lt;h2&gt;Adding a Submodule to a Git Repository&lt;/h2&gt;

&lt;p&gt;First, lets add the third party repository as a submodule to a sub
folder in our own repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/code &amp;gt; git submodule add git@mygithost:project.git lib/folder
Cloning into lib/folder...
remote: Counting objects: 448, done.
remote: Compressing objects: 100% (444/444), done.
remote: Total 448 (delta 290), reused 0 (delta 0)
Receiving objects: 100% (448/448), 493.84 KiB | 322 KiB/s, done.
Resolving deltas: 100% (290/290), done.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, lets see what this did to our repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/code &amp;gt; git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use &quot;git rm --cached &amp;lt;file&amp;gt;...&quot; to unstage)
#
#new file:   .gitmodules
#new file:   lib/folder
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;.gitmodules&lt;/code&gt; file  basically tells Git to keep track of lib/folder as a git submodule. 
Add those files and get on with it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git add . &amp;amp;&amp;amp; git commit -m &quot;Submodule added&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Using and Updating a Git Submodule&lt;/h2&gt;

&lt;p&gt;When cloning a repository with submodules in it for the first time, the
folders where the submodules live are empty. In order to get the latest
source you can initialize the submodule:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git submodule init
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then update it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git submodule update
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Voila!&lt;/p&gt;

&lt;p&gt;You can look at submodules as its own repositories inside yours. 
And as submodules updated this way are headless, we can make sure to pull
from a specific branch in our submodule (in this case, master):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd lib/folder
git checkout master
git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Commit those changes and we're done!&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Using variables in Ruby Regular Expressions</title><link>http://arnklint.com/variable-regular-expressions</link><comments>http://arnklint.com/variable-regular-expressions#disqus_thread</comments><pubDate>Wed, 02 Sep 2009 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/variable-regular-expressions</guid><description>&lt;p&gt;An easy way to deal with variating Regular Expressions.&lt;/p&gt;

&lt;h2&gt;Use variables in regular expressions&lt;/h2&gt;

&lt;p&gt;Pretty basic concept, that I can't seem to remember whenever I need it. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Note to self!

re = &quot;string&quot;
&quot;my string&quot; =~ /#{re}/    # =&amp;gt; 3

# So you can do:

a = 'dog'
b = 'hates cats'
str = &quot;my dog hates cats&quot;
str.match(/#{a} #{b}/)    # =&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Distribute your Rails App with a One Click .exe</title><link>http://arnklint.com/one-click-exe-ruby</link><comments>http://arnklint.com/one-click-exe-ruby#disqus_thread</comments><pubDate>Sun, 30 Aug 2009 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/one-click-exe-ruby</guid><description>&lt;p&gt;Ever wondered how to distribute you rails application to a window
instance. This is how:&lt;/p&gt;

&lt;h2&gt;Distribute your Rails app with a one click .exe&lt;/h2&gt;

&lt;p&gt;There is a great tool for making a ruby application run smoothly on
Microsoft platforms. It's called RubyScript2Exe and Tar2RubyScript. The
author of both of these has made a great job explaining how to
distribute a Rails app as a one click .exe with the above tools.
However, the example is about three years old by now, so a small update
is posted here.&lt;/p&gt;

&lt;p&gt;The part I have changed since Erik posted the tutorial (which is using
Ruby on Rails version 0.14.3) is the following. Instead of:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Rails
  class Configuration
    def database_configuration
      conf = YAML::load(ERB.new(IO.read(database_configuration_file)).result)
      if defined?(TAR2RUBYSCRIPT)
        conf.each do |k, v|
          if v[&quot;adapter&quot;] =~ /^sqlite/
            v[&quot;database&quot;] = oldlocation(v[&quot;database&quot;]) if v.include?(&quot;database&quot;)
            v[&quot;dbfile&quot;]   = oldlocation(v[&quot;dbfile&quot;]) if v.include?(&quot;dbfile&quot;)
          end
        end
      end
      conf
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Super Simpler SPAM Protection in Ruby on Rails</title><link>http://arnklint.com/super-simple-spam-protection-in-rails</link><comments>http://arnklint.com/super-simple-spam-protection-in-rails#disqus_thread</comments><pubDate>Thu, 27 Aug 2009 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/super-simple-spam-protection-in-rails</guid><description>&lt;p&gt;SPAM bots usually fill in all of the fields in a form, especially those
who a user would normally fill in. The plan is to simply trick the bot
into filling in a form element, call it &quot;comment&quot;, that is hidden from
the real users. When the form is submitted, we will detect if it is
filled in. If it is, well, then we have our SPAM bot.&lt;/p&gt;

&lt;h2&gt;Protect your Rails Application from SPAM&lt;/h2&gt;

&lt;p&gt;The model:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Post &amp;lt; ActiveRecord::Base
  attr_accessor :comment # fake attribute used for spam trapping
  validates_length_of :comment, :in =&amp;gt; 0..1
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then the view in which we ask the user to not care about a field (if
CSS is turned off, otherwise it's hidden)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;% form_for @comment do |f| %&amp;gt;
   ...
   &amp;lt;p style=&quot;width: 1px; height: 1px; overflow: hidden;&quot;&amp;gt;
     Please leave following field blank:
     &amp;lt;%= f.text_area :comment %&amp;gt;
   &amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;SPAM means problem&lt;/h2&gt;

&lt;p&gt;One common problem with popular sites are SPAM bots. You know, the ones
that fill in your forms, submit them and hopes to get their word out
about what I should buy and click on. But as they don't really
contribute to your site, you'd probably want to get rid of them or don't
have their posts published in the first place.&lt;/p&gt;

&lt;p&gt;Don't let the user suffer from the problem
One way to get rid of them are CAPTCHA's. Even if those are good at
differentiate users from bots thus protecting your site, they rarely
make life easier for your actual users.&lt;/p&gt;

&lt;p&gt;Additional reading&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://petewilliams.info/blog/2009/02/why-captcha-sucks-and-what-to-do-about-it/&quot;&gt;Why CAPTCHA sucks and what to do about
it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://davids.utrymme.net/2009/08/superenkelt-spamskydd-for-ruby-on-rails.html&quot;&gt;David Svenssons original
post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://gist.github.com/167152&quot;&gt;Related GIST&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>How to Become an Efficient Programmer</title><link>http://arnklint.com/become-efficient-programmer</link><comments>http://arnklint.com/become-efficient-programmer#disqus_thread</comments><pubDate>Wed, 12 Aug 2009 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/become-efficient-programmer</guid><description>&lt;p&gt;Good programmers usually have one thing in common. They work
efficiently. These are my own rules on how to get better and foremost
more efficient when it comes to programming stuff. Whether you do C#,
Ruby or even &lt;a href=&quot;http://lolcode.com/&quot;&gt;LOLCode&lt;/a&gt;, these rules apply to all of them. Sure, you can be
a master of Zen in one or two languages, but that doesn't mean that you
are an efficient and good programmer overall. Do give me feedback if you
know something this post lacks!&lt;/p&gt;

&lt;h2&gt;Automate the stuff you are able to automate&lt;/h2&gt;

&lt;p&gt;When it comes to stuff you do daily on your computer or programming
device (I know people that hack on their cellphone), you should always
try to automate that stuff as much as you can. Try to find tasks that
can be automated and automate them. It could be file transfers or
creation of a base template application.&lt;/p&gt;

&lt;p&gt;Depending on the project you are working on tests are great to automate
when possible. As for Ruby, Autotest/Zentetest is a great tool for
automating tests.&lt;/p&gt;

&lt;h2&gt;Learn the shortcuts&lt;/h2&gt;

&lt;p&gt;I'm not only talking about keyboard shortcuts or the ones you can click
on to get to a different location in your file structure. Try to always
be on your watch when programming or even just using the OS for smart
and fast ways to get from A to B. Especially tasks that you repeat often
will save you a lot of time in the long run.&lt;/p&gt;

&lt;h2&gt;Use Version Control&lt;/h2&gt;

&lt;p&gt;Keep your projects in a Source Version Control.
&lt;a href=&quot;http://git-scm.com/&quot;&gt;Git&lt;/a&gt; is a great tool to
do that. Whenever you make a change, you can commit it to your
repository and later on switch back to a commit you did earlier if
something goes wrong. Keep your changes small and describe them well, so
that you easily can look back in history when you are in need for that.
Too small changes though makes you inefficient and finding a balance
might take a while.&lt;/p&gt;

&lt;h2&gt;Do Instead of Talk&lt;/h2&gt;

&lt;p&gt;A golden rule that I used to ignore. The worst thing that can happen if
you start doing stuff before planning is that you fail. Then you get to
do it all over again. And what comes with that? That's right,
experience. Try to get feedback more often while developing a feature
instead of planning how it will look like when its done. Chances are
that you will fail along the way anyway and have to go back to the
planning stage. The best solutions are usually those, which are tested
and tried out by users who will use them.&lt;/p&gt;

&lt;h2&gt;Keep a Library&lt;/h2&gt;

&lt;p&gt;While Google is a great code library, there are some snippets of code
you will never find there. Keep a personal code library of stuff you
have done. This way, you will always be able to go back and fetch code
from a project later on to reuse in the next one. This saves you time
and makes your life as a programmer easier.&lt;/p&gt;

&lt;h2&gt;Focus&lt;/h2&gt;

&lt;p&gt;Get rid of the noise that's bothering you. You might not even notice,
but your IM, cellphone and e-mail client doesn't always deserve the
amount of attention that you are giving them.&lt;/p&gt;

&lt;p&gt;A couple of years ago during a super hectic time at work/school, I did
them both at the same time, I simply closed down my e-mail client only
launched it three times a day. One time in the morning, one before lunch
and one half an hour before i finished work. This has kept me from
focusing on my customers problems or requests all day long. Remember,
you are not saying no to your customers/colleagues, you are simply
putting them on hold for you to be totally focused on them later on.&lt;/p&gt;

&lt;p&gt;IM and texts are a great tool of communication. Thats a fact. But not at
all times! Interruptions are usually a bad thing when you are
programming. Think about it!&lt;/p&gt;

&lt;p&gt;This is really a subject of &lt;a href=&quot;/saying-no&quot;&gt;saying no&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I know there are great tools that can help you follow these rules and I
would really appreciate some feedback about just those.&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Custom jQuery selectors</title><link>http://arnklint.com/custom-jquery-selectors</link><comments>http://arnklint.com/custom-jquery-selectors#disqus_thread</comments><pubDate>Fri, 23 Nov 2007 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/custom-jquery-selectors</guid><description>&lt;p&gt;I find that a lot of times you want to use jQuery selectors that are a
bit messy on a couple of places. Making your own selectors tidies your
code and makes it
&lt;a href=&quot;http://en.wikipedia.org/wiki/Don't_repeat_yourself&quot;&gt;DRY&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;DRY up your JavaScript code using your own custom selectors&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://jquery.com&quot;&gt;jQuery&lt;/a&gt; is starting to be really enjoyable. This is an easy peasy way to 
make your own custom selector, which could be used to extract elements
in a cleaner way. This also allows you to find any type of element based
on one or more attributes which you couldn't use the included selectors
to find.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$.expr[':'].my_elements = function(obj){
  var $this = $(obj);
  return ($this.attr('special_attribute') != '');
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then you can use your homebrewed selector the same way you would use the pre
defined:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$('h1:my_elements').css({color: &quot;green&quot;});
&lt;/code&gt;&lt;/pre&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Deploy your Jekyll Site Directly from TextMate</title><link>http://arnklint.com/deploy-jekyll-with-textmate</link><comments>http://arnklint.com/deploy-jekyll-with-textmate#disqus_thread</comments><pubDate>Thu, 01 Nov 2007 15:14:14 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/deploy-jekyll-with-textmate</guid><description>&lt;p&gt;&lt;a href=&quot;http://github.com/mojombo/jekyll/tree/master&quot;&gt;Jekyll&lt;/a&gt; is the &quot;engine for static blogs&quot; that I'm using here when
blogging. You simply write your posts in any text editor (preferably
TextMate if you are on a Mac) and then process the blog posts that are
written in Markdown or Textile formats via the Liquid Templating
Language.&lt;/p&gt;

&lt;h2&gt;Automate&lt;/h2&gt;

&lt;p&gt;Before this post, there were no clean way to deploy your precompiled
Jekyll site to a remote server. So I made a Textmate command allowing
you to compile your jekyll site before you deploy it via rsync to your
server. It's a super simple, yet neat way to use Textmate for deploying
your site.&lt;/p&gt;

&lt;p&gt;Simply follow the instructions in the README in the Github repo to
install the command and deploy script.&lt;/p&gt;

&lt;p&gt;The Textmate command simply launches a shell script in your ./_tasks
directory called up:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash
jekyll ../ ../_site --pygments &amp;amp;&amp;amp; 
rsync -avz --delete ../_site/ user@server:/path/to/webroot
&lt;/code&gt;&lt;/pre&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item><item><title>Your own API based on Ruby on Rails</title><link>http://arnklint.com/rails-rest-api</link><comments>http://arnklint.com/rails-rest-api#disqus_thread</comments><pubDate>Mon, 11 Jun 2007 00:00:00 +0000</pubDate><guid isPermaLink="true">http://arnklint.com/rails-rest-api</guid><description>&lt;p&gt;Making your own REST(ful) API based on Ruby on Rails is not that hard.
There are plenty of libraries that makes it a bit easier, but as you
probably know, dependencies are not always a good thing for
maintainability.&lt;/p&gt;

&lt;h2&gt;Why an API?&lt;/h2&gt;

&lt;p&gt;A great way to open up your application is to enable your users to write
their own applications interacting with your web app. While opening up, the
users are likely to produce more traffic and more buzz if there is a
simple way to integrate your app with theirs.&lt;/p&gt;

&lt;h2&gt;Planning an API&lt;/h2&gt;

&lt;p&gt;I've been producing a couple of API's lately and the one and only rule I
can think of in general is to start small and add to it. Be responsible
when writing the API and try to plan ahead so that you wont have to
remove parts of it in the future, which might cause other apps dependent
upon your API to fail. Another option is to make versions of the api, so
that new changes wont affect apps that consume your API. Consider
different endpoints for different versions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://myapp.com/api/v1/comments.json
http://myapp.com/api/v2/comments.json
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;How it's done in Rails&lt;/h2&gt;

&lt;p&gt;Create an &quot;API base controller&quot; that will be inherited from the rest of
your API controllers (namespace them or whatever).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# app/controllers/api_controller.rb
class ApiController &amp;lt; ActionController::Base
  attr_accessor :current_user
  prepend_around_filter ApiAuthorizedFilter.new
end

# app/models/api_authorized_filter.rb

class ApiAuthorizedFilter
  def before(controller)
    return true unless controller.params[:api_key]
    controller.current_user =
User.find_by_api_key(controller.params[:api_key])
  end

  def after(controller)
    controller.current_user = nil
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This way, we can control authorization with an API key. Additional
parameters can of course be taken into consideration when autorizing the
user.&lt;/p&gt;

&lt;p&gt;Now you can use the 'api_controller.rb' when implementing the api and
make each new controller inherit from it like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# app/controllers/comments_controller.rb
class CommentsController &amp;lt; ApiController 
  def index
    Comment.find(:all)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You´ve just accomplished a super easy filter to authenticate/authorize a
user via your own Ruby on Rails based API!&lt;/p&gt;</description><author>jonas.a@revrise.com (Jonas Arnklint)</author></item></channel></rss>