<?xml version="1.0" encoding="UTF-8"?>
<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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Earthman&#039;s Blog</title>
	<atom:link href="http://earthman.ca/feed/" rel="self" type="application/rss+xml" />
	<link>http://earthman.ca</link>
	<description>Website Consultant, Wordpress Web Designer, 80&#039;s DJ, Existentialist, and more...</description>
	<lastBuildDate>Mon, 06 Feb 2012 05:08:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>JavaScript Testing From Scratch: New on Premium</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/r5rmgQFQnpY/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/r5rmgQFQnpY/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 20:30:53 +0000</pubDate>
		<dc:creator>Andrew Burgess</dc:creator>
				<category><![CDATA[JavaScript & AJAX]]></category>
		<category><![CDATA[Premium]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Videos]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23927</guid>
		<description><![CDATA[This likely isn&#8217;t the first tutorial on testing that you&#8217;ve ever seen. But perhaps you&#8217;ve had your doubts about testing, and never took the time to read them. After all, it can seem like extra work for no reason.


This tutorial (with...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/7w5Qjr3-r7Q/' rel='bookmark' title='Permanent Link: Next Generation JavaScript with AMD and RequireJS: New on Premium'>Next Generation JavaScript with AMD and RequireJS: New on Premium</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/kpFMd_-2RFo/' rel='bookmark' title='Permanent Link: Testing Your JavaScript with Jasmine'>Testing Your JavaScript with Jasmine</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/pR1GqIKuuHA/' rel='bookmark' title='Permanent Link: Digging into Dojo: Premium Video Series'>Digging into Dojo: Premium Video Series</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23927&c=202765907' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23927&c=202765907' border='0' alt='' /></a><p>This likely isn&#8217;t the first tutorial on testing that you&#8217;ve ever seen. But perhaps you&#8217;ve had your doubts about testing, and never took the time to read them. After all, it can seem like extra work for no reason.
</p>
<p>
This tutorial (with screencasts) intends to change your views. We&#8217;re going to start at the very beginning: what is testing and why should you do it? Then, we&#8217;ll talk briefly about writing testable code, before actually, you know, doing some testing! Let&#8217;s get to it.</p>
<p><a href="http://net.tutsplus.com/about/join-plus/" >Become a Premium member</a> to read this tutorial/screencast, as well as hundreds of other advanced tutorials and screencasts from the Tuts+ network.</p>
<p><span id="more-23927"></span></p>
<hr />
<h2>Tuts+ Premium</h2>
<p><a style="float: right; margin-left: 20px;" href="http://tutsplus.com/take-the-tour/"><img src="http://tutsplus.s3.amazonaws.com/banners/250x250.jpg"></a>The recently re-launched <a href="http://tutsplus.com">Tuts+ Premium</a> is a service that provides top-tier training in a variety of creative fields. Whether you prefer <a href="http://tutsplus.com/ebook/getting-good-with-javascript-2/">books</a>, <a href="http://tutsplus.com/course/wordpress-plugin-development-essentials/">visual training</a>, or <a href="http://tutsplus.com/tutorial/a-guide-to-custom-theming-jquery-ui-widgets/">in depth tutorials</a>, we have you covered. While we unfortunately can&#8217;t afford to provide the service for free, it&#8217;s only $19 a month &#8211; less than you&#8217;d spend on dinner. </p>
<p>I hope you&#8217;ll consider <a href="http://tutsplus.com">checking it out</a>! In addition to learning a huge variety of new skills, it&#8217;s also a fantastic way to say thank you to Nettuts+. </p>
<p><a href="http://feedads.g.doubleclick.net/~a/Zm1rMoGleu06USjdyTW6e6TWbIk/0/da"><img src="http://feedads.g.doubleclick.net/~a/Zm1rMoGleu06USjdyTW6e6TWbIk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Zm1rMoGleu06USjdyTW6e6TWbIk/1/da"><img src="http://feedads.g.doubleclick.net/~a/Zm1rMoGleu06USjdyTW6e6TWbIk/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=r5rmgQFQnpY:7NrnBfJ9w-Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=r5rmgQFQnpY:7NrnBfJ9w-Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=r5rmgQFQnpY:7NrnBfJ9w-Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=r5rmgQFQnpY:7NrnBfJ9w-Y:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=r5rmgQFQnpY:7NrnBfJ9w-Y:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=r5rmgQFQnpY:7NrnBfJ9w-Y:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=r5rmgQFQnpY:7NrnBfJ9w-Y:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=r5rmgQFQnpY:7NrnBfJ9w-Y:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/r5rmgQFQnpY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/javascript-testing-from-scratch-new-on-premium/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Best of Tuts+ in January 2012</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/JtBVW0IlEaE/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/JtBVW0IlEaE/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 15:37:09 +0000</pubDate>
		<dc:creator>David Appleyard</dc:creator>
				<category><![CDATA[bestof]]></category>
		<category><![CDATA[monthlypicks]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23918</guid>
		<description><![CDATA[Each month, we bring together a selection of the best tutorials and articles from across the whole Tuts+ network. Whether you&#8217;d like to read the top posts from your favourite site, or would like to start learning something completely new, this is...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/' rel='bookmark' title='Permanent Link: Recently in Web Development (January ’12 Edition)'>Recently in Web Development (January ’12 Edition)</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/' rel='bookmark' title='Permanent Link: Recently in Web Development (January ’12 Edition)'>Recently in Web Development (January ’12 Edition)</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/-w3KCw1sVbc/' rel='bookmark' title='Permanent Link: Best of Tuts+ in August'>Best of Tuts+ in August</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23918&c=1655942008' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23918&c=1655942008' border='0' alt='' /></a><p>Each month, we bring together a selection of the best tutorials and articles from across the whole <a href="http://tutsplus.com/">Tuts+ network</a>. Whether you&#8217;d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start!</p>
<p><span id="more-23918"></span></p>
<hr />
<h2>Psdtuts+ — Photoshop Tutorials</h2>
<ul class="webroundup">
<li class='clear'>
<div>
			<img src="http://d2f8dzk2mhcqts.cloudfront.net/0808_Truck/preview.jpg" alt="Create a Pimped Out Truck Using Photoshop and Point and Shoot Photos" width="200" height="200" />
		</div>
<h4><a href='http://psd.tutsplus.com/tutorials/photo-effects-tutorials/pimped-out-truck/'>Create a Pimped Out Truck Using Photoshop and Point and Shoot Photos</a></h4>
<p>Making modifications to your car or truck in Photoshop can be a lot of fun. In this tutorial we will demonstrate how to create a pimped out truck modification using photos taken with a simple point and shoot camera, with no advanced lighting setup. Let&#8217;s get started!</p>
<p><a href='http://psd.tutsplus.com/tutorials/photo-effects-tutorials/pimped-out-truck/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
			<img src="http://d2f8dzk2mhcqts.cloudfront.net/0806_Elephant/preview.jpg" alt="Create an Elephant Sundae Using Photo Manipulation Techniques" width="200" height="200" />
		</div>
<h4><a href='http://psd.tutsplus.com/tutorials/photo-effects-tutorials/elephant-sundae/'>Create an Elephant Sundae Using Photo Manipulation Techniques</a></h4>
<p>Photoshop is great at seamlessly combing photos to create an entirely new scene. In this tutorial we will create an elephant sundae using several stock photos. Let&#8217;s get started!</p>
<p><a href='http://psd.tutsplus.com/tutorials/photo-effects-tutorials/elephant-sundae/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
			<img src="http://d2f8dzk2mhcqts.cloudfront.net/0818_Michaelo/preview.jpg" alt="The Incredible Digital Art of Michael Oswald" width="200" height="200" />
		</div>
<h4><a href='http://psd.tutsplus.com/articles/inspiration/michael-oswald/'>The Incredible Digital Art of Michael Oswald</a></h4>
<p>In this article we will be featuring the work of <a href="http://www.bymichaelo.com/" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','www.bymichaelo.com']);">Michael Oswald</a>. Oswald is a digital artist with a unique style. His technique involves a combination of photo manipulation and digital painting techniques and the results are often stunning. Let&#8217;s take a look!</p>
<p><a href='http://psd.tutsplus.com/articles/inspiration/michael-oswald/'>Visit Article</a></p>
</li>
<hr />
<h2>Nettuts+ — Web Development Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://d2o0t5hpnwv4c1.cloudfront.net/1038_sublime/sublime-text-2-tips-and-tricks.jpg" alt="Sublime Text 2 Tips and Tricks (Updated)" width="200" height="200" />
	</div>
<h4><a href='http://net.tutsplus.com/tutorials/tools-and-tips/sublime-text-2-tips-and-tricks/'>Sublime Text 2 Tips and Tricks (Updated)</a></h4>
<p><a href="http://www.sublimetext.com/dev" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','www.sublimetext.com']);">Sublime Text 2</a> is one of the fastest and most incredible code editors to be released in a long time! With a community and plugin ecosystem as passionate as this one, it just might be impossible for any other editor to catch up. I&#8217;ll show you my favorite tips and tricks today. </p>
<p><a href='http://net.tutsplus.com/tutorials/tools-and-tips/sublime-text-2-tips-and-tricks/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d2o0t5hpnwv4c1.cloudfront.net/1119_html5/html5-media-and-accessibility.jpg" alt="An In Depth Analysis of HTML5 Multimedia and Accessibility" width="200" height="200" />
	</div>
<h4><a href='http://net.tutsplus.com/tutorials/html-css-techniques/an-in-depth-overview-of-html5-multimedia-and-accessibility/'>An In Depth Analysis of HTML5 Multimedia and Accessibility</a></h4>
<p>In this tutorial, youll learn how HTML5 helps to provide you with several ways of presenting your media content to users. As a result, youll increase the availability of your media to users with different<br />
needs and requirements, making it more accessible.</p>
<p><a href='http://net.tutsplus.com/tutorials/html-css-techniques/an-in-depth-overview-of-html5-multimedia-and-accessibility/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d2o0t5hpnwv4c1.cloudfront.net/1129_api_wrapper_tdd/api-wrapper-for-dribbble.png" alt="Writing an API Wrapper in Ruby with TDD" width="200" height="200" />
	</div>
<h4><a href='http://net.tutsplus.com/tutorials/ruby/writing-an-api-wrapper-in-ruby-with-tdd/'>Writing an API Wrapper in Ruby with TDD</a></h4>
<p>Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the API itself. This process is slow and inefficient, as we can experience network issues and data inconsistencies (the API results may change). Let&#8217;s review how we can avoid all of this effort with Ruby.</p>
<p><a href='http://net.tutsplus.com/tutorials/ruby/writing-an-api-wrapper-in-ruby-with-tdd/'>Visit Article</a></p>
</li>
<hr />
<h2>Vectortuts+ — Illustrator Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://dsmy2muqb7t4m.cloudfront.net/tuts/000-2012/477-microscope/preview.jpg" alt="How to Illustrate a Microscope in Illustrator" width="200" height="200" />
	</div>
<h4><a href='http://vector.tutsplus.com/tutorials/illustration/illustrate-a-microscope/'>How to Illustrate a Microscope in Illustrator</a></h4>
<p>The microscopes is a symbol of our civilization. Throughout this tutorial on how to illustrate a vector microscope you&#8217;ll take advantage of numerous Illustrator tools. You will learn how to use blends, art brushes and 3D rendering in Adobe Illustrator. Let&#8217;s get started!</p>
<p><a href='http://vector.tutsplus.com/tutorials/illustration/illustrate-a-microscope/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://dsmy2muqb7t4m.cloudfront.net/tuts/000-2012/471-gallery/preview.jpg" alt="Create a Picture Gallery in Illustrator" width="200" height="200" />
	</div>
<h4><a href='http://vector.tutsplus.com/tutorials/illustration/create-a-picture-gallery/'>Create a Picture Gallery in Illustrator</a></h4>
<p>This work is a common project created together with <a href="http://vector.tutsplus.com/author/iaroslav-lazunov/" >Iaroslav Lazunov</a> and <a href="http://vector.tutsplus.com/author/alexander-egupov/" >Alexander Egupov</a>. We have used 3D rendering, Blends, Opacity masks, making this three-dimensional stage with vanishing points. Learn every step in how to create this picture gallery work.</p>
<p><a href='http://vector.tutsplus.com/tutorials/illustration/create-a-picture-gallery/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://dsmy2muqb7t4m.cloudfront.net/articles/2012/article-tutorials-typeface-font-design/preview.jpg" alt="13 Important Resources for Learning How to Design Typefaces and Full Fonts" width="200" height="200" />
	</div>
<h4><a href='http://vector.tutsplus.com/articles/web-roundups/how-to-design-typefaces-fonts/'>Important Resources for Learning How to Design Typefaces and Full Fonts</a></h4>
<p>If you&#8217;re serious about creating a typeface design, then you&#8217;ll need some solid resources to get started. Learn effective typeface design workflows, how to take an initial spark of an idea from sketch, through Illustrator, into Fontlab, and then work your creation into a complete and custom font design. Here are multiple tutorials that show you how to create fonts in Illustrator and Fontlab, and you can also dive into articles that describe the foundation of quality type design with ample inspirational examples.</p>
<p><a href='http://vector.tutsplus.com/articles/web-roundups/how-to-design-typefaces-fonts/'>Visit Article</a></p>
</li>
<hr />
<h2>Webdesigntuts+ — Web Design Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://d3pr5r64n04s3o.cloudfront.net/articles/062_pairing_fonts/preview.png" alt="A Beginner&#8217;s Guide to Pairing Fonts" width="200" height="200" />
	</div>
<h4><a href='http://webdesign.tutsplus.com/articles/typography-articles/a-beginners-guide-to-pairing-fonts/'>A Beginner&#8217;s Guide to Pairing Fonts</a></h4>
<p>Pairing fonts can be a challenge. Selecting two or more fonts which work well is one thing &#8211; selecting two which work <em>together</em> to achieve your typographic aims may have you reaching for the aspirin. Let&#8217;s see if we can alleviate any headaches. This guide will help you get started with font pairing for the web.</p>
<p><a href='http://webdesign.tutsplus.com/articles/typography-articles/a-beginners-guide-to-pairing-fonts/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d3pr5r64n04s3o.cloudfront.net/tuts/235_banner_ads/preview.png" alt="Design a Series of Smart Banner Ads in Photoshop" width="200" height="200" />
	</div>
<h4><a href='http://webdesign.tutsplus.com/tutorials/visuals/design-a-series-of-smart-banner-ads-in-photoshop/'>Design a Series of Smart Banner Ads in Photoshop</a></h4>
<p>With the continuous growth of the Internet, online marketing has gotten bigger every year, and along with it, the advertising industry. One major factor in all this craziness is buying and selling ads. </p>
<p><a href='http://webdesign.tutsplus.com/tutorials/visuals/design-a-series-of-smart-banner-ads-in-photoshop/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="https://d3pr5r64n04s3o.cloudfront.net/tuts/231_twitter_bootstrap_101/bootstrap.png" alt="Twitter Bootstrap 101: Introduction" width="200" height="200" />
	</div>
<h4><a href='http://webdesign.tutsplus.com/tutorials/complete-websites/twitter-bootstrap-101-introduction/'>Twitter Bootstrap 101: Introduction</a></h4>
<p>Twitter&#8217;s Bootstrap is an excellent set of carefully crafted user interface elements, layouts, and javascript tools, freely available to use in your next web design project. This video series aims to introduce you to Bootstrap; taking you all the way from downloading the resources, to building a complete Bootstrap-based website.</p>
<p><a href='http://webdesign.tutsplus.com/tutorials/complete-websites/twitter-bootstrap-101-introduction/'>Visit Article</a></p>
</li>
<hr />
<h2>Phototuts+ — Photography Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://d2f29brjr0xbt3.cloudfront.net/805_hdrtakeleave/preview.jpg" alt="HDR: Love it or Leave It?" width="200" height="200" />
	</div>
<h4><a href='http://photo.tutsplus.com/articles/post-processing-articles/hdr-love-it-or-leave-it/'>HDR: Love it or Leave It?</a></h4>
<p>There are few techniques in the photography world that divide our community as much as HDR. High dynamic range images, or HDR images, are a special type of composite image that combines several images at different exposure settings in order to create an image with increased dynamic range. The look provided by HDR is loved by many, and disliked by perhaps just as many. In today&#8217;s article, we&#8217;re going to take a better look at what HDR is, and get some opinions from photographers using HDR.<span id="more-8505"></span></p>
<p><a href='http://photo.tutsplus.com/articles/post-processing-articles/hdr-love-it-or-leave-it/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d2f29brjr0xbt3.cloudfront.net/807_motorsportRU/preview.jpg" alt="50 Inspiring Images of Cars and Motorcycles" width="200" height="200" />
	</div>
<h4><a href='http://photo.tutsplus.com/articles/inspiration/50-inspiring-images-of-cars-and-motorcycles/'>Inspiring Images of Cars and Motorcycles</a></h4>
<p>Cars and motorbikes have been around for 100 years. Throughout the century, they have looked beautiful, satisfied our need for speed and become a symbol for thrill seeking. Today, we&#8217;ll look at photos ranging from brand new Ferrari&#8217;s to classic muscle cars.<span id="more-8519"></span></p>
<p><a href='http://photo.tutsplus.com/articles/inspiration/50-inspiring-images-of-cars-and-motorcycles/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d2f29brjr0xbt3.cloudfront.net/822_gimpQT/preview.jpg" alt="Quick Tip: GIMP Portable &#8211; Take Your Editing Software With You" width="200" height="200" />
	</div>
<h4><a href='http://photo.tutsplus.com/articles/post-processing-articles/quick-tip-gimp-portable-take-your-editing-software-with-you/'>Quick Tip: GIMP Portable &#8211; Take Your Editing Software With You</a></h4>
<p>While a number of smartphones now offer photo editing basics (and a plethora of apps to expand things even more), the portability of a solid photo editing program has been hard to come by. Photoshop is a monster in regards to space requirements and its ability to work on any system where it is not expressively installed. Picasa can be fairly &#8216;lightweight&#8217; but lacks many of the more advanced photo editing tools. So what about GIMP?<span id="more-8627"></span></p>
<p><a href='http://photo.tutsplus.com/articles/post-processing-articles/quick-tip-gimp-portable-take-your-editing-software-with-you/'>Visit Article</a></p>
</li>
<hr />
<h2>Cgtuts+ — Computer Graphics Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://d2d04grx5ahzvh.cloudfront.net/336_Blender_TRex_Modeling/Thumb.png" alt="Modeling, UVmapping And Texturing A Low Poly T-Rex In Blender, Part 1" width="200" height="200" />
	</div>
<h4><a href='http://cg.tutsplus.com/tutorials/blender/modeling-uvmapping-and-texturing-a-low-poly-t-rex-in-blender-part-1/'>Modeling, UVmapping And Texturing A Low Poly T-Rex In Blender, Part 1</a></h4>
<p>In the first tutorial of 2012 you’ll learn how to create an awesome low-poly dinosaur using Blender and Gimp. In today’s post artist Karan Shah will walk you through the entire modeling process step by step, and show you how to create an optimized model suitable for use in any game engine.</p>
<p><a href='http://cg.tutsplus.com/tutorials/blender/modeling-uvmapping-and-texturing-a-low-poly-t-rex-in-blender-part-1/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d2d04grx5ahzvh.cloudfront.net/337_Maya_Fluids_Explosion/Thumb.jpg" alt="Create A Realistic Explosion In Maya Using Maya Fluids" width="200" height="200" />
	</div>
<h4><a href='http://cg.tutsplus.com/tutorials/autodesk-maya/create-a-realistic-explosion-in-maya-using-maya-fluids/'>Create A Realistic Explosion In Maya Using Maya Fluids</a></h4>
<p>Today you’ll learn to animate and shade fluids, understand all of the major attributes, learn how adding fields will allow you to gain better control over your simulation, and how to light and render the final animation.</p>
<p><a href='http://cg.tutsplus.com/tutorials/autodesk-maya/create-a-realistic-explosion-in-maya-using-maya-fluids/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d2d04grx5ahzvh.cloudfront.net/339_UDK_Speedtree_Part_1/Thumb.jpg" alt="SpeedTree To UDK: The Complete Workflow, Part 1 Creating The Tree" width="200" height="200" />
	</div>
<h4><a href='http://cg.tutsplus.com/tutorials/game-dev/speedtree-to-udk-the-complete-workflow-part-1/'>SpeedTree To UDK: The Complete Workflow, Part 1 Creating The Tree</a></h4>
<p>Due to the shear number of polygons often required to make believable 3D trees, creating realistic ones for use &#8220;in-game&#8221; can be a challenging, time consuming task. SpeedTree from IDV aims to change all that with it&#8217;s intuitive UI, ease of use and powerful toolset. Making believable trees and plants has literally never been easier!</p>
<p><a href='http://cg.tutsplus.com/tutorials/game-dev/speedtree-to-udk-the-complete-workflow-part-1/'>Visit Article</a></p>
</li>
<hr />
<h2>Aetuts+ — After Effects Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://d3gphd0pfuxn95.cloudfront.net/694_dominoes/dominoes_thumbnail.jpg" alt="&#8220;Dominoes&#8221; CameraTracker and Cinema 4d Case Study &#8211; Day 1" width="200" height="200" />
	</div>
<h4><a href='http://ae.tutsplus.com/tutorials/workflow/dominoes-cameratracker-and-cinema-4d-case-study-day-1/'>Dominoes&#8221; CameraTracker and Cinema 4d Case Study &#8211; Day 1</a></h4>
<p>In this tutorial we&#8217;re going to go over the principle functionality of <a href="http://www.thefoundry.co.uk/products/cameratracker/" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','www.thefoundry.co.uk']);">CameraTracker</a> from The Foundry, learning basic workflow, optimizing results, aligning the ground plane and exporting this data from After Effects to <a href="http://www.maxon.net/" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','www.maxon.net']);" rel="external">Cinema 4d</a>.<span id="more-18522"></span></p>
<p><a href='http://ae.tutsplus.com/tutorials/workflow/dominoes-cameratracker-and-cinema-4d-case-study-day-1/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://tutsplus.s3.amazonaws.com/tutspremium/after-effects/59_flame_react/Flame_Reactant_Thumbnail.jpg" alt="Make An Amazing Motion Reactant Flame &#8211; Tuts+ Premium" width="200" height="200" />
	</div>
<h4><a href='http://ae.tutsplus.com/tutorials/vfx/make-an-amazing-motion-reactant-flame-tutsplus-premium/'>Make An Amazing Motion Reactant Flame &#8211; Tuts+ Premium</a></h4>
<p>Using just a few video elements of torch flames, we composite a burning hand by using a series of null objects and expressions to drive a <strong>time lagged displacement effect</strong> to simulate fire burning from a moving source. We use the Puppet tool for the distortion and throw on some tracked lighting effects and a displacement map for the Heat. This principle can be used to <strong>add realistic, fluid motion to any tracked object</strong>.</p>
<p><a href='http://ae.tutsplus.com/tutorials/vfx/make-an-amazing-motion-reactant-flame-tutsplus-premium/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d3gphd0pfuxn95.cloudfront.net/misc/freelancer.jpg" alt="10 Key Tips To Becoming A Successful Video Freelancer" width="200" height="200" />
	</div>
<h4><a href='http://ae.tutsplus.com/articles/in-depth/10-key-tips-to-becoming-a-successful-video-freelancer/'>Key Tips To Becoming A Successful Video Freelancer</a></h4>
<p>Youve watched thousands of tutorials. Youve put in countless hours and spent many late nights working on personal projects. Youve finally come to the conclusion that this may just be something you would like to do for a career. It can seem a little intimidating at first, because how are you going to convince someone to pay you to do this? Up until now youve been your only client. How do you get more?  Im going to share my insight and experiences on how to successfully launch your freelance career this year!</p>
<p><a href='http://ae.tutsplus.com/articles/in-depth/10-key-tips-to-becoming-a-successful-video-freelancer/'>Visit Article</a></p>
</li>
<hr />
<h2>Audiotuts+ — Audio &#038; Production Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://d3vvl31cy8gagb.cloudfront.net/713_8free/Preview%20Image.jpg" alt="8 Free Professional Quality Audio Unit Plug-ins for Mac" width="200" height="200" />
	</div>
<h4><a href='http://audio.tutsplus.com/articles/general/8-free-professional-quality-audio-unit-plug-ins-for-mac/'>Free Professional Quality Audio Unit Plug-ins for Mac</a></h4>
<p>Lets face it, software is expensive. While there are hundreds of free plug-ins available online, more often than not two problems will arise: One, most of them are for PCs leaving us Mac users feeling left out. Two, most of them are vary poor quality.</p>
<p>While I do agree with the saying, &#8220;The tools are only as good as the artist,&#8221; I also believe the opposite is true; that at some point the artist can only be as good as his tools are.</p>
<p><a href='http://audio.tutsplus.com/articles/general/8-free-professional-quality-audio-unit-plug-ins-for-mac/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d3vvl31cy8gagb.cloudfront.net/qt_168_drums4/Thumbnail.jpg" alt="Quick Tip: Drum Processing Part 4: Tips and Tricks" width="200" height="200" />
	</div>
<h4><a href='http://audio.tutsplus.com/tutorials/production/quick-tip-drum-processing-part-4-tips-and-tricks/'>Quick Tip: Drum Processing Part 4: Tips and Tricks</a></h4>
<p>This short series of quick tips is designed to give you a good overview of the audio processing techniques involved in creating a professional sounding drum beat for use in house, electro and breaks in Cubase. In this final part we will look at a few ways to add even more life to your drums.<br />
<span id="more-13319"></span><br />
Here is a sample of the type of beat you could expect to end up with at the end of this series of tips:</p>
<p><a href='http://audio.tutsplus.com/tutorials/production/quick-tip-drum-processing-part-4-tips-and-tricks/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d3vvl31cy8gagb.cloudfront.net/qt_164_math/preview.jpg" alt="Quick Tip: Use the Doubling Technique for Quick Drums" width="200" height="200" />
	</div>
<h4><a href='http://audio.tutsplus.com/tutorials/production/quick-tip-use-the-doubling-technique-for-quick-drums/'>Quick Tip: Use the Doubling Technique for Quick Drums</a></h4>
<p>It&#8217;s 3:30 in the afternoon when your phone rings. The head of a music library is calling and she needs your help. They have a commercial for an A-list client that needs music, and they want you to submit an entry. You&#8217;ll get $10,000 if you land the gig.</p>
<p><a href='http://audio.tutsplus.com/tutorials/production/quick-tip-use-the-doubling-technique-for-quick-drums/'>Visit Article</a></p>
</li>
<hr />
<h2>Activetuts+ — Flash, Flex &#038; ActionScript Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/394_microphoneGameCode/preview.jpg" alt="Create a Microphone-Controlled Flash Game: Code" width="200" height="200" />
	</div>
<h4><a href='http://active.tutsplus.com/tutorials/games/create-a-microphone-controlled-flash-game-code/'>Create a Microphone-Controlled Flash Game: Code</a></h4>
<p>In this mini-series, we&#8217;re creating a spaceship game where the main control is via the microphone: shout louder to make the ship fly higher. <a href="http://active.tutsplus.com/tutorials/games/create-a-microphone-controlled-flash-game-design/" >So far</a>, we&#8217;ve created all the required graphical elements for the game. Now, it&#8217;s time to work on our code. We&#8217;ve got a lot to do, so let&#8217;s get started!<span id="more-10562"></span></p>
<p><a href='http://active.tutsplus.com/tutorials/games/create-a-microphone-controlled-flash-game-code/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d2fhka9tf2vaj2.cloudfront.net/articles/084_whyBotherWithjQuery/why_bother_with_jquery.png" alt="Why Bother With jQuery? A Guide for (Former) Flash Developers" width="200" height="200" />
	</div>
<h4><a href='http://active.tutsplus.com/articles/explanatory/why-bother-with-jquery-a-guide-for-former-flash-developers/'>Why Bother With jQuery? A Guide for (Former) Flash Developers</a></h4>
<p>If you, like many Flash developers, are looking into using HTML5 for your web apps, you&#8217;ll almost certainly have come across jQuery. It&#8217;s a very popular JavaScript library, used by <a href="http://trends.builtwith.com/javascript/JQuery" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','trends.builtwith.com']);" rel="external">a large percentage</a> of the most visited websites &#8211; but what&#8217;s all the fuss about, and should you use it?<span id="more-10723"></span></p>
<p><a href='http://active.tutsplus.com/articles/explanatory/why-bother-with-jquery-a-guide-for-former-flash-developers/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/398_gamepadAPIIntro/gamepadAPI-preview.jpg" alt="An Introduction to the HTML5 Gamepad API" width="200" height="200" />
	</div>
<h4><a href='http://active.tutsplus.com/tutorials/games/an-introduction-to-the-html5-gamepad-api/'>An Introduction to the HTML5 Gamepad API</a></h4>
<p>As HTML games begin to gradually increase in popularity, vendors are starting to introduce some exciting new APIs to make gaming that little bit sweeter for both us developers and our end players. One of these is the GamepadAPI, which allows you to connect your good old console gamepad into your computer and use it for browser based games, plug and play style. Let&#8217;s dive in!<span id="more-10686"></span></p>
<p><a href='http://active.tutsplus.com/tutorials/games/an-introduction-to-the-html5-gamepad-api/'>Visit Article</a></p>
</li>
<hr />
<h2>Wptuts+ — WordPress Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://wptutsplus.s3.amazonaws.com/159_RiseHTML5/html5.jpg" alt="The Rise of HTML5 in WordPress" width="200" height="200" />
	</div>
<h4><a href='http://wp.tutsplus.com/articles/the-rise-of-html5-in-wordpress/'>The Rise of HTML5 in WordPress</a></h4>
<p>2011 was a big year for the advancement of HTML5 in the web development community. It became pretty widely adopted, especially for the mobile web. There have been major projects that help developers use HTML5, like Paul Irish&#8217;s <a href="http://html5boilerplate.com/" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','html5boilerplate.com']);">HTML5 Boilerplate</a> (technically 2010, but popularized in 2011) and books galore!</p>
<p><a href='http://wp.tutsplus.com/articles/the-rise-of-html5-in-wordpress/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://wptutsplus.s3.amazonaws.com/131_MetaBoxPt1/metabox_0.jpg" alt="Reusable Custom Meta Boxes Part 3: Extra Fields" width="200" height="200" />
	</div>
<h4><a href='http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-3-extra-fields/'>Reusable Custom Meta Boxes Part 3: Extra Fields</a></h4>
<p>In <a href="http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-1-intro-and-basic-fields/" >Part 1</a> and <a href="http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-2-advanced-fields/" >Part 2</a> of our custom meta box template tutorial series, we learned how to create a field array to loop through and create a custom meta box with your standard fields. Now let&#8217;s throw in a bit of JavaScript for some fancy, but highly useful fields.</p>
<p><a href='http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-3-extra-fields/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://wptutsplus.s3.amazonaws.com/167_ySlowTut/img/uwo.png" alt="The Ultimate Quickstart Guide to Speeding Up Your WordPress Site" width="200" height="200" />
	</div>
<h4><a href='http://wp.tutsplus.com/tutorials/the-ultimate-quickstart-guide-to-speeding-up-your-wordpress-site/'>The Ultimate Quickstart Guide to Speeding Up Your WordPress Site</a></h4>
<p>Give your site a boost! Implement crucial optimization techniques that will improve not only your <strong><a href="http://developer.yahoo.com/yslow/" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','developer.yahoo.com']);">ySlow </a></strong>score, but your Google rank too. In this tutorial we will cover all aspects of W3 caching, ySlow, Google page speed, CSS sprites &#038; htaccess rules, to achieve a high ySlow score like i have done on <a href="http://imattic.com/" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','imattic.com']);">my blog.</a></p>
<p><a href='http://wp.tutsplus.com/tutorials/the-ultimate-quickstart-guide-to-speeding-up-your-wordpress-site/'>Visit Article</a></p>
</li>
<hr />
<h2>Mobiletuts+ — Mobile Development Tutorials</h2>
<li class='clear'>
<div>
		<img src="http://d339vfjsz5zott.cloudfront.net/iOS-SDK_Creating-A-Carousel/carousel.jpg" alt="iOS SDK: Creating an Awesome Carousel" width="200" height="200" />
	</div>
<h4><a href='http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-creating-an-awesome-carousel/'>iOS SDK: Creating an Awesome Carousel</a></h4>
<p>Engage your users with stunning carousels.  We&#8217;ll look at how easy and clean it can be to implement scrollable, interactive carousels in your iOS applications.  With high configurability, you can have 3D, flat, rotating, and endless scrolling arrays for data, images, or buttons.<br />
<span id="more-9302"></span></p>
<p><a href='http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-creating-an-awesome-carousel/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d339vfjsz5zott.cloudfront.net/PhoneGap-From-Scratch/phonegap.jpg" alt="PhoneGap From Scratch: Introduction" width="200" height="200" />
	</div>
<h4><a href='http://mobile.tutsplus.com/tutorials/phonegap/phonegap-from-scratch/'>PhoneGap From Scratch: Introduction</a></h4>
<p>Want to learn how to use PhoneGap, but don&#8217;t know where to get started? Join us as we put together &#8220;Sculder&#8221;, not only a tribute to an excellent science fiction TV series, but a fully-fledged native mobile application for the believer in you!</p>
<p><a href='http://mobile.tutsplus.com/tutorials/phonegap/phonegap-from-scratch/'>Visit Article</a></p>
</li>
<li class='clear'>
<div>
		<img src="http://d339vfjsz5zott.cloudfront.net/Mobile-Flash-Is-Far-From-Dead/mobile-flash.png" alt="Mobile Flash is Far From Dead: Setting the Record Straight" width="200" height="200" />
	</div>
<h4><a href='http://mobile.tutsplus.com/?p=9436'>Mobile Flash is Far From Dead: Setting the Record Straight</a></h4>
<p>In light of recent announcements from Adobe, there has been a lot of confusion over the state of the Flash Platform &#8211; specifically in regard to Flash content on mobile devices. This article seeks to clarify many of the misconceptions that exist by addressing the main points of confusion around these announcements regardless of the initial, monumental, and absolutely unbelievable blunders from failed public (and private) relations messaging and general marketing surrounding these announcements.<span id="more-9436"></span></p>
<p><a href='http://mobile.tutsplus.com/?p=9436'>Visit Article</a></p>
</li>
</ul>
<p><a href="http://feedads.g.doubleclick.net/~a/tjYQojFRFOpF7wcRcegljIW3a-M/0/da"><img src="http://feedads.g.doubleclick.net/~a/tjYQojFRFOpF7wcRcegljIW3a-M/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/tjYQojFRFOpF7wcRcegljIW3a-M/1/da"><img src="http://feedads.g.doubleclick.net/~a/tjYQojFRFOpF7wcRcegljIW3a-M/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=JtBVW0IlEaE:CeiJ0V3T4Gg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=JtBVW0IlEaE:CeiJ0V3T4Gg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=JtBVW0IlEaE:CeiJ0V3T4Gg:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/JtBVW0IlEaE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/articles/news/best-of-tuts-in-january-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn jQuery in 30 Days</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/hI3XrFMnqw8/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/hI3XrFMnqw8/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 04:47:14 +0000</pubDate>
		<dc:creator>Jeffrey Way</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23901</guid>
		<description><![CDATA[Sometimes, it&#8217;s easy to become overwhelmed by how much there is to learn in this industry. If jQuery happens to be on your personal &#8220;need to learn soon&#8221; list, then I&#8217;m happy to announce my new course: &#8220;Learn jQuery in 30 D...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/QU03njmI--Y/' rel='bookmark' title='Permanent Link: 30 Days to Learn HTML and CSS: a Free Tuts+ Premium Course'>30 Days to Learn HTML and CSS: a Free Tuts+ Premium Course</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/VbbiRc892FU/' rel='bookmark' title='Permanent Link: Are jQuery Users Fools?'>Are jQuery Users Fools?</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/7WlqzndfiXk/' rel='bookmark' title='Permanent Link: From jQuery to JavaScript: A Reference'>From jQuery to JavaScript: A Reference</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23901&c=1910207228' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23901&c=1910207228' border='0' alt='' /></a><p>Sometimes, it&#8217;s easy to become overwhelmed by how much there is to learn in this industry. If jQuery happens to be on your personal &#8220;need to learn soon&#8221; list, then I&#8217;m happy to announce my new course: <a href="http://learnjquery.tutsplus.com">&#8220;Learn jQuery in 30 Days&#8221;</a>. If you&#8217;ll give me fifteen minutes a day for the next month, I&#8217;ll help you become a jQuery pro &#8211; <strong>and it&#8217;s free!</strong><span id="more-23901"></span></p>
<hr />
<h2> How Does it Work? </h2>
<div class="tutorial_image">
<a href="http://learnjquery.tutsplus.com"><img src="http://tutsplus.s3.amazonaws.com/tutspremium/courses_$folder$/30DaysJquery/images/learnjQuerySite.jpg" alt="Learn jQuery"></a>
</div>
<blockquote class=pullquote>
<p>Sporadically, your skills will be put to the test, when you take the interactive quizzes! </p>
</blockquote>
<p>Once you <a href="http://learnjquery.tutsplus.com">enroll (free) via email</a>, each day, you&#8217;ll receive a 10-15 minute video lesson. As you might expect, every episode will build upon the one it proceeds, and, sporadically, your skills will be put to the test, when you take the interactive quizzes! </p>
<p>Along the way, you&#8217;ll learn the essentials (querying and manipulating the DOM), while incrementally working your way up to more advanced topics, such as jQuery&#8217;s AJAX methods and plugin development. </p>
<p>I worked particularly hard to make the process of picking up this new skill as easy as possible for everyone &#8211; even if you have very, very little JavaScript experience. So&#8230;<a href="http://learnjquery.tutsplus.com">do you want to join me?</a> </p>
<p><a href="http://feedads.g.doubleclick.net/~a/MtYoR3hM8OVHnim4KTgeKQ1doQI/0/da"><img src="http://feedads.g.doubleclick.net/~a/MtYoR3hM8OVHnim4KTgeKQ1doQI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/MtYoR3hM8OVHnim4KTgeKQ1doQI/1/da"><img src="http://feedads.g.doubleclick.net/~a/MtYoR3hM8OVHnim4KTgeKQ1doQI/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=hI3XrFMnqw8:9H-58M5y3RI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=hI3XrFMnqw8:9H-58M5y3RI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=hI3XrFMnqw8:9H-58M5y3RI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/hI3XrFMnqw8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/articles/news/learn-jquery-in-30-days/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recently in Web Development (January ’12 Edition)</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 20:37:02 +0000</pubDate>
		<dc:creator>Siddharth</dc:creator>
				<category><![CDATA[announcements]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[community links]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23889</guid>
		<description><![CDATA[Web development is an industry that&#8217;s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.
In this series, published monthl...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/' rel='bookmark' title='Permanent Link: Recently in Web Development (January ’12 Edition)'>Recently in Web Development (January ’12 Edition)</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/uevKgXT8uSM/' rel='bookmark' title='Permanent Link: Recently in Web Development (July Edition)'>Recently in Web Development (July Edition)</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/Y-te7jVBfWc/' rel='bookmark' title='Permanent Link: Recently in Web Development (October Edition)'>Recently in Web Development (October Edition)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23889&c=893158197' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23889&c=893158197' border='0' alt='' /></a><p>Web development is an industry that&#8217;s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.</p>
<p>In this series, published monthly, we&#8217;ll seek to rectify this by bringing you all the important news, announcements, releases and interesting discussions within the web development industry in a concise package. Join me after the jump for an extra dose of community content this month!</p>
<p><span id="more-23889"></span></p>
<h2>
<hr style="clear: both;"/>News and Releases</h2>
<p>All of the important news in a single place: releases, announcements, companies bickering, security issues and all related hoopla.</p>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/html.png" width="250" /></div>
<h3>&#8216;HTML5 Please&#8217; Helps Devs Make Informed Decisions</h3>
<p>HTML5 is a beast of a spec with no one <em>truly</em> knowing everything there is to know. This shiny new site gives you all the information you need to use HTML5 features on your site, right now.</p>
<p>The site provides you with recommendations as to whether you should be using that specific facet of HTML5 right now and provides you with helpful links to polyfills, when necessary. Time saver!</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://html5please.us/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/enyo.png" width="250" /></div>
<h3>HP Open Sources Enyo</h3>
<p>Enyo is the engine that powers webOS. But what exactly is Enyo, you ask? Well, it&#8217;s a spiffy JavaScript framework that helps you build better performing, easier to maintain application.</p>
<p>I&#8217;m sure you&#8217;ve heard this plenty of times before so why don&#8217;t you check out the link below to find out for yourself?</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://enyojs.com/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1112_riwd7/sopa.png" width="250" /></div>
<h3>Tech Giants Protest SOPA</h3>
<p>Last month saw a figurative deluge of protests against SOPA. If you have no idea what SOPA is, hit the link below to find out.</p>
<p>While many services merely blackened out their logo, many others, including Wikipedia and Reddit, went the extra length and completely blacked out their sites. The proposed bill has been shelved but I predict that we&#8217;ll see another in a different skin soon&#8230;</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://en.wikipedia.org/wiki/SOPA" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/vim.png" width="250" /></div>
<h3>Vim on a Tablet? Yes, Please!</h3>
<p>I understand not everyone uses a tablet but the number is growing, quite rapidly. Wouldn&#8217;t it be great to SSH into your server to fix that pesky bug? Get a proper laptop, you say? I&#8217;m going to ask you to shush for now and go with the flow.</p>
<p>This month saw the release of Vim for the iOS platform. And no, it&#8217;s not a gimped version. From a quick run through, it seems that all the nice bits are still in there. If you&#8217;re in the intersection between developers and iPad users, let us know in the comments below as to whether it fits your needs.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://applidium.com/en/applications/vim/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/ctr.jpg" width="250" /></div>
<h3>Cut the Rope Ported to the Browser</h3>
<p>I&#8217;m sure a lot of you have played this ridiculously cute &#8216;aww&#8217; inducing game. What brings the game to our list is the fact that it has been ported to the browser by the newly cool Internet Explorer team. </p>
<p>And true to their current vision, they&#8217;ve ported it using JavaScript and the magic of HTML5. The link below leads you to a write up about the game development instead of the game itself to protect your productivity.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://www.cuttherope.ie/dev/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1002_riwd1/rails.png" width="250" /></div>
<h3>The Rails Tutorial, Version Two, Inches Towards Completion</h3>
<p>&#8216;The&#8217; Rails tutorial? Indeed it is! Michael Hartl&#8217;s <em>free</em> has helped many learn the voodoo that is Rails and Michael is slowly updating his ebook for Ruby 1.9 and Rails 3.2</p>
<p>Thus far, six chapters are out with a chapter expected every week in the future. Make sure to check the site out! </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://news.railstutorial.org/ruby-on-rails-tutorial-second-edition-updated" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/st2.png" width="250" /></div>
<h3>Sublime Text 2 Piles on More Features with New Beta</h3>
<p>Sublime Text 2 is a grand piece of work and every build only reaffirms this. This new build introduces a ton of features including auto complete, performance improvements, a new UI theme and a ton more.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://www.sublimetext.com/blog/articles/sublime-text-2-build-2165" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<h2>
<hr style="clear: both;"/>New Kids on the Block</h2>
<p>As web developers, the sheer amount of resources we can tap into increases exponentially with time. Here is just a quick look at some recently created resources that deserve your attention &#8212; everything from new books to scripts and frameworks.</p>
<hr />
<h3>wrap.js</h3>
<blockquote><p>My wrap.js plugin handles the nested require based on a config, and takes it to the next level by generating an actual AMD module for you during the build. So now you don’t have to write wrappers around scripts that you wish were modules, wrap.js does that for you. </p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/geddesign/wrap.js" >Github Repo</a></p>
<hr />
<h3>Resumable.js</h3>
<blockquote><p>Resumables is a JavaScript library providing multiple simultaneous, stable and resumable uploads via the HTML5 File API.<br />
The library is designed to introduce fault-tolerance into the upload of large files through HTTP. This is done by splitting each files into small chunks; whenever the upload of a chunk fails, uploading is retried until the procedure completes.</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/23/resumable.js" >Github Repo</a></p>
<hr />
<h3>IcedCoffeeScript</h3>
<blockquote><p>IcedCoffeeScript is a fork of CoffeeScript. It is superset of the CoffeeScript language. The iced interpreter is a drop-in replacement for the standard coffee interpreter since it will interpret all existing CoffeeScript programs. IcedCoffeeScript (ICS) adds two new keywords: await and defer. These additions simply and powerfully streamline asynchronous control flow, both on the server and on the browser. </p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://maxtaco.github.com/coffee-script/" >Github Repo</a></p>
<hr />
<h3>Banking.js</h3>
<blockquote><p> Banking.JS retrieves all of your bank transactions similiar to how quickbooks does it. There is no need to depend on or pay for third party services. The bank statement results are in JSON or Valid XML and supports all financial institutions.</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/euforic/banking.js" >Github Repo</a></p>
<hr />
<h3>Roy</h3>
<blockquote><p>Roy is a small functional language that compiles to JavaScript. The main features include whitespace significant syntax, compile-time meta-programming, structural typing and monad syntax</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/pufuwozu/roy" >Github Repo</a></p>
<hr />
<h3>jsgif</h3>
<blockquote><p>jsgif an animated GIF player bookmarklet with support for pausing, going frame-by-frame, playing in reverse, and other features that one might expect from a video player. </p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/shachaf/jsgif" >Github Repo</a></p>
<hr />
<h3>zip.js</h3>
<blockquote><p>zip.js offers a low-level API for writing and reading large zip files (up to 4GB) with a stable RAM use. It also offers a Filesystem API in order to manipulate zip file structure.</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://gildas-lormeau.github.com/zip.js/" >Github Repo</a></p>
<hr />
<h3>Seriously.js</h3>
<blockquote><p>Seriously.js is a real-time, node-based video compositor for the web. Inspired by professional software such as After Effects and Nuke, Seriously.js renders high-quality video effects, but allows them to be dynamic and interactive.</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/brianchirls/Seriously.js" >Github Repo</a></p>
<h2>
<hr style="clear: both;"/>Best of the Internet</h2>
<p>Often, you&#8217;re not really looking for a tutorial as much as you&#8217;re looking for a rant, an opinion or the musings of a tired developer or just something cool with absolutely zero real world use. This sections contains links to precisely those &#8212; interesting and cool stuff from the developer community. </p>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/749_WebHostFeatures/preview.jpg" width="250" /></div>
<h3>The Five Stages of Hosting</h3>
<p>Five common options for hosting a web business, ranked in decreasing order of &#8216;cloudiness&#8217;. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://blog.pinboard.in/2012/01/the_five_stages_of_hosting/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/913_jsDevs/yehuda_katz.png" width="250" /></div>
<h3>JavaScript Needs Blocks</h3>
<p>Yehuda Katz talks about why he wants to see block lambdas in JavaScript. It&#8217;s a bit technical but well worth a read. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://yehudakatz.com/2012/01/10/javascript-needs-blocks/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1002_riwd1/ror.png" width="250" /></div>
<h3>How I Learned Enough Ruby On Rails In 12 Weeks To Launch Freelancify</h3>
<p>A Non-Developer explains how&#8230; I think you know already. Just click the darn link and move on.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://www.webstartup.me/learned-ruby-rails-12-weeks-launch-freelancify" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1096_riwd6/cfn.gif" width="250" /></div>
<h3>Why are software development task estimations regularly off by a factor of 2-3?</h3>
<p>Is it the developer&#8217;s fault? Is it a management issue? Bad methodology, or lack thereof? Or is it ingrained in the nature of the process?</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://www.quora.com/Engineering-Management/Why-are-software-development-task-estimations-regularly-off-by-a-factor-of-2-3" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/wat.png" width="250" /></div>
<h3>Explanation for the &#8216;Wat&#8217; Talk &#8211; CodeMash 2012</h3>
<p>This StackOverflow question, along with the well written answers below, explore the code that was demonstrated in the talk mentioned in the title. Provides a quick look at the quirkier portions of JavaScript. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://stackoverflow.com/questions/9032856/can-anyone-explain-these-bizarre-javascript-behaviours-mentioned-in-the-wat-ta" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/db.png" width="250" /></div>
<h3>Why are column oriented databases so much faster than row oriented databases?</h3>
<p>A quick little read that explains why, and how, different databases perform differently. There isn&#8217;t much jargon there and gets the point quite clearly. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://siganakis.com/using-bitmap-indexes-in-query-processing" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/734_oop/200x200.jpg" width="250" /></div>
<h3>PHP Mind Love</h3>
<p>The link below points to some PHP code. Figure out what the output is and you get a cookie!</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/TheFox/JaPHPh/blob/master/japhph.php" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1096_riwd6/2d.jpg" width="250" /></div>
<h3>Testing Socket.IO With Mocha, Should.js and Socket.IO Client</h3>
<p>A clean writeup that details how the author got all the named technologies working together. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://liamkaufman.com/blog/2012/01/28/testing-socketio-with-mocha-should-and-socketio-client/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1019_riwd2/js.jpg" width="250" /></div>
<h3>What is the difference between semicolons in JavaScript and in Python?</h3>
<p>Ever had to think about the question above? How exactly do they each handle semicolons and newlines? Read up below.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://stackoverflow.com/questions/7219541/what-is-the-difference-between-semicolons-in-javascript-and-in-python" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/dj.png" width="250" /></div>
<h3>The Programming Djinn</h3>
<p>The Least Boring Programming Book teaches Ruby programming to beginners in an unconventional way. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://ethanfast.com/2012/01/the-least-boring-programming-book-chapter-1-excerpt/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/hg.png" width="250" /></div>
<h3>Non-Canvas Wizardry</h3>
<p>I don&#8217;t really have much context to go on here so just give the link below a click. Pretty smooth stuff for something that&#8217;s not canvas or Flash based.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://scorcher.de/palette/palette.html?fps=10&#038;colors=500&%23038;pixels=30&%23038;container=680" >Read more</a></p>
<div style="clear: both;"></div>
<h2>
<hr style="clear: both;"/>Wrapping Up</h2>
<p>Well, that&#8217;s about all the major changes that happened in our industry lately. </p>
<p>Do you want us to cover more standard news? A focus on upcoming scripts maybe? Or just more interesting posts and discussions from the community? Let us know in the comments and thank you so much for reading! </p>
<p><a href="http://feedads.g.doubleclick.net/~a/8amDKxS801IDE-2Ei0LFlSElF7M/0/da"><img src="http://feedads.g.doubleclick.net/~a/8amDKxS801IDE-2Ei0LFlSElF7M/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/8amDKxS801IDE-2Ei0LFlSElF7M/1/da"><img src="http://feedads.g.doubleclick.net/~a/8amDKxS801IDE-2Ei0LFlSElF7M/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/CZhjBpTuRuM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/articles/news/recently-in-web-development-january-12-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recently in Web Development (January ’12 Edition)</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 20:37:02 +0000</pubDate>
		<dc:creator>Siddharth</dc:creator>
				<category><![CDATA[announcements]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23889</guid>
		<description><![CDATA[Web development is an industry that&#8217;s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.
In this series, published monthl...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/' rel='bookmark' title='Permanent Link: Recently in Web Development (January ’12 Edition)'>Recently in Web Development (January ’12 Edition)</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/uevKgXT8uSM/' rel='bookmark' title='Permanent Link: Recently in Web Development (July Edition)'>Recently in Web Development (July Edition)</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/Y-te7jVBfWc/' rel='bookmark' title='Permanent Link: Recently in Web Development (October Edition)'>Recently in Web Development (October Edition)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23889&c=637656488' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23889&c=637656488' border='0' alt='' /></a><p>Web development is an industry that&#8217;s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.</p>
<p>In this series, published monthly, we&#8217;ll seek to rectify this by bringing you all the important news, announcements, releases and interesting discussions within the web development industry in a concise package. Join me after the jump for an extra dose of community content this month!</p>
<p><span id="more-23889"></span></p>
<h2>
<hr style="clear: both;"/>News and Releases</h2>
<p>All of the important news in a single place: releases, announcements, companies bickering, security issues and all related hoopla.</p>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/html.png" width="250" /></div>
<h3>&#8216;HTML5 Please&#8217; Helps Devs Make Informed Decisions</h3>
<p>HTML5 is a beast of a spec with no one <em>truly</em> knowing everything there is to know. This shiny new site gives you all the information you need to use HTML5 features on your site, right now.</p>
<p>The site provides you with recommendations as to whether you should be using that specific facet of HTML5 right now and provides you with helpful links to polyfills, when necessary. Time saver!</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://html5please.us/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/enyo.png" width="250" /></div>
<h3>HP Open Sources Enyo</h3>
<p>Enyo is the engine that powers webOS. But what exactly is Enyo, you ask? Well, it&#8217;s a spiffy JavaScript framework that helps you build better performing, easier to maintain application.</p>
<p>I&#8217;m sure you&#8217;ve heard this plenty of times before so why don&#8217;t you check out the link below to find out for yourself?</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://enyojs.com/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1112_riwd7/sopa.png" width="250" /></div>
<h3>Tech Giants Protest SOPA</h3>
<p>Last month saw a figurative deluge of protests against SOPA. If you have no idea what SOPA is, hit the link below to find out.</p>
<p>While many services merely blackened out their logo, many others, including Wikipedia and Reddit, went the extra length and completely blacked out their sites. The proposed bill has been shelved but I predict that we&#8217;ll see another in a different skin soon&#8230;</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://en.wikipedia.org/wiki/SOPA" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/vim.png" width="250" /></div>
<h3>Vim on a Tablet? Yes, Please!</h3>
<p>I understand not everyone uses a tablet but the number is growing, quite rapidly. Wouldn&#8217;t it be great to SSH into your server to fix that pesky bug? Get a proper laptop, you say? I&#8217;m going to ask you to shush for now and go with the flow.</p>
<p>This month saw the release of Vim for the iOS platform. And no, it&#8217;s not a gimped version. From a quick run through, it seems that all the nice bits are still in there. If you&#8217;re in the intersection between developers and iPad users, let us know in the comments below as to whether it fits your needs.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://applidium.com/en/applications/vim/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/ctr.jpg" width="250" /></div>
<h3>Cut the Rope Ported to the Browser</h3>
<p>I&#8217;m sure a lot of you have played this ridiculously cute &#8216;aww&#8217; inducing game. What brings the game to our list is the fact that it has been ported to the browser by the newly cool Internet Explorer team. </p>
<p>And true to their current vision, they&#8217;ve ported it using JavaScript and the magic of HTML5. The link below leads you to a write up about the game development instead of the game itself to protect your productivity.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://www.cuttherope.ie/dev/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1002_riwd1/rails.png" width="250" /></div>
<h3>The Rails Tutorial, Version Two, Inches Towards Completion</h3>
<p>&#8216;The&#8217; Rails tutorial? Indeed it is! Michael Hartl&#8217;s <em>free</em> has helped many learn the voodoo that is Rails and Michael is slowly updating his ebook for Ruby 1.9 and Rails 3.2</p>
<p>Thus far, six chapters are out with a chapter expected every week in the future. Make sure to check the site out! </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://news.railstutorial.org/ruby-on-rails-tutorial-second-edition-updated" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/st2.png" width="250" /></div>
<h3>Sublime Text 2 Piles on More Features with New Beta</h3>
<p>Sublime Text 2 is a grand piece of work and every build only reaffirms this. This new build introduces a ton of features including auto complete, performance improvements, a new UI theme and a ton more.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://www.sublimetext.com/blog/articles/sublime-text-2-build-2165" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<h2>
<hr style="clear: both;"/>New Kids on the Block</h2>
<p>As web developers, the sheer amount of resources we can tap into increases exponentially with time. Here is just a quick look at some recently created resources that deserve your attention &#8212; everything from new books to scripts and frameworks.</p>
<hr />
<h3>wrap.js</h3>
<blockquote><p>My wrap.js plugin handles the nested require based on a config, and takes it to the next level by generating an actual AMD module for you during the build. So now you don’t have to write wrappers around scripts that you wish were modules, wrap.js does that for you. </p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/geddesign/wrap.js" >Github Repo</a></p>
<hr />
<h3>Resumable.js</h3>
<blockquote><p>Resumables is a JavaScript library providing multiple simultaneous, stable and resumable uploads via the HTML5 File API.<br />
The library is designed to introduce fault-tolerance into the upload of large files through HTTP. This is done by splitting each files into small chunks; whenever the upload of a chunk fails, uploading is retried until the procedure completes.</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/23/resumable.js" >Github Repo</a></p>
<hr />
<h3>IcedCoffeeScript</h3>
<blockquote><p>IcedCoffeeScript is a fork of CoffeeScript. It is superset of the CoffeeScript language. The iced interpreter is a drop-in replacement for the standard coffee interpreter since it will interpret all existing CoffeeScript programs. IcedCoffeeScript (ICS) adds two new keywords: await and defer. These additions simply and powerfully streamline asynchronous control flow, both on the server and on the browser. </p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://maxtaco.github.com/coffee-script/" >Github Repo</a></p>
<hr />
<h3>Banking.js</h3>
<blockquote><p> Banking.JS retrieves all of your bank transactions similiar to how quickbooks does it. There is no need to depend on or pay for third party services. The bank statement results are in JSON or Valid XML and supports all financial institutions.</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/euforic/banking.js" >Github Repo</a></p>
<hr />
<h3>Roy</h3>
<blockquote><p>Roy is a small functional language that compiles to JavaScript. The main features include whitespace significant syntax, compile-time meta-programming, structural typing and monad syntax</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/pufuwozu/roy" >Github Repo</a></p>
<hr />
<h3>jsgif</h3>
<blockquote><p>jsgif an animated GIF player bookmarklet with support for pausing, going frame-by-frame, playing in reverse, and other features that one might expect from a video player. </p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/shachaf/jsgif" >Github Repo</a></p>
<hr />
<h3>zip.js</h3>
<blockquote><p>zip.js offers a low-level API for writing and reading large zip files (up to 4GB) with a stable RAM use. It also offers a Filesystem API in order to manipulate zip file structure.</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://gildas-lormeau.github.com/zip.js/" >Github Repo</a></p>
<hr />
<h3>Seriously.js</h3>
<blockquote><p>Seriously.js is a real-time, node-based video compositor for the web. Inspired by professional software such as After Effects and Nuke, Seriously.js renders high-quality video effects, but allows them to be dynamic and interactive.</p></blockquote>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/brianchirls/Seriously.js" >Github Repo</a></p>
<h2>
<hr style="clear: both;"/>Best of the Internet</h2>
<p>Often, you&#8217;re not really looking for a tutorial as much as you&#8217;re looking for a rant, an opinion or the musings of a tired developer or just something cool with absolutely zero real world use. This sections contains links to precisely those &#8212; interesting and cool stuff from the developer community. </p>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/749_WebHostFeatures/preview.jpg" width="250" /></div>
<h3>The Five Stages of Hosting</h3>
<p>Five common options for hosting a web business, ranked in decreasing order of &#8216;cloudiness&#8217;. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://blog.pinboard.in/2012/01/the_five_stages_of_hosting/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/913_jsDevs/yehuda_katz.png" width="250" /></div>
<h3>JavaScript Needs Blocks</h3>
<p>Yehuda Katz talks about why he wants to see block lambdas in JavaScript. It&#8217;s a bit technical but well worth a read. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://yehudakatz.com/2012/01/10/javascript-needs-blocks/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1002_riwd1/ror.png" width="250" /></div>
<h3>How I Learned Enough Ruby On Rails In 12 Weeks To Launch Freelancify</h3>
<p>A Non-Developer explains how&#8230; I think you know already. Just click the darn link and move on.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://www.webstartup.me/learned-ruby-rails-12-weeks-launch-freelancify" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1096_riwd6/cfn.gif" width="250" /></div>
<h3>Why are software development task estimations regularly off by a factor of 2-3?</h3>
<p>Is it the developer&#8217;s fault? Is it a management issue? Bad methodology, or lack thereof? Or is it ingrained in the nature of the process?</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://www.quora.com/Engineering-Management/Why-are-software-development-task-estimations-regularly-off-by-a-factor-of-2-3" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/wat.png" width="250" /></div>
<h3>Explanation for the &#8216;Wat&#8217; Talk &#8211; CodeMash 2012</h3>
<p>This StackOverflow question, along with the well written answers below, explore the code that was demonstrated in the talk mentioned in the title. Provides a quick look at the quirkier portions of JavaScript. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://stackoverflow.com/questions/9032856/can-anyone-explain-these-bizarre-javascript-behaviours-mentioned-in-the-wat-ta" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/db.png" width="250" /></div>
<h3>Why are column oriented databases so much faster than row oriented databases?</h3>
<p>A quick little read that explains why, and how, different databases perform differently. There isn&#8217;t much jargon there and gets the point quite clearly. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://siganakis.com/using-bitmap-indexes-in-query-processing" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/734_oop/200x200.jpg" width="250" /></div>
<h3>PHP Mind Love</h3>
<p>The link below points to some PHP code. Figure out what the output is and you get a cookie!</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="https://github.com/TheFox/JaPHPh/blob/master/japhph.php" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1096_riwd6/2d.jpg" width="250" /></div>
<h3>Testing Socket.IO With Mocha, Should.js and Socket.IO Client</h3>
<p>A clean writeup that details how the author got all the named technologies working together. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/gg" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1019_riwd2/js.jpg" width="250" /></div>
<h3>What is the difference between semicolons in JavaScript and in Python?</h3>
<p>Ever had to think about the question above? How exactly do they each handle semicolons and newlines? Read up below.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://stackoverflow.com/questions/7219541/what-is-the-difference-between-semicolons-in-javascript-and-in-python" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/dj.png" width="250" /></div>
<h3>The Programming Djinn</h3>
<p>The Least Boring Programming Book teaches Ruby programming to beginners in an unconventional way. </p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://ethanfast.com/2012/01/the-least-boring-programming-book-chapter-1-excerpt/" >Read more</a></p>
<div style="clear: both;"></div>
<div style="clear: both;"></div>
<div style="float:left; margin-right:20px; margin-top: 25px; padding: 5px; border: 1px solid #E8E8E8; "><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/hg.png" width="250" /></div>
<h3>Non-Canvas Wizardry</h3>
<p>I don&#8217;t really have much context to go on here so just give the link below a click. Pretty smooth stuff for something that&#8217;s not canvas or Flash based.</p>
<p><a style="display: block; text-align: right" style="display: block; text-align: right" href="http://scorcher.de/palette/palette.html?fps=10&#038;colors=500&%23038;pixels=30&%23038;container=680" >Read more</a></p>
<div style="clear: both;"></div>
<h2>
<hr style="clear: both;"/>Wrapping Up</h2>
<p>Well, that&#8217;s about all the major changes that happened in our industry lately. </p>
<p>Do you want us to cover more standard news? A focus on upcoming scripts maybe? Or just more interesting posts and discussions from the community? Let us know in the comments and thank you so much for reading! </p>
<p><a href="http://feedads.g.doubleclick.net/~a/KH7eF1fsvCT5hbD59kBjcIUu_MA/0/da"><img src="http://feedads.g.doubleclick.net/~a/KH7eF1fsvCT5hbD59kBjcIUu_MA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/KH7eF1fsvCT5hbD59kBjcIUu_MA/1/da"><img src="http://feedads.g.doubleclick.net/~a/KH7eF1fsvCT5hbD59kBjcIUu_MA/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/CZhjBpTuRuM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/articles/news/recently-in-web-development-january-12-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing an API Wrapper in Ruby with TDD</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/UkklRP6FQRY/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/UkklRP6FQRY/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 23:18:32 +0000</pubDate>
		<dc:creator>Claudio Ortolina</dc:creator>
				<category><![CDATA[api]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23875</guid>
		<description><![CDATA[Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/UkklRP6FQRY/' rel='bookmark' title='Permanent Link: Writing an API Wrapper in Ruby with TDD'>Writing an API Wrapper in Ruby with TDD</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/9kE88rT84Hc/' rel='bookmark' title='Permanent Link: Creating an API-Centric Web Application'>Creating an API-Centric Web Application</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/HBVPLZISqvU/' rel='bookmark' title='Permanent Link: Wrangling with the Facebook Graph API'>Wrangling with the Facebook Graph API</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23875&c=807871677' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23875&c=807871677' border='0' alt='' /></a><p>Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the API itself. This process is slow and inefficient, as we can experience network issues and data inconsistencies (the API results may change). Let&#8217;s review how we can avoid all of this effort with Ruby.</p>
<p><span id="more-23875"></span></p>
<hr />
<h2>Our Goal</h2>
<blockquote class="pullquote pqRight">
<p>&#8220;Flow is essential: write the tests, run them and see them fail, then write the minimal implementation code to make them pass. Once they all do, refactor if needed.&#8221;</p>
</blockquote>
<p>Our goal is simple: write a small wrapper around the <a href="http://dribbble.com/api">Dribbble API</a> to retrieve information about a user (called &#8216;player&#8217; in the Dribbble world).<br />
As we will be using Ruby, we will also follow a TDD approach: if you&#8217;re not familiar with this technique, Nettuts+ has a <a href="http://net.tutsplus.com/tutorials/ruby/ruby-for-newbies-testing-with-rspec/">good primer on RSpec</a> you can read. In a nutshell, we will write tests before writing our code implementation, making it easier to spot bugs and to achieve a high code quality. Flow is essential: write the tests, run them and see them fail, then write the minimal implementation code to make them pass. Once they all do, refactor if needed.</p>
<h3>The API</h3>
<p>The Dribbble API is fairly straightforward. At the time of this   it supports only GET requests and doesn&#8217;t require authentication: an ideal candidate for our tutorial. Moreover, it offers a 60 calls per minute limit, a restriction that perfectly shows why working with APIs require a smart approach.</p>
<hr />
<h2>Key Concepts</h2>
<p>This tutorial needs to assume that you have some familiarity with testing concepts: fixtures, mocks, expectations. Testing is an important topic (especially in the Ruby community) and even if you are not a Rubyist,  I&#8217;d encourage you to dig deeper into the matter and to search for equivalent tools for your everyday language. You may want to read <a href="http://pragprog.com/book/achbd/the-rspec-book">&#8220;The RSpec book&#8221; by David Chelimsky et al.</a>, an excellent primer on Behavior Driven Development. </p>
<p>To summarize here, here are three key concepts you must know:</p>
<ul>
<li><strong>Mock</strong>: also called double, a mock is &#8220;an object that stands in for another object in an example&#8221;. This means that if we want to test the interaction between an object and another, we can mock the second one. In this tutorial, we will mock the Dribbble API, as to test our code we don&#8217;t need the API, itself, but something that behaves like it and exposes the same interface.</li>
<li><strong>Fixture</strong>: a dataset that recreates a specific state in the system. A fixture can be used to create the needed data to test a piece of logic.</li>
<li><strong>Expectation</strong>: a test example written the from the point of view of the result we want to achieve.</li>
</ul>
<hr />
<h2>Our Tools</h2>
<blockquote class="pullquote pqRight">
<p>&#8220;As a general practice, run tests every time you update them.&#8221;</p>
</blockquote>
<p><a href="https://github.com/bblimke/webmock">WebMock</a> is a Ruby mocking library that is used to mock (or stub) http requests. In other words, it allows you to simulate any HTTP request without actually making one. The primary advantage to this is being able to develop and test against any HTTP service without needing the service itself and without incurring in related issues (like API limits, IP restrictions and such).<br />
<a href="https://github.com/myronmarston/vcr">VCR</a> is a complementary tool that records any real http request and creates a fixture, a file that contains all the needed data to replicate that request without performing it again. We will configure it to use WebMock to do that. In other words, our tests will interact with the real Dribbble API just once: after that, WebMock will stub all the requests thanks to the data recorded by VCR. We will have a perfect replica of the Dribbble API responses recorded locally. In addition, WebMock will let us test edge cases (like the request timing out) easily and consistently. A wonderful consequence of our setup is that everything will be extremely fast.</p>
<p>
As for unit testing, we will be using <a href="https://github.com/seattlerb/minitest">Minitest</a>. It&#8217;s a fast and simple unit testing library that also supports expectations in the RSpec fashion. It offers a  smaller feature set, but I find that this actually encourages and pushes you to separate your logic into small, testable methods. Minitest is part of Ruby 1.9, so if you&#8217;re using it (I hope so) you don&#8217;t need to install it. On Ruby 1.8, it&#8217;s only a matter of <code>gem install minitest</code>.</p>
<p>
I will be using Ruby 1.9.3: if you don&#8217;t, you will probably encounter some issues related to <code>require_relative</code>, but I&#8217;ve included fallback code in a comment right below it. As a general practice, you should run tests every time you update them, even if I won&#8217;t be mentioning this step explicitly throughout the tutorial.</p>
<hr />
<h2>Setup</h2>
<div class="tutorial_image">
  <img src="http://d2o0t5hpnwv4c1.cloudfront.net/1129_api_wrapper_tdd/images/01_setup.jpg" alt="Setup">
</div>
<p>We will use the conventional <code>/lib</code> and <code>/spec</code> folder structure to organize our code. As for the name of our library, we&#8217;ll call it <b>Dish</b>, following the Dribbble convention of using basketball related terms.</p>
<p>The Gemfile will contain all our dependencies, albeit they&#8217;re quite small.</p>
<pre class="brush: ruby; title: ; notranslate">
source :rubygems

gem 'httparty'

group :test do
  gem 'webmock'
  gem 'vcr'
  gem 'turn'
  gem 'rake'
end
</pre>
<p><a href="https://github.com/jnunemaker/httparty">Httparty</a> is an easy to use gem to handle HTTP requests; it will be the core of our library. In the test group, we will also add <a href="https://github.com/TwP/turn">Turn</a> to change the output of our tests to be more descriptive and to support color.</p>
<p>The <code>/lib</code> and <code>/spec</code> folders have a symmetrical structure: for every file contained in the <code>/lib/dish</code> folder, there should be a file inside <code>/spec/dish</code> with the same name and the &#8216;_spec&#8217; suffix.</p>
<p>
Let&#8217;s start by creating a <code>/lib/dish.rb</code> file and add the following code:</p>
<pre class="brush: ruby; title: ; notranslate">
require &quot;httparty&quot;
Dir[File.dirname(__FILE__) + '/dish/*.rb'].each do |file|
  require file
end
</pre>
<p>It doesn&#8217;t do much: it requires &#8216;httparty&#8217; and then iterates over every <code>.rb</code> file inside <code>/lib/dish</code> to require it. With this file in place, we will be able to add any functionality inside separate files in <code>/lib/dish</code> and have it automatically loaded just by requiring this single file.</p>
<p>Let&#8217;s move to the <code>/spec</code> folder. Here&#8217;s the content of the <code>spec_helper.rb</code> file.</p>
<pre class="brush: ruby; title: ; notranslate">
#we need the actual library file
require_relative '../lib/dish'
# For Ruby &lt; 1.9.3, use this instead of require_relative
# require(File.expand_path('../../lib/dish', __FILE__))

#dependencies
require 'minitest/autorun'
require 'webmock/minitest'
require 'vcr'
require 'turn'

Turn.config do |c|
 # :outline  - turn's original case/test outline mode [default]
 c.format  = :outline
 # turn on invoke/execute tracing, enable full backtrace
 c.trace   = true
 # use humanized test names (works only with :outline format)
 c.natural = true
end

#VCR config
VCR.config do |c|
  c.cassette_library_dir = 'spec/fixtures/dish_cassettes'
  c.stub_with :webmock
end
</pre>
<p>There&#8217;s quite a few things here worth noting, so let&#8217;s break it piece by piece:</p>
<ul>
<li>At first, we require the main lib file for our app, making the code we want to test available to the test suite. The <code>require_relative</code> statement is a Ruby 1.9.3 addition.
<li>We then require all the library dependencies: <code>minitest/autorun</code> includes all the expectations we will be using, <code>webmock/minitest</code> adds the needed bindings between the two libraries, while <code>vcr</code> and <code>turn</code> are pretty self-explanatory.
<li> The Turn config block merely needs to tweak our test output. We will use the outline format, where we can see the description of our specs.
<li>The VCR config blocks tells VCR to store the requests into a fixture folder (note the relative path) and to use WebMock as a stubbing library (VCR supports some other ones).</p>
</ul>
<p>Last, but not least, the <code>Rakefile</code> that contains some support code:</p>
<pre class="brush: ruby; title: ; notranslate">
require 'rake/testtask'

Rake::TestTask.new do |t|
  t.test_files = FileList['spec/lib/dish/*_spec.rb']
  t.verbose = true
end

task :default =&gt; :test
</pre>
<p>The <code>rake/testtask</code> library includes a <code>TestTask</code> class that is useful to set the location of our test files. From now on, to run our specs, we will only type <code>rake</code> from the library root directory.</p>
<p>As a way to test our configuration, let&#8217;s add the following code to <code>/lib/dish/player.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
module Dish
  class Player
  end
end
</pre>
<p>Then <code>/spec/lib/dish/player_spec.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
require_relative '../../spec_helper'
# For Ruby &lt; 1.9.3, use this instead of require_relative
# require (File.expand_path('./../../../spec_helper', __FILE__))

describe Dish::Player do

  it &quot;must work&quot; do
    &quot;Yay!&quot;.must_be_instance_of String
  end

end
</pre>
<p>Running <code>rake</code> should give you one test passing and no errors. This test is by no means useful for our project, yet it implicitly verifies that our library file structure is in place (the <code>describe</code> block would throw an error if the <code>Dish::Player</code> module was not loaded).</p>
<hr />
<h2>First Specs</h2>
<p>To work properly, Dish requires the Httparty modules and the correct <code>base_uri</code>, i.e. the base url of the Dribbble API. Let&#8217;s write the relevant tests for these requirements in <code>player_spec.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
...
describe Dish::Player do

  describe &quot;default attributes&quot; do

    it &quot;must include httparty methods&quot; do
      Dish::Player.must_include HTTParty
    end

    it &quot;must have the base url set to the Dribble API endpoint&quot; do
      Dish::Player.base_uri.must_equal 'http://api.dribbble.com'
    end

  end

end
</pre>
<p>As you can see, Minitest expectations are self-explanatory, especially if you are an RSpec user: the biggest difference is wording, where Minitest prefers &#8220;must/wont&#8221; to &#8220;should/should_not&#8221;.</p>
<p>Running these tests will show one error and one failure. To have them pass, let&#8217;s add our first lines of implementation code to <code>player.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
module Dish

  class Player

    include HTTParty

    base_uri 'http://api.dribbble.com'

  end

end
</pre>
<p>Running <code>rake</code> again should show the two specs passing. Now our <code>Player</code> class has access to all Httparty class methods, like <code>get</code> or <code>post</code>.</p>
<hr />
<h2>Recording our First Request</h2>
<p>As we will be working on the <code>Player</code> class, we will need to have API data for a player. The Dribbble API documentation page shows that the endpoint to get data about a specific player is <code>http://api.dribbble.com/players/:id</code></p>
<p>As in typical Rails fashion, <code>:id</code> is either the <em>id</em> or the <em>username</em> of a specific player. We will be using <code>simplebits</code>, the username of Dan Cederholm, one of the Dribbble founders.</p>
<p>To record the request with VCR, let&#8217;s update our <code>player_spec.rb</code> file by adding the following <code>describe</code> block to the spec, right after the first one:</p>
<pre class="brush: ruby; title: ; notranslate">
  ...

  describe &quot;GET profile&quot; do

  before do
    VCR.insert_cassette 'player', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;records the fixture&quot; do
    Dish::Player.get('/players/simplebits')
  end

  end

end
</pre>
<blockquote class="pullquote pqRight">
<p>After running <code>rake</code>, you can verify that the fixture has been created. From now on, all our tests will be completely network independent.</p>
</blockquote>
<p>The <code>before</code> block is used to execute a specific portion of code before every expectation: we use it to add the VCR macro used to record a fixture that we will call &#8216;player&#8217;. This will create a <code>player.yml</code> file under <code>spec/fixtures/dish_cassettes</code>. The <code>:record</code> option is set to record all new requests once and replay them on every subsequent, identical request. As a proof of concept, we can add a spec whose only aim is to record a fixture for simplebits&#8217;s profile. The <code>after</code> directive tells VCR to remove the cassette after the tests, making sure that everything is properly isolated. The <code>get</code> method on the <code>Player</code> class is made available, thanks to the inclusion of the <code>Httparty</code> module.</p>
<p>After running <code>rake</code>, you can verify that the fixture has been created. From now on, all our tests will be completely network independent.</p>
<hr />
<h2>Getting the Player Profile</h2>
<div class="tutorial_image"><img src="http://d2o0t5hpnwv4c1.cloudfront.net/1129_api_wrapper_tdd/images/02_dribbble.jpg" alt="Dribbble"></div>
<p>Every Dribbble user has a profile that contains a pretty extensive amount of data. Let&#8217;s think about how we would like our library to be when actually used: this is a useful way to flesh out our DSL will work. Here&#8217;s what we want to achieve:</p>
<pre class="brush: ruby; title: ; notranslate">
simplebits = Dish::Player.new('simplebits')
simplebits.profile
  =&gt; #returns a hash with all the data from the API
simplebits.username
  =&gt; 'simplebits'
simplebits.id
  =&gt; 1
simplebits.shots_count
  =&gt; 157
</pre>
<p>Simple and effective: we want to instantiate a Player by using its username and then get access to its data by calling methods on the instance that map to the attributes returned by the API. We need to be consistent with the API itself.</p>
<p>Let&#8217;s tackle one thing at a time and write some tests related to getting the player data from the API. We can modify our <code>"GET profile"</code> block to have:</p>
<pre class="brush: ruby; title: ; notranslate">
describe &quot;GET profile&quot; do

  let(:player) { Dish::Player.new }

  before do
    VCR.insert_cassette 'player', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;must have a profile method&quot; do
    player.must_respond_to :profile
  end

  it &quot;must parse the api response from JSON to Hash&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must perform the request and get the data&quot; do
    player.profile[&quot;username&quot;].must_equal 'simplebits'
  end

end
</pre>
<p>The <code>let</code> directive at the top creates a <code>Dish::Player</code> instance available in the expectations. Next, we want to make sure that our player has got a profile method whose value is a hash representing the data from the API. As a last step, we test a sample key (the username) to make sure that we actually perform the request.</p>
<p>
Note that we&#8217;re not yet handling how to set the username, as this is a further step. The minimal implementation required is the following:</p>
<pre class="brush: ruby; title: ; notranslate">
...
class Player

  include HTTParty

  base_uri 'http://api.dribbble.com'

  def profile
    self.class.get '/players/simplebits'
  end

end
...
</pre>
<p>A very little amount of code: we&#8217;re just wrapping a get call in the <code>profile</code> method. We then pass the hardcoded path to retrieve simplebits&#8217;s data, data that we had already stored thanks to VCR.</p>
<p>All our tests should be passing.</p>
<hr />
<h2>Setting the Username</h2>
<p>Now that we have a working profile function, we can take care of the username. Here are the relevant specs:</p>
<pre class="brush: ruby; title: ; notranslate">
describe &quot;default instance attributes&quot; do

  let(:player) { Dish::Player.new('simplebits') }

  it &quot;must have an id attribute&quot; do
    player.must_respond_to :username
  end

  it &quot;must have the right id&quot; do
    player.username.must_equal 'simplebits'
  end

end

describe &quot;GET profile&quot; do

  let(:player) { Dish::Player.new('simplebits') }

  before do
    VCR.insert_cassette 'base', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;must have a profile method&quot; do
    player.must_respond_to :profile
  end

  it &quot;must parse the api response from JSON to Hash&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must get the right profile&quot; do
    player.profile[&quot;username&quot;].must_equal &quot;simplebits&quot;
  end

end
</pre>
<p>We&#8217;ve added a new describe block to check the username we&#8217;re going to add and simply amended the <code>player</code> initialization in the <code>GET profile</code> block to reflect the DSL we want to have. Running the specs now will reveal many errors, as our <code>Player</code> class doesn&#8217;t accept arguments when initialized (for now).</p>
<p>Implementation is very straightforward:</p>
<pre class="brush: ruby; title: ; notranslate">
...
class Player

  attr_accessor :username

  include HTTParty

  base_uri 'http://api.dribbble.com'

  def initialize(username)
    self.username = username
  end

  def profile
    self.class.get &quot;/players/#{self.username}&quot;
  end

end
...
</pre>
<p>The initialize method gets a username that gets stored inside the class thanks to the <code>attr_accessor</code> method added above. We then change the profile method to interpolate the username attribute.</p>
<p>We should get all our tests passing once again.</p>
<hr />
<h2>Dynamic Attributes</h2>
<p>At a basic level, our lib is in pretty good shape. As profile is a Hash, we could stop here and already use it by passing the key of the attribute we want to get the value for. Our goal, however, is to create an easy to use DSL that has a method for each attribute.</p>
<p>Let&#8217;s think about what we need to achieve. Let&#8217;s assume we have a player instance and stub how it would work:</p>
<pre class="brush: ruby; title: ; notranslate">
player.username
  =&gt; 'simplebits'
player.shots_count
  =&gt; 157
player.foo_attribute
  =&gt; NoMethodError
</pre>
<p>Let&#8217;s translate this into specs and add them to the <code>GET profile</code> block:</p>
<pre class="brush: ruby; title: ; notranslate">
...
describe &quot;dynamic attributes&quot; do

  before do
    player.profile
  end

  it &quot;must return the attribute value if present in profile&quot; do
    player.id.must_equal 1
  end

  it &quot;must raise method missing if attribute is not present&quot; do
    lambda { player.foo_attribute }.must_raise NoMethodError
  end

end
...
</pre>
<p>We already have a spec for username, so we don&#8217;t need to add another one. Note a few things:</p>
<ul>
<li>we explicitly call <code>player.profile</code> in a before block, otherwise it will be nil when we try to get the attribute value.</li>
<li>to test that <code>foo_attribute</code> raises an exception, we need to wrap it in a lambda and check that it raises the expected error.</li>
<li>we test that <code>id</code> equals <code>1</code>, as we know that that is the expected value (this is a purely data-dependent test).</li>
</ul>
<p>Implementation-wise, we could define a series of methods to access the <code>profile</code> hash, yet this would create a lot of duplicated logic. Moreover, the would rely on the API result to always have the same keys.</p>
<blockquote class="pullquote pqLeft">
<p>&#8220;We will rely on <code>method_missing</code> to handle this cases and &#8216;generate&#8217; all those methods on the fly.&#8221;</p>
</blockquote>
<p>Instead, we will rely on <code>method_missing</code> to handle this cases and &#8216;generate&#8217; all those methods on the fly. But what does this mean? Without going into too much metaprogramming, we can simply say that every time we call a method not present on the object, Ruby raises a <code>NoMethodError</code> by using <code>method_missing</code>. By redefining this very method inside a class, we can modify its behaviour.</p>
<p>In our case, we will intercept the <code>method_missing</code> call, verify that the method name that has been called is a key in the profile hash and in case of positive result, return the hash value for that key. If not, we will call <code>super</code> to raise a standard <code>NoMethodError</code>: this is needed to make sure that our library behaves exactly the way any other library would do. In other words, we want to guarantee the least possible surprise.</p>
<p>Let&#8217;s add the following code to the <code>Player</code> class:</p>
<pre class="brush: ruby; title: ; notranslate">
def method_missing(name, *args, &amp;block)
  if profile.has_key?(name.to_s)
    profile[name.to_s]
  else
    super
  end
end
</pre>
<p>The code does exactly what described above. If you now run the specs, you should have them all pass. I&#8217;d encorage you to add some more to the spec files for some other attribute, like <code>shots_count</code>.</p>
<p>This implementation, however, is not really idiomatic Ruby. It works, but it can be streamlined into a ternary operator, a condensed form of an if-else conditional. It can be rewritten as:</p>
<pre class="brush: ruby; title: ; notranslate">
def method_missing(name, *args, &amp;block)
  profile.has_key?(name.to_s) ? profile[name.to_s] : super
end
</pre>
<p>It&#8217;s not just a matter of length, but also a matter of consistency and shared conventions between developers. Browsing source code of Ruby gems and libraries is a good way to get accustomed to these conventions.</p>
<hr />
<h2>Caching</h2>
<p>As a final step, we want to make sure that our library is efficient. It should not make any more requests than needed and possibly cache data internally. Once again, let&#8217;s think about how we could use it:</p>
<pre class="brush: ruby; title: ; notranslate">
player.profile
  =&gt; performs the request and returns a Hash
player.profile
  =&gt; returns the same hash
player.profile(true)
  =&gt; forces the reload of the http request and then returns the hash (with data changes if necessary)
</pre>
<p>How can we test this? We can by using WebMock to enable and disable network connections to the API endpoint. Even if we&#8217;re using VCR fixtures, WebMock can simulate a network Timeout or a different response to the server. In our case, we can test caching by getting the profile once and then disabling the network. By calling <code>player.profile</code> again we should see the same data, while by calling <code>player.profile(true)</code> we should get a <code>Timeout::Error</code>, as the library would try to connect to the (disabled) API endpoint.</p>
<p>Let&#8217;s add another block to the <code>player_spec.rb</code> file, right after <code>dynamic attribute generation</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
describe &quot;caching&quot; do

  # we use Webmock to disable the network connection after
  # fetching the profile
  before do
    player.profile
    stub_request(:any, /api.dribbble.com/).to_timeout
  end

  it &quot;must cache the profile&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must refresh the profile if forced&quot; do
    lambda { player.profile(true) }.must_raise Timeout::Error
  end

end
</pre>
<p>The <code>stub_request</code> method intercepts all calls to the API endpoint and simulates a timeout, raising the expected <code>Timeout::Error</code>. As we did before, we test the presence of this error in a lambda.</p>
<p>Implementation can be tricky, so we&#8217;ll split it into two steps. Firstly, let&#8217;s move the actual http request to a private method:</p>
<pre class="brush: ruby; title: ; notranslate">
...
def profile
  get_profile
end

...

private

def get_profile
  self.class.get(&quot;/players/#{self.username}&quot;)
end
...
</pre>
<p>This will not get our specs passing, as we&#8217;re not caching the result of <code>get_profile</code>. To do that, let&#8217;s change the <code>profile</code> method:</p>
<pre class="brush: ruby; title: ; notranslate">
...
def profile
  @profile ||= get_profile
end
...
</pre>
<p>We will store the result hash into an instance variable. Also note the <code>||=</code> operator, whose presence makes sure that <code>get_profile</code> is run only if @profile returns a falsy value (like <code>nil</code>).</p>
<p>Next we can add the forced reload directive:</p>
<pre class="brush: ruby; title: ; notranslate">
...
def profile(force = false)
  force ? @profile = get_profile : @profile ||= get_profile
end
...
</pre>
<p>We&#8217;re using a ternary again: if <code>force</code> is false, we perform <code>get_profile</code> and cache it, if not, we use the logic written in the previous version of this method (i.e. performing the request only if we don&#8217;t have already an hash).</p>
<p>Our specs should be green now and this is also the end of our tutorial.</p>
<hr />
<h2>Wrapping Up</h2>
<p>Our purpose in this tutorial was to write a small and efficient library to interact with the Dribbble API; we&#8217;ve laid the foundation for this to happen. Most of the logic we&#8217;ve written can be abstracted and reused to access all the other endpoints. Minitest, WebMock and VCR have proven to be valuable tools to help us shape our code.</p>
<p>
We do, however, need to be aware of a small caveat: VCR can become a double-edged sword, as our tests can become too much data-dependent. If, for any reason, the API we&#8217;re building against changes without any visible sign (like a version number), we may risk having our tests perfectly working with a dataset, which is no longer relevant. In that case, removing and recreating the fixture is the best way to make sure that our code still works as expected.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/pBBp6l16KiEDmQxVt1EVs425qwA/0/da"><img src="http://feedads.g.doubleclick.net/~a/pBBp6l16KiEDmQxVt1EVs425qwA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/pBBp6l16KiEDmQxVt1EVs425qwA/1/da"><img src="http://feedads.g.doubleclick.net/~a/pBBp6l16KiEDmQxVt1EVs425qwA/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/UkklRP6FQRY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/ruby/writing-an-api-wrapper-in-ruby-with-tdd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing an API Wrapper in Ruby with TDD</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/UkklRP6FQRY/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/UkklRP6FQRY/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 23:18:32 +0000</pubDate>
		<dc:creator>Claudio Ortolina</dc:creator>
				<category><![CDATA[api]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23875</guid>
		<description><![CDATA[Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/UkklRP6FQRY/' rel='bookmark' title='Permanent Link: Writing an API Wrapper in Ruby with TDD'>Writing an API Wrapper in Ruby with TDD</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/9kE88rT84Hc/' rel='bookmark' title='Permanent Link: Creating an API-Centric Web Application'>Creating an API-Centric Web Application</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/HBVPLZISqvU/' rel='bookmark' title='Permanent Link: Wrangling with the Facebook Graph API'>Wrangling with the Facebook Graph API</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23875&c=1274595345' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23875&c=1274595345' border='0' alt='' /></a><p>Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the API itself. This process is slow and inefficient, as we can experience network issues and data inconsistencies (the API results may change). Let&#8217;s review how we can avoid all of this effort with Ruby.</p>
<p><span id="more-23875"></span></p>
<hr />
<h2>Our Goal</h2>
<blockquote class="pullquote pqRight">
<p>&#8220;Flow is essential: write the tests, run them and see them fail, then write the minimal implementation code to make them pass. Once they all do, refactor if needed.&#8221;</p>
</blockquote>
<p>Our goal is simple: write a small wrapper around the <a href="http://dribbble.com/api">Dribbble API</a> to retrieve information about a user (called &#8216;player&#8217; in the Dribbble world).<br />
As we will be using Ruby, we will also follow a TDD approach: if you&#8217;re not familiar with this technique, Nettuts+ has a <a href="http://net.tutsplus.com/tutorials/ruby/ruby-for-newbies-testing-with-rspec/">good primer on RSpec</a> you can read. In a nutshell, we will write tests before writing our code implementation, making it easier to spot bugs and to achieve a high code quality. Flow is essential: write the tests, run them and see them fail, then write the minimal implementation code to make them pass. Once they all do, refactor if needed.</p>
<h3>The API</h3>
<p>The Dribbble API is fairly straightforward. At the time of this   it supports only GET requests and doesn&#8217;t require authentication: an ideal candidate for our tutorial. Moreover, it offers a 60 calls per minute limit, a restriction that perfectly shows why working with APIs require a smart approach.</p>
<hr />
<h2>Key Concepts</h2>
<p>This tutorial needs to assume that you have some familiarity with testing concepts: fixtures, mocks, expectations. Testing is an important topic (especially in the Ruby community) and even if you are not a Rubyist,  I&#8217;d encourage you to dig deeper into the matter and to search for equivalent tools for your everyday language. You may want to read <a href="http://pragprog.com/book/achbd/the-rspec-book">&#8220;The RSpec book&#8221; by David Chelimsky et al.</a>, an excellent primer on Behavior Driven Development. </p>
<p>To summarize here, here are three key concepts you must know:</p>
<ul>
<li><strong>Mock</strong>: also called double, a mock is &#8220;an object that stands in for another object in an example&#8221;. This means that if we want to test the interaction between an object and another, we can mock the second one. In this tutorial, we will mock the Dribbble API, as to test our code we don&#8217;t need the API, itself, but something that behaves like it and exposes the same interface.</li>
<li><strong>Fixture</strong>: a dataset that recreates a specific state in the system. A fixture can be used to create the needed data to test a piece of logic.</li>
<li><strong>Expectation</strong>: a test example written the from the point of view of the result we want to achieve.</li>
</ul>
<hr />
<h2>Our Tools</h2>
<blockquote class="pullquote pqRight">
<p>&#8220;As a general practice, run tests every time you update them.&#8221;</p>
</blockquote>
<p><a href="https://github.com/bblimke/webmock">WebMock</a> is a Ruby mocking library that is used to mock (or stub) http requests. In other words, it allows you to simulate any HTTP request without actually making one. The primary advantage to this is being able to develop and test against any HTTP service without needing the service itself and without incurring in related issues (like API limits, IP restrictions and such).<br />
<a href="https://github.com/myronmarston/vcr">VCR</a> is a complementary tool that records any real http request and creates a fixture, a file that contains all the needed data to replicate that request without performing it again. We will configure it to use WebMock to do that. In other words, our tests will interact with the real Dribbble API just once: after that, WebMock will stub all the requests thanks to the data recorded by VCR. We will have a perfect replica of the Dribbble API responses recorded locally. In addition, WebMock will let us test edge cases (like the request timing out) easily and consistently. A wonderful consequence of our setup is that everything will be extremely fast.</p>
<p>
As for unit testing, we will be using <a href="https://github.com/seattlerb/minitest">Minitest</a>. It&#8217;s a fast and simple unit testing library that also supports expectations in the RSpec fashion. It offers a  smaller feature set, but I find that this actually encourages and pushes you to separate your logic into small, testable methods. Minitest is part of Ruby 1.9, so if you&#8217;re using it (I hope so) you don&#8217;t need to install it. On Ruby 1.8, it&#8217;s only a matter of <code>gem install minitest</code>.</p>
<p>
I will be using Ruby 1.9.3: if you don&#8217;t, you will probably encounter some issues related to <code>require_relative</code>, but I&#8217;ve included fallback code in a comment right below it. As a general practice, you should run tests every time you update them, even if I won&#8217;t be mentioning this step explicitly throughout the tutorial.</p>
<hr />
<h2>Setup</h2>
<div class="tutorial_image">
  <img src="http://d2o0t5hpnwv4c1.cloudfront.net/1129_api_wrapper_tdd/images/01_setup.jpg" alt="Setup">
</div>
<p>We will use the conventional <code>/lib</code> and <code>/spec</code> folder structure to organize our code. As for the name of our library, we&#8217;ll call it <b>Dish</b>, following the Dribbble convention of using basketball related terms.</p>
<p>The Gemfile will contain all our dependencies, albeit they&#8217;re quite small.</p>
<pre class="brush: ruby; title: ; notranslate">
source :rubygems

gem 'httparty'

group :test do
  gem 'webmock'
  gem 'vcr'
  gem 'turn'
  gem 'rake'
end
</pre>
<p><a href="https://github.com/jnunemaker/httparty">Httparty</a> is an easy to use gem to handle HTTP requests; it will be the core of our library. In the test group, we will also add <a href="https://github.com/TwP/turn">Turn</a> to change the output of our tests to be more descriptive and to support color.</p>
<p>The <code>/lib</code> and <code>/spec</code> folders have a symmetrical structure: for every file contained in the <code>/lib/dish</code> folder, there should be a file inside <code>/spec/dish</code> with the same name and the &#8216;_spec&#8217; suffix.</p>
<p>
Let&#8217;s start by creating a <code>/lib/dish.rb</code> file and add the following code:</p>
<pre class="brush: ruby; title: ; notranslate">
require &quot;httparty&quot;
Dir[File.dirname(__FILE__) + '/dish/*.rb'].each do |file|
  require file
end
</pre>
<p>It doesn&#8217;t do much: it requires &#8216;httparty&#8217; and then iterates over every <code>.rb</code> file inside <code>/lib/dish</code> to require it. With this file in place, we will be able to add any functionality inside separate files in <code>/lib/dish</code> and have it automatically loaded just by requiring this single file.</p>
<p>Let&#8217;s move to the <code>/spec</code> folder. Here&#8217;s the content of the <code>spec_helper.rb</code> file.</p>
<pre class="brush: ruby; title: ; notranslate">
#we need the actual library file
require_relative '../lib/dish'
# For Ruby &lt; 1.9.3, use this instead of require_relative
# require(File.expand_path('../../lib/dish', __FILE__))

#dependencies
require 'minitest/autorun'
require 'webmock/minitest'
require 'vcr'
require 'turn'

Turn.config do |c|
 # :outline  - turn's original case/test outline mode [default]
 c.format  = :outline
 # turn on invoke/execute tracing, enable full backtrace
 c.trace   = true
 # use humanized test names (works only with :outline format)
 c.natural = true
end

#VCR config
VCR.config do |c|
  c.cassette_library_dir = 'spec/fixtures/dish_cassettes'
  c.stub_with :webmock
end
</pre>
<p>There&#8217;s quite a few things here worth noting, so let&#8217;s break it piece by piece:</p>
<ul>
<li>At first, we require the main lib file for our app, making the code we want to test available to the test suite. The <code>require_relative</code> statement is a Ruby 1.9.3 addition.
<li>We then require all the library dependencies: <code>minitest/autorun</code> includes all the expectations we will be using, <code>webmock/minitest</code> adds the needed bindings between the two libraries, while <code>vcr</code> and <code>turn</code> are pretty self-explanatory.
<li> The Turn config block merely needs to tweak our test output. We will use the outline format, where we can see the description of our specs.
<li>The VCR config blocks tells VCR to store the requests into a fixture folder (note the relative path) and to use WebMock as a stubbing library (VCR supports some other ones).</p>
</ul>
<p>Last, but not least, the <code>Rakefile</code> that contains some support code:</p>
<pre class="brush: ruby; title: ; notranslate">
require 'rake/testtask'

Rake::TestTask.new do |t|
  t.test_files = FileList['spec/lib/dish/*_spec.rb']
  t.verbose = true
end

task :default =&gt; test
</pre>
<p>The <code>rake/testtask</code> library includes a <code>TestTask</code> class that is useful to set the location of our test files. From now on, to run our specs, we will only type <code>rake</code> from the library root directory.</p>
<p>As a way to test our configuration, let&#8217;s add the following code to <code>/lib/dish/player.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
module Dish
  class Player
  end
end
</pre>
<p>Then <code>/spec/lib/dish/player_spec.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
require_relative '../../spec_helper'
# For Ruby &lt; 1.9.3, use this instead of require_relative
# require (File.expand_path('./../../../spec_helper', __FILE__))

describe Dish::Player do

  it &quot;must work&quot; do
    &quot;Yay!&quot;.must_be_instance_of String
  end

end
</pre>
<p>Running <code>rake</code> should give you one test passing and no errors. This test is by no means useful for our project, yet it implicitly verifies that our library file structure is in place (the <code>describe</code> block would throw an error if the <code>Dish::Player</code> module was not loaded).</p>
<hr />
<h2>First Specs</h2>
<p>To work properly, Dish requires the Httparty modules and the correct <code>base_uri</code>, i.e. the base url of the Dribbble API. Let&#8217;s write the relevant tests for these requirements in <code>player_spec.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
...
describe Dish::Player do

  describe &quot;default attributes&quot; do

    it &quot;must include httparty methods&quot; do
      Dish::Player.must_include HTTParty
    end

    it &quot;must have the base url set to the Dribble API endpoint&quot; do
      Dish::Player.base_uri.must_equal 'http://api.dribbble.com'
    end

  end

end
</pre>
<p>As you can see, Minitest expectations are self-explanatory, especially if you are an RSpec user: the biggest difference is wording, where Minitest prefers &#8220;must/wont&#8221; to &#8220;should/should_not&#8221;.</p>
<p>Running these tests will show one error and one failure. To have them pass, let&#8217;s add our first lines of implementation code to <code>player.rb</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
module Dish

  class Player

    include HTTParty

    base_uri 'http://api.dribbble.com'

  end

end
</pre>
<p>Running <code>rake</code> again should show the two specs passing. Now our <code>Player</code> class has access to all Httparty class methods, like <code>get</code> or <code>post</code>.</p>
<hr />
<h2>Recording our First Request</h2>
<p>As we will be working on the <code>Player</code> class, we will need to have API data for a player. The Dribbble API documentation page shows that the endpoint to get data about a specific player is <code>http://api.dribbble.com/players/:id</code></p>
<p>As in typical Rails fashion, <code>:id</code> is either the <em>id</em> or the <em>username</em> of a specific player. We will be using <code>simplebits</code>, the username of Dan Cederholm, one of the Dribbble founders.</p>
<p>To record the request with VCR, let&#8217;s update our <code>player_spec.rb</code> file by adding the following <code>describe</code> block to the spec, right after the first one:</p>
<pre class="brush: ruby; title: ; notranslate">
  ...

  describe &quot;GET profile&quot; do

  before do
    VCR.insert_cassette 'player', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;records the fixture&quot; do
    Dish::Player.get('/players/simplebits')
  end

  end

end
</pre>
<blockquote class="pullquote pqRight">
<p>After running <code>rake</code>, you can verify that the fixture has been created. From now on, all our tests will be completely network independent.</p>
</blockquote>
<p>The <code>before</code> block is used to execute a specific portion of code before every expectation: we use it to add the VCR macro used to record a fixture that we will call &#8216;player&#8217;. This will create a <code>player.yml</code> file under <code>spec/fixtures/dish_cassettes</code>. The <code>:record</code> option is set to record all new requests once and replay them on every subsequent, identical request. As a proof of concept, we can add a spec whose only aim is to record a fixture for simplebits&#8217;s profile. The <code>after</code> directive tells VCR to remove the cassette after the tests, making sure that everything is properly isolated. The <code>get</code> method on the <code>Player</code> class is made available, thanks to the inclusion of the <code>Httparty</code> module.</p>
<p>After running <code>rake</code>, you can verify that the fixture has been created. From now on, all our tests will be completely network independent.</p>
<hr />
<h2>Getting the Player Profile</h2>
<div class="tutorial_image"><img src="http://d2o0t5hpnwv4c1.cloudfront.net/1129_api_wrapper_tdd/images/02_dribbble.jpg" alt="Dribbble"></div>
<p>Every Dribbble user has a profile that contains a pretty extensive amount of data. Let&#8217;s think about how we would like our library to be when actually used: this is a useful way to flesh out our DSL will work. Here&#8217;s what we want to achieve:</p>
<pre class="brush: ruby; title: ; notranslate">
simplebits = Dish::Player.new('simplebits')
simplebits.profile
  =&gt; #returns a hash with all the data from the API
simplebits.username
  =&gt; 'simplebits'
simplebits.id
  =&gt; 1
simplebits.shots_count
  =&gt; 157
</pre>
<p>Simple and effective: we want to instantiate a Player by using its username and then get access to its data by calling methods on the instance that map to the attributes returned by the API. We need to be consistent with the API itself.</p>
<p>Let&#8217;s tackle one thing at a time and write some tests related to getting the player data from the API. We can modify our <code>"GET profile"</code> block to have:</p>
<pre class="brush: ruby; title: ; notranslate">
describe &quot;GET profile&quot; do

  let(:player) { Dish::Player.new }

  before do
    VCR.insert_cassette 'player', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;must have a profile method&quot; do
    player.must_respond_to :profile
  end

  it &quot;must parse the api response from JSON to Hash&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must perform the request and get the data&quot; do
    player.profile[&quot;username&quot;].must_equal 'simplebits'
  end

end
</pre>
<p>The <code>let</code> directive at the top creates a <code>Dish::Player</code> instance available in the expectations. Next, we want to make sure that our player has got a profile method whose value is a hash representing the data from the API. As a last step, we test a sample key (the username) to make sure that we actually perform the request.</p>
<p>
Note that we&#8217;re not yet handling how to set the username, as this is a further step. The minimal implementation required is the following:</p>
<pre class="brush: ruby; title: ; notranslate">
...
class Player

  include HTTParty

  base_uri 'http://api.dribbble.com'

  def profile
    self.class.get '/players/simplebits'
  end

end
...
</pre>
<p>A very little amount of code: we&#8217;re just wrapping a get call in the <code>profile</code> method. We then pass the hardcoded path to retrieve simplebits&#8217;s data, data that we had already stored thanks to VCR.</p>
<p>All our tests should be passing.</p>
<hr />
<h2>Setting the Username</h2>
<p>Now that we have a working profile function, we can take care of the username. Here are the relevant specs:</p>
<pre class="brush: ruby; title: ; notranslate">
describe &quot;default instance attributes&quot; do

  let(:player) { Dish::Player.new('simplebits') }

  it &quot;must have an id attribute&quot; do
    player.must_respond_to :username
  end

  it &quot;must have the right id&quot; do
    player.username.must_equal 'simplebits'
  end

end

describe &quot;GET profile&quot; do

  let(:player) { Dish::Player.new('simplebits') }

  before do
    VCR.insert_cassette 'base', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;must have a profile method&quot; do
    player.must_respond_to :profile
  end

  it &quot;must parse the api response from JSON to Hash&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must get the right profile&quot; do
    player.profile[&quot;username&quot;].must_equal &quot;simplebits&quot;
  end

end
</pre>
<p>We&#8217;ve added a new describe block to check the username we&#8217;re going to add and simply amended the <code>player</code> initialization in the <code>GET profile</code> block to reflect the DSL we want to have. Running the specs now will reveal many errors, as our <code>Player</code> class doesn&#8217;t accept arguments when initialized (for now).</p>
<p>Implementation is very straightforward:</p>
<pre class="brush: ruby; title: ; notranslate">
...
class Player

  attr_accessor :username

  include HTTParty

  base_uri 'http://api.dribbble.com'

  def initialize(username)
    self.username = username
  end

  def profile
    self.class.get &quot;/players/#{self.username}&quot;
  end

end
...
</pre>
<p>The initialize method gets a username that gets stored inside the class thanks to the <code>attr_accessor</code> method added above. We then change the profile method to interpolate the username attribute.</p>
<p>We should get all our tests passing once again.</p>
<hr />
<h2>Dynamic Attributes</h2>
<p>At a basic level, our lib is in pretty good shape. As profile is a Hash, we could stop here and already use it by passing the key of the attribute we want to get the value for. Our goal, however, is to create an easy to use DSL that has a method for each attribute.</p>
<p>Let&#8217;s think about what we need to achieve. Let&#8217;s assume we have a player instance and stub how it would work:</p>
<pre class="brush: ruby; title: ; notranslate">
player.username
  =&gt; 'simplebits'
player.shots_count
  =&gt; 157
player.foo_attribute
  =&gt; NoMethodError
</pre>
<p>Let&#8217;s translate this into specs and add them to the <code>GET profile</code> block:</p>
<pre class="brush: ruby; title: ; notranslate">
...
describe &quot;dynamic attributes&quot; do

  before do
    player.profile
  end

  it &quot;must return the attribute value if present in profile&quot; do
    player.id.must_equal 1
  end

  it &quot;must raise method missing if attribute is not present&quot; do
    lambda { player.foo_attribute }.must_raise NoMethodError
  end

end
...
</pre>
<p>We already have a spec for username, so we don&#8217;t need to add another one. Note a few things:</p>
<ul>
<li>we explicitly call <code>player.profile</code> in a before block, otherwise it will be nil when we try to get the attribute value.</li>
<li>to test that <code>foo_attribute</code> raises an exception, we need to wrap it in a lambda and check that it raises the expected error.</li>
<li>we test that <code>id</code> equals <code>1</code>, as we know that that is the expected value (this is a purely data-dependent test).</li>
</ul>
<p>Implementation-wise, we could define a series of methods to access the <code>profile</code> hash, yet this would create a lot of duplicated logic. Moreover, the would rely on the API result to always have the same keys.</p>
<blockquote class="pullquote pqLeft">
<p>&#8220;We will rely on <code>method_missing</code> to handle this cases and &#8216;generate&#8217; all those methods on the fly.&#8221;</p>
</blockquote>
<p>Instead, we will rely on <code>method_missing</code> to handle this cases and &#8216;generate&#8217; all those methods on the fly. But what does this mean? Without going into too much metaprogramming, we can simply say that every time we call a method not present on the object, Ruby raises a <code>NoMethodError</code> by using <code>method_missing</code>. By redefining this very method inside a class, we can modify its behaviour.</p>
<p>In our case, we will intercept the <code>method_missing</code> call, verify that the method name that has been called is a key in the profile hash and in case of positive result, return the hash value for that key. If not, we will call <code>super</code> to raise a standard <code>NoMethodError</code>: this is needed to make sure that our library behaves exactly the way any other library would do. In other words, we want to guarantee the least possible surprise.</p>
<p>Let&#8217;s add the following code to the Player class:</p>
<pre class="brush: ruby; title: ; notranslate">
def method_missing(name)
  if profile.has_key?(name.to_s)
    profile[name.to_s]
  else
    super
  end
end
</pre>
<p>The code does exactly what described above. If you now run the specs, you should have them all pass. I&#8217;d encorage you to add some more to the spec files for some other attribute, like <code>shots_count</code>.</p>
<p>This implementation, however, is not really idiomatic Ruby. It works, but it can be streamlined into a ternary operator, a condensed form of an if-else conditional. It can be rewritten as:</p>
<pre class="brush: ruby; title: ; notranslate">
def method_missing(name, *args, &amp;block)
  profile.has_key?(name.to_s) ? profile[name.to_s] : super
end
</pre>
<p>It&#8217;s not just a matter of length, but also a matter of consistency and shared conventions between developers. Browsing source code of Ruby gems and libraries is a good way to get accustomed to these conventions.</p>
<hr />
<h2>Caching</h2>
<p>As a final step, we want to make sure that our library is efficient. It should not make any more requests than needed and possibly cache data internally. Once again, let&#8217;s think about how we could use it:</p>
<pre class="brush: ruby; title: ; notranslate">
player.profile
  =&gt; performs the request and returns a Hash
player.profile
  =&gt; returns the same hash
player.profile(true)
  =&gt; forces the reload of the http request and then returns the hash (with data changes if necessary)
</pre>
<p>How can we test this? We can by using WebMock to enable and disable network connections to the API endpoint. Even if we&#8217;re using VCR fixtures, WebMock can simulate a network Timeout or a different response to the server. In our case, we can test caching by getting the profile once and then disabling the network. By calling <code>player.profile</code> again we should see the same data, while by calling <code>player.profile(true)</code> we should get a <code>Timeout::Error</code>, as the library would try to connect to the (disabled) API endpoint.</p>
<p>Let&#8217;s add another block to the <code>player_spec.rb</code> file, right after <code>dynamic attribute generation</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
describe &quot;caching&quot; do

  # we use Webmock to disable the network connection after
  # fetching the profile
  before do
    player.profile
    stub_request(:any, /api.dribbble.com/).to_timeout
  end

  it &quot;must cache the profile&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must refresh the profile if forced&quot; do
    lambda { player.profile(true) }.must_raise Timeout::Error
  end

end
</pre>
<p>The <code>stub_request</code> method intercepts all calls to the API endpoint and simulates a timeout, raising the expected <code>Timeout::Error</code>. As we did before, we test the presence of this error in a lambda.</p>
<p>Implementation can be tricky, so we&#8217;ll split it into two steps. Firstly, let&#8217;s move the actual http request to a private method:</p>
<pre class="brush: ruby; title: ; notranslate">
...
def profile
  get_profile
end

...

private

def get_profile
  self.class.get(&quot;/players/#{self.username}&quot;)
end
...
</pre>
<p>This will not get our specs passing, as we&#8217;re not caching the result of <code>get_profile</code>. To do that, let&#8217;s change the <code>profile</code> method:</p>
<pre class="brush: ruby; title: ; notranslate">
...
def profile
  @profile ||= get_profile
end
...
</pre>
<p>We will store the result hash into an instance variable. Also note the <code>||=</code> operator, whose presence makes sure that <code>get_profile</code> is run only if @profile returns a falsy value (like <code>nil</code>).</p>
<p>Next we can add the forced reload directive:</p>
<pre class="brush: ruby; title: ; notranslate">
...
def profile(force = false)
  force ? @profile = get_profile : @profile ||= get_profile
end
...
</pre>
<p>We&#8217;re using a ternary again: if <code>force</code> is false, we perform <code>get_profile</code> and cache it, if not, we use the logic written in the previous version of this method (i.e. performing the request only if we don&#8217;t have already an hash).</p>
<p>Our specs should be green now and this is also the end of our tutorial.</p>
<hr />
<h2>Wrapping Up</h2>
<p>Our purpose in this tutorial was writing a small and efficient library to interact with the Dribbble API; we&#8217;ve laid the foundation for this to happen. Most of the logic we&#8217;ve written can be abstracted and requesed to access all the other endpoints. Minitest, WebMock and VCR have proven to be valuable tools to help us shape our code.</p>
<p>
We do, however, need to be aware of a small caveat: VCR can become a double-edged sword, as our tests can become too much data-dependent. If, for any reason, the API we&#8217;re building against changes without any visible sign (like a version number), we may risk having our tests perfectly working with a dataset, which is no longer relevant. In that case, removing and recreating the fixture is the best way to make sure that our code still works as expected.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/LER8jqe63jWFyvChbz31gykQOd8/0/da"><img src="http://feedads.g.doubleclick.net/~a/LER8jqe63jWFyvChbz31gykQOd8/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/LER8jqe63jWFyvChbz31gykQOd8/1/da"><img src="http://feedads.g.doubleclick.net/~a/LER8jqe63jWFyvChbz31gykQOd8/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/UkklRP6FQRY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/ruby/writing-an-api-wrapper-in-ruby-with-tdd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>24 Extremely Useful Ruby Gems for Web Development</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/TQXIcZXrplk/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/TQXIcZXrplk/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 21:38:56 +0000</pubDate>
		<dc:creator>Siddharth</dc:creator>
				<category><![CDATA[gems]]></category>
		<category><![CDATA[must have]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Roundups]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23863</guid>
		<description><![CDATA[One of the nicer things about developing on the Ruby platform is the sheer amount of meticulously categorized, highly reusable code wrapped up in the form of aptly named &#8216;gems&#8217;. 
I&#8217;m sure you&#8217;ve heard of popular frameworks like ...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/TQXIcZXrplk/' rel='bookmark' title='Permanent Link: 24 Extremely Useful Ruby Gems for Web Development'>24 Extremely Useful Ruby Gems for Web Development</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/vq5s_MZEZLQ/' rel='bookmark' title='Permanent Link: Ruby for Newbies: Testing Web Apps with Capybara and Cucumber'>Ruby for Newbies: Testing Web Apps with Capybara and Cucumber</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/' rel='bookmark' title='Permanent Link: Recently in Web Development (January ’12 Edition)'>Recently in Web Development (January ’12 Edition)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23863&c=858716227' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23863&c=858716227' border='0' alt='' /></a><p>One of the nicer things about developing on the Ruby platform is the sheer amount of meticulously categorized, highly reusable code wrapped up in the form of aptly named &#8216;gems&#8217;. </p>
<p>I&#8217;m sure you&#8217;ve heard of popular frameworks like Sinatra or the super popular Rails that ship as gems but you&#8217;re missing an entire spectrum of others that handle issues at a much lower level. Start using these and watch your productivity shoot through the roof!</p>
<p><span id="more-23863"></span></p>
<hr />
<h2>A Quick Note</h2>
<p>I&#8217;m well aware that some of the gems listed here have Rails, or parts of Rails, as a dependency. That doesn&#8217;t mean that they are any less useful or need to be sneered at. </p>
<hr />
<h2>CarrierWave</h2>
<blockquote><p>Upload files in your Ruby applications, map them to a range of ORMs, store them on different backends. It works well with Rack based web applications, such as Ruby on Rails.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/jnicklas/carrierwave" >Github repo</a></li>
<li><a href="http://www.engineyard.com/blog/2011/a-gentle-introduction-to-carrierwave/" >A Gentle Introduction to CarrierWave</a></li>
</ul>
<hr /<br />
<h2>Kaminari</h2>
<blockquote><p>Kaminari is a Scope &#038; Engine based, clean, powerful, customizable and sophisticated paginator. Kaminari supports multiple ORMs (ActiveRecord, Mongoid, MongoMapper) multiple web frameworks (Rails, Sinatra), and multiple template engines (ERB, Haml).</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/amatsuda/kaminari" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/254-pagination-with-kaminari" >Railscasts #254 Pagination with Kaminari</a></li>
</ul>
<hr />
<h2>HAML</h2>
<blockquote><p>Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML that&#8217;s designed to express the structure of XHTML or XML documents in a non-repetitive, elegant, easy way, using indentation rather than closing tags and allowing Ruby to be embedded with ease. It was originally envisioned as a plugin for Ruby on Rails, but it can function as a stand-alone templating engine.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="http://haml-lang.com/" >HAML website</a></li>
<li><a href="http://net.tutsplus.com/tutorials/ruby/an-introduction-to-haml-and-sinatra/" >An Introduction to Haml and Sinatra </a></li>
<li><a href="http://rubysource.com/an-introduction-to-haml/" >An Introduction to Haml </a></li>
</ul>
<hr />
<h2>Authlogic</h2>
<blockquote><p>A simple, unobtrusive model based Ruby authentication solution. Authlogic is very flexible, it has a strong public API and a plethora of hooks to allow you to modify behavior and extend it.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/binarylogic/authlogic" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/160-authlogic" >Railscasts #160 Authlogic</a></li>
</ul>
<hr />
<h2>Shoulda</h2>
<blockquote><p>Shoulda is a gem that allows you to create more understandable tests for your Ruby application. Shoulda allows you to provide context to your tests enabling you to categorize tests according to a specific feature or scenario you&#8217;re testing.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/shoulda" >Github repo</a></li>
<li><a href="http://railstips.org/blog/archives/2009/02/21/shoulda-looked-at-it-sooner/" >Shoulda Looked At It Sooner</a></li>
</ul>
<hr />
<h2>factory_girl</h2>
<blockquote><p>factory_girl provides a framework and DSL for defining and using factories &#8211; less error-prone, more explicit, and all-around easier to work with than fixtures. It has straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/factory_girl" >Github repo</a></li>
<li><a href="http://www.agileweboperations.com/real-world-example-using-factory_girl-to-simplify-our-test-setup" >Using factory_girl to simplify our test setup</a></li>
</ul>
<hr />
<h2>RMagick</h2>
<blockquote><p>RMagick is an interface between the Ruby programming language and the ImageMagick and GraphicsMagick image processing libraries.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/rmagick/rmagick" >Github repo</a></li>
<li><a href="http://www.imagemagick.org/RMagick/doc/rvgtut.html" >Drawing with RVG</a></li>
</ul>
<hr />
<h2>Cancan</h2>
<blockquote><p>CanCan is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access and is decoupled from user roles. All permissions are stored in a single location and not duplicated across controllers, views, and database queries.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/ryanb/cancan" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/192-authorization-with-cancan" >Railscasts #192 Authorization with CanCan</a></li>
</ul>
<hr />
<h2>Nokogiri</h2>
<blockquote><p>Nokogiri is an HTML, XML, SAX, and Reader parser. Among Nokogiri’s many features is the ability to search documents via XPath or CSS3 selectors. Nokogiri parses and searches XML/HTML very quickly, and also has correctly implemented CSS3 selector support as well as XPath support.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/tenderlove/nokogiri" >Github repo</a></li>
<li><a href="http://www.engineyard.com/blog/2010/getting-started-with-nokogiri/" >Getting Started with Nokogiri</a></li>
<li><a href="http://railscasts.com/episodes/190-screen-scraping-with-nokogiri" >Railscasts #190 Screen Scraping with Nokogiri</a></li>
</ul>
<hr />
<h2>SASS</h2>
<blockquote><p>Sass makes CSS fun again. Sass is an extension of CSS3, adding nested rules, variables, mixins, selector inheritance, and more. It’s translated to well-formatted, standard CSS using the command line tool or a web-framework plugin.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/nex3/sass" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/268-sass-basics" >Railscasts #268 Sass Basics</a></li>
</ul>
<hr />
<h2>Formtastic</h2>
<blockquote><p>Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/justinfrench/formtastic/" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/184-formtastic-part-1" >Railscasts #184 Formtastic Part 1</a></li>
<li><a href="http://railscasts.com/episodes/185-formtastic-part-2" >Railscasts #185 Formtastic Part 2</a></li>
</ul>
<hr />
<h2>Capistrano</h2>
<blockquote><p>Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake) that allows you to define tasks, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPN&#8217;s and firewalls.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/capistrano/capistrano/" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/133-capistrano-tasks" >Railscasts #133 Capistrano Tasks</a></li>
</ul>
<hr />
<h2>Omniauth</h2>
<blockquote><p>OmniAuth is a Ruby authentication framework that provides a standardized interface to many different authentication providers such as Facebook, OpenID, and even traditional username and password.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/intridea/omniauth" >Github repo</a></li>
<li><a href="http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/" >How to Use Omniauth to Authenticate your Users </a></li>
<li><a href="http://railscasts.com/episodes/241-simple-omniauth" >Railscasts #241 Simple OmniAuth</a></li>
</ul>
<hr />
<h2>Bundler</h2>
<blockquote><p>Bundler is a tool that manages gem dependencies for your ruby application. It takes a gem manifest file and is able to fetch, download, and install the gems and all child dependencies specified in this manifest. It can manage any update to the gem manifest file and update the bundle&#8217;s gems accordingly. It also lets you run any ruby code in context of the bundle&#8217;s gem environment.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/carlhuda/bundler" >Github repo</a></li>
<li><a href="http://yehudakatz.com/2009/11/03/using-the-new-gem-bundler-today/" >Using the New Gem Bundler Today</a></li>
</ul>
<hr />
<h2>resque</h2>
<blockquote><p>Resque (pronounced like &#8220;rescue&#8221;) is a Redis-backed library for creating background jobs, placing those jobs on multiple queues, and processing them later. Resque is heavily inspired by DelayedJob.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/defunkt/resque" >Github repo</a></li>
<li><a href="http://feedproxy.google.com/~r/nettuts/~3/TQXIcZXrplk/rubylearning.com/blog/2010/11/08/do-you-know-resque/" >Do YOU know Resque?</a></li>
<li><a href="http://railscasts.com/episodes/271-resque" >Railscasts #271 Resque</a></li>
</ul>
<hr />
<h2>Jammit</h2>
<blockquote><p>Jammit is an industrial strength asset packaging library for Rails, providing both the CSS and JavaScript concatenation and compression that you&#8217;d expect, as well as YUI Compressor and Closure Compiler compatibility, ahead-of-time gzipping, built-in JavaScript template support, and optional Data-URI / MHTML image embedding.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="http://documentcloud.github.com/jammit/" >Github repo</a></li>
<li><a href="http://www.ruby-on-rails-outsourcing.com/articles/2011/07/21/using-jammit-in-rails/" >Using Jammit in Rails</a></li>
</ul>
<hr />
<h2>capybara</h2>
<blockquote><p>Capybara helps you test Rails and Rack applications by simulating how a real user would interact with your app. It is agnostic about the driver running your tests and comes with Rack::Test and Selenium support built in. </p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/jnicklas/capybara" >Github repo</a></li>
<li><a href="http://opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/" >Capybara (and Selenium) with RSpec &#038; Rails 3</a></li>
</ul>
<hr />
<h2>Active Merchant</h2>
<blockquote><p>Active Merchant is an extraction from the e-commerce system Shopify. Shopify&#8217;s requirements for a simple and unified API to access dozens of different payment gateways with very different internal APIs was the chief principle in designing the library. It was developed for usage in Ruby on Rails web applications and integrates seamlessly as a plugin but it also works excellently as a stand alone library.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/Shopify/active_merchant" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/144-active-merchant-basics" >Railscasts #144 Active Merchant Basics</a></li>
</ul>
<hr />
<h2>eventmachine</h2>
<blockquote><p>EventMachine implements a fast, single-threaded engine for arbitrary networkcommunications. It&#8217;s extremely easy to use in Ruby. EventMachine wraps all interactions with IP sockets, allowing programs to concentrate on the implementation of network protocols. It can be used to create both network servers and clients.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/eventmachine/eventmachine" >Github repo</a></li>
<li><a href="http://rubylearning.com/blog/2010/10/01/an-introduction-to-eventmachine-and-how-to-avoid-callback-spaghetti/" >An introduction to eventmachine, and how to avoid callback spaghetti</a></li>
</ul>
<hr />
<h2>mustache</h2>
<blockquote><p>Inspired by ctemplate, Mustache is a framework-agnostic way to renderlogic-free views.As ctemplates says, &#8220;It emphasizes separating logic from presentation:it is impossible to embed application logic in this templatelanguage.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/defunkt/mustache" >Github repo</a></li>
</ul>
<hr />
<h2>Passenger</h2>
<blockquote><p>Phusion Passenger™ — a.k.a. mod_rails or mod_rack — makes deployment of Ruby web applications, such as those built on the revolutionary Ruby on Rails web framework, a breeze.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/FooBarWidget/passenger" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/122-passenger-in-development" >Railscasts #122 Passenger in Development</a></li>
</ul>
<hr />
<h2>Chef</h2>
<blockquote><p>Chef is a system integration framework designed to bring the benefits of configuration management to your entire infrastructure. With Chef, you can manage your servers by writing code, not by running commands. </p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/opscode/chef" >Github repo</a></li>
<li><a href="http://www.themomorohoax.com/2010/07/31/ruby-chef-tutorial" >Getting started with Chef tutorial</a></li>
</ul>
<hr />
<h2>Thinking Sphinx</h2>
<blockquote><p>A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/freelancing-god/thinking-sphinx" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/120-thinking-sphinx-revised" >Railscasts #120 Thinking Sphinx</a></li>
</ul>
<hr />
<h2>Wrapping Up</h2>
<p>So those were some of the awesome gems I&#8217;ve found extremely useful when I&#8217;m whipping up a web app in Ruby. I&#8217;m a 100% sure I&#8217;m missing a metric butt load of others though. Let me know about your favorite gems in the comments below and thank you so much for reading!</p>
<p><a href="http://feedads.g.doubleclick.net/~a/T1U4VtEp3gsSkleXEB7McFlfotg/0/da"><img src="http://feedads.g.doubleclick.net/~a/T1U4VtEp3gsSkleXEB7McFlfotg/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/T1U4VtEp3gsSkleXEB7McFlfotg/1/da"><img src="http://feedads.g.doubleclick.net/~a/T1U4VtEp3gsSkleXEB7McFlfotg/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/TQXIcZXrplk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/articles/web-roundups/24-extremely-useful-ruby-gems-for-web-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>24 Extremely Useful Ruby Gems for Web Development</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/TQXIcZXrplk/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/TQXIcZXrplk/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 21:38:56 +0000</pubDate>
		<dc:creator>Siddharth</dc:creator>
				<category><![CDATA[gems]]></category>
		<category><![CDATA[must have]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Roundups]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=23863</guid>
		<description><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&#38;k=d754f1e9ba63a736ba8ff5ece958f7dd&#38;a=23863&#38;c=230202170' target='_blank'><img src='http://rss.buysellads.com/img.php?z=1260013&#38;k=d754f1e9ba63a736ba8ff5ece958f7dd&#38;a=23863&#38;c=230202170' border='0' alt='' /></a><p>One of the nicer things about developing on the Ruby platform is the sheer amount of meticulously categorized, highly reusable code wrapped up in the form of aptly named &#8216;gems&#8217;. </p>
<p>I&#8217;m sure you&#8217;ve heard of popular frameworks like Sinatra or the super popular Rails that ship as gems but you&#8217;re missing an entire spectrum of others that handle issues at a much lower level. Start using these and watch your productivity shoot through the roof!</p>
<p><span></span></p>
<hr />
<h2>A Quick Note</h2>
<p>I&#8217;m well aware that some of the gems listed here have Rails, or parts of Rails, as a dependency. That doesn&#8217;t mean that they are any less useful or need to be sneered at. </p>
<hr />
<h2>CarrierWave</h2>
<blockquote><p>Upload files in your Ruby applications, map them to a range of ORMs, store them on different backends. It works well with Rack based web applications, such as Ruby on Rails.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/jnicklas/carrierwave">Github repo</a></li>
<li><a href="http://www.engineyard.com/blog/2011/a-gentle-introduction-to-carrierwave/">A Gentle Introduction to CarrierWave</a></li>
</ul>
&#60;hr /<br />
<h2>Kaminari</h2>
<blockquote><p>Kaminari is a Scope &#38; Engine based, clean, powerful, customizable and sophisticated paginator. Kaminari supports multiple ORMs (ActiveRecord, Mongoid, MongoMapper) multiple web frameworks (Rails, Sinatra), and multiple template engines (ERB, Haml).</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/amatsuda/kaminari">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/254-pagination-with-kaminari">Railscasts #254 Pagination with Kaminari</a></li>
</ul>
<hr />
<h2>HAML</h2>
<blockquote><p>Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML that&#8217;s designed to express the structure of XHTML or XML documents in a non-repetitive, elegant, easy way, using indentation rather than closing tags and allowing Ruby to be embedded with ease. It was originally envisioned as a plugin for Ruby on Rails, but it can function as a stand-alone templating engine.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="http://haml-lang.com/">HAML website</a></li>
<li><a href="http://net.tutsplus.com/tutorials/ruby/an-introduction-to-haml-and-sinatra/">An Introduction to Haml and Sinatra </a></li>
<li><a href="http://rubysource.com/an-introduction-to-haml/">An Introduction to Haml </a></li>
</ul>
<hr />
<h2>Authlogic</h2>
<blockquote><p>A simple, unobtrusive model based Ruby authentication solution. Authlogic is very flexible, it has a strong public API and a plethora of hooks to allow you to modify behavior and extend it.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/binarylogic/authlogic">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/160-authlogic">Railscasts #160 Authlogic</a></li>
</ul>
<hr />
<h2>Shoulda</h2>
<blockquote><p>Shoulda is a gem that allows you to create more understandable tests for your Ruby application. Shoulda allows you to provide context to your tests enabling you to categorize tests according to a specific feature or scenario you&#8217;re testing.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/shoulda">Github repo</a></li>
<li><a href="http://railstips.org/blog/archives/2009/02/21/shoulda-looked-at-it-sooner/">Shoulda Looked At It Sooner</a></li>
</ul>
<hr />
<h2>factory_girl</h2>
<blockquote><p>factory_girl provides a framework and DSL for defining and using factories &#8211; less error-prone, more explicit, and all-around easier to work with than fixtures. It has straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/factory_girl">Github repo</a></li>
<li><a href="http://www.agileweboperations.com/real-world-example-using-factory_girl-to-simplify-our-test-setup">Using factory_girl to simplify our test setup</a></li>
</ul>
<hr />
<h2>RMagick</h2>
<blockquote><p>RMagick is an interface between the Ruby programming language and the ImageMagick and GraphicsMagick image processing libraries.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/rmagick/rmagick">Github repo</a></li>
<li><a href="http://www.imagemagick.org/RMagick/doc/rvgtut.html">Drawing with RVG</a></li>
</ul>
<hr />
<h2>Cancan</h2>
<blockquote><p>CanCan is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access and is decoupled from user roles. All permissions are stored in a single location and not duplicated across controllers, views, and database queries.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/ryanb/cancan">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/192-authorization-with-cancan">Railscasts #192 Authorization with CanCan</a></li>
</ul>
<hr />
<h2>Nokogiri</h2>
<blockquote><p>Nokogiri is an HTML, XML, SAX, and Reader parser. Among Nokogiri’s many features is the ability to search documents via XPath or CSS3 selectors. Nokogiri parses and searches XML/HTML very quickly, and also has correctly implemented CSS3 selector support as well as XPath support.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/tenderlove/nokogiri">Github repo</a></li>
<li><a href="http://www.engineyard.com/blog/2010/getting-started-with-nokogiri/">Getting Started with Nokogiri</a></li>
<li><a href="http://railscasts.com/episodes/190-screen-scraping-with-nokogiri">Railscasts #190 Screen Scraping with Nokogiri</a></li>
</ul>
<hr />
<h2>SASS</h2>
<blockquote><p>Sass makes CSS fun again. Sass is an extension of CSS3, adding nested rules, variables, mixins, selector inheritance, and more. It’s translated to well-formatted, standard CSS using the command line tool or a web-framework plugin.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/nex3/sass">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/268-sass-basics">Railscasts #268 Sass Basics</a></li>
</ul>
<hr />
<h2>Formtastic</h2>
<blockquote><p>Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/justinfrench/formtastic/">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/184-formtastic-part-1">Railscasts #184 Formtastic Part 1</a></li>
<li><a href="http://railscasts.com/episodes/185-formtastic-part-2">Railscasts #185 Formtastic Part 2</a></li>
</ul>
<hr />
<h2>Capistrano</h2>
<blockquote><p>Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake) that allows you to define tasks, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPN&#8217;s and firewalls.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/capistrano/capistrano/">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/133-capistrano-tasks">Railscasts #133 Capistrano Tasks</a></li>
</ul>
<hr />
<h2>Omniauth</h2>
<blockquote><p>OmniAuth is a Ruby authentication framework that provides a standardized interface to many different authentication providers such as Facebook, OpenID, and even traditional username and password.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/intridea/omniauth">Github repo</a></li>
<li><a href="http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/">How to Use Omniauth to Authenticate your Users </a></li>
<li><a href="http://railscasts.com/episodes/241-simple-omniauth">Railscasts #241 Simple OmniAuth</a></li>
</ul>
<hr />
<h2>Bundler</h2>
<blockquote><p>Bundler is a tool that manages gem dependencies for your ruby application. It takes a gem manifest file and is able to fetch, download, and install the gems and all child dependencies specified in this manifest. It can manage any update to the gem manifest file and update the bundle&#8217;s gems accordingly. It also lets you run any ruby code in context of the bundle&#8217;s gem environment.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/carlhuda/bundler">Github repo</a></li>
<li><a href="http://yehudakatz.com/2009/11/03/using-the-new-gem-bundler-today/">Using the New Gem Bundler Today</a></li>
</ul>
<hr />
<h2>resque</h2>
<blockquote><p>Resque (pronounced like &#8220;rescue&#8221;) is a Redis-backed library for creating background jobs, placing those jobs on multiple queues, and processing them later. Resque is heavily inspired by DelayedJob.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/defunkt/resque">Github repo</a></li>
<li><a href="rubylearning.com/blog/2010/11/08/do-you-know-resque/">Do YOU know Resque?</a></li>
<li><a href="http://railscasts.com/episodes/271-resque">Railscasts #271 Resque</a></li>
</ul>
<hr />
<h2>Jammit</h2>
<blockquote><p>Jammit is an industrial strength asset packaging library for Rails, providing both the CSS and JavaScript concatenation and compression that you&#8217;d expect, as well as YUI Compressor and Closure Compiler compatibility, ahead-of-time gzipping, built-in JavaScript template support, and optional Data-URI / MHTML image embedding.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="http://documentcloud.github.com/jammit/">Github repo</a></li>
<li><a href="http://www.ruby-on-rails-outsourcing.com/articles/2011/07/21/using-jammit-in-rails/">Using Jammit in Rails</a></li>
</ul>
<hr />
<h2>capybara</h2>
<blockquote><p>Capybara helps you test Rails and Rack applications by simulating how a real user would interact with your app. It is agnostic about the driver running your tests and comes with Rack::Test and Selenium support built in. </p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/jnicklas/capybara">Github repo</a></li>
<li><a href="http://opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/">Capybara (and Selenium) with RSpec &#38; Rails 3</a></li>
</ul>
<hr />
<h2>Active Merchant</h2>
<blockquote><p>Active Merchant is an extraction from the e-commerce system Shopify. Shopify&#8217;s requirements for a simple and unified API to access dozens of different payment gateways with very different internal APIs was the chief principle in designing the library. It was developed for usage in Ruby on Rails web applications and integrates seamlessly as a plugin but it also works excellently as a stand alone library.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/Shopify/active_merchant">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/144-active-merchant-basics">Railscasts #144 Active Merchant Basics</a></li>
</ul>
<hr />
<h2>eventmachine</h2>
<blockquote><p>EventMachine implements a fast, single-threaded engine for arbitrary networkcommunications. It&#8217;s extremely easy to use in Ruby. EventMachine wraps all interactions with IP sockets, allowing programs to concentrate on the implementation of network protocols. It can be used to create both network servers and clients.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/eventmachine/eventmachine">Github repo</a></li>
<li><a href="http://rubylearning.com/blog/2010/10/01/an-introduction-to-eventmachine-and-how-to-avoid-callback-spaghetti/">An introduction to eventmachine, and how to avoid callback spaghetti</a></li>
</ul>
<hr />
<h2>mustache</h2>
<blockquote><p>Inspired by ctemplate, Mustache is a framework-agnostic way to renderlogic-free views.As ctemplates says, &#8220;It emphasizes separating logic from presentation:it is impossible to embed application logic in this templatelanguage.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/defunkt/mustache">Github repo</a></li>
</ul>
<hr />
<h2>Passenger</h2>
<blockquote><p>Phusion Passenger™ — a.k.a. mod_rails or mod_rack — makes deployment of Ruby web applications, such as those built on the revolutionary Ruby on Rails web framework, a breeze.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/FooBarWidget/passenger">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/122-passenger-in-development">Railscasts #122 Passenger in Development</a></li>
</ul>
<hr />
<h2>Chef</h2>
<blockquote><p>Chef is a system integration framework designed to bring the benefits of configuration management to your entire infrastructure. With Chef, you can manage your servers by writing code, not by running commands. </p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/opscode/chef">Github repo</a></li>
<li><a href="http://www.themomorohoax.com/2010/07/31/ruby-chef-tutorial">Getting started with Chef tutorial</a></li>
</ul>
<hr />
<h2>Thinking Sphinx</h2>
<blockquote><p>A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/freelancing-god/thinking-sphinx">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/120-thinking-sphinx-revised">Railscasts #120 Thinking Sphinx</a></li>
</ul>
<hr />
<h2>Wrapping Up</h2>
<p>So those were some of the awesome gems I&#8217;ve found extremely useful when I&#8217;m whipping up a web app in Ruby. I&#8217;m a 100% sure I&#8217;m missing a metric butt load of others though. Let me know about your favorite gems in the comments below and thank you so much for reading!</p>
<p><a href="http://feedads.g.doubleclick.net/~a/WL_9th0GhnHNdGv6YG9E0n0IpcU/0/da"><img src="http://feedads.g.doubleclick.net/~a/WL_9th0GhnHNdGv6YG9E0n0IpcU/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/WL_9th0GhnHNdGv6YG9E0n0IpcU/1/da"><img src="http://feedads.g.doubleclick.net/~a/WL_9th0GhnHNdGv6YG9E0n0IpcU/1/di" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/TQXIcZXrplk" height="1">


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/TQXIcZXrplk/' rel='bookmark' title='Permanent Link: 24 Extremely Useful Ruby Gems for Web Development'>24 Extremely Useful Ruby Gems for Web Development</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/vq5s_MZEZLQ/' rel='bookmark' title='Permanent Link: Ruby for Newbies: Testing Web Apps with Capybara and Cucumber'>Ruby for Newbies: Testing Web Apps with Capybara and Cucumber</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/CZhjBpTuRuM/' rel='bookmark' title='Permanent Link: Recently in Web Development (January ’12 Edition)'>Recently in Web Development (January ’12 Edition)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23863&c=230202170' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=23863&c=230202170' border='0' alt='' /></a><p>One of the nicer things about developing on the Ruby platform is the sheer amount of meticulously categorized, highly reusable code wrapped up in the form of aptly named &#8216;gems&#8217;. </p>
<p>I&#8217;m sure you&#8217;ve heard of popular frameworks like Sinatra or the super popular Rails that ship as gems but you&#8217;re missing an entire spectrum of others that handle issues at a much lower level. Start using these and watch your productivity shoot through the roof!</p>
<p><span id="more-23863"></span></p>
<hr />
<h2>A Quick Note</h2>
<p>I&#8217;m well aware that some of the gems listed here have Rails, or parts of Rails, as a dependency. That doesn&#8217;t mean that they are any less useful or need to be sneered at. </p>
<hr />
<h2>CarrierWave</h2>
<blockquote><p>Upload files in your Ruby applications, map them to a range of ORMs, store them on different backends. It works well with Rack based web applications, such as Ruby on Rails.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/jnicklas/carrierwave" >Github repo</a></li>
<li><a href="http://www.engineyard.com/blog/2011/a-gentle-introduction-to-carrierwave/" >A Gentle Introduction to CarrierWave</a></li>
</ul>
<hr /<br />
<h2>Kaminari</h2>
<blockquote><p>Kaminari is a Scope &#038; Engine based, clean, powerful, customizable and sophisticated paginator. Kaminari supports multiple ORMs (ActiveRecord, Mongoid, MongoMapper) multiple web frameworks (Rails, Sinatra), and multiple template engines (ERB, Haml).</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/amatsuda/kaminari" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/254-pagination-with-kaminari" >Railscasts #254 Pagination with Kaminari</a></li>
</ul>
<hr />
<h2>HAML</h2>
<blockquote><p>Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML that&#8217;s designed to express the structure of XHTML or XML documents in a non-repetitive, elegant, easy way, using indentation rather than closing tags and allowing Ruby to be embedded with ease. It was originally envisioned as a plugin for Ruby on Rails, but it can function as a stand-alone templating engine.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="http://haml-lang.com/" >HAML website</a></li>
<li><a href="http://net.tutsplus.com/tutorials/ruby/an-introduction-to-haml-and-sinatra/" >An Introduction to Haml and Sinatra </a></li>
<li><a href="http://rubysource.com/an-introduction-to-haml/" >An Introduction to Haml </a></li>
</ul>
<hr />
<h2>Authlogic</h2>
<blockquote><p>A simple, unobtrusive model based Ruby authentication solution. Authlogic is very flexible, it has a strong public API and a plethora of hooks to allow you to modify behavior and extend it.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/binarylogic/authlogic" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/160-authlogic" >Railscasts #160 Authlogic</a></li>
</ul>
<hr />
<h2>Shoulda</h2>
<blockquote><p>Shoulda is a gem that allows you to create more understandable tests for your Ruby application. Shoulda allows you to provide context to your tests enabling you to categorize tests according to a specific feature or scenario you&#8217;re testing.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/shoulda" >Github repo</a></li>
<li><a href="http://railstips.org/blog/archives/2009/02/21/shoulda-looked-at-it-sooner/" >Shoulda Looked At It Sooner</a></li>
</ul>
<hr />
<h2>factory_girl</h2>
<blockquote><p>factory_girl provides a framework and DSL for defining and using factories &#8211; less error-prone, more explicit, and all-around easier to work with than fixtures. It has straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/factory_girl" >Github repo</a></li>
<li><a href="http://www.agileweboperations.com/real-world-example-using-factory_girl-to-simplify-our-test-setup" >Using factory_girl to simplify our test setup</a></li>
</ul>
<hr />
<h2>RMagick</h2>
<blockquote><p>RMagick is an interface between the Ruby programming language and the ImageMagick and GraphicsMagick image processing libraries.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/rmagick/rmagick" >Github repo</a></li>
<li><a href="http://www.imagemagick.org/RMagick/doc/rvgtut.html" >Drawing with RVG</a></li>
</ul>
<hr />
<h2>Cancan</h2>
<blockquote><p>CanCan is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access and is decoupled from user roles. All permissions are stored in a single location and not duplicated across controllers, views, and database queries.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/ryanb/cancan" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/192-authorization-with-cancan" >Railscasts #192 Authorization with CanCan</a></li>
</ul>
<hr />
<h2>Nokogiri</h2>
<blockquote><p>Nokogiri is an HTML, XML, SAX, and Reader parser. Among Nokogiri’s many features is the ability to search documents via XPath or CSS3 selectors. Nokogiri parses and searches XML/HTML very quickly, and also has correctly implemented CSS3 selector support as well as XPath support.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/tenderlove/nokogiri" >Github repo</a></li>
<li><a href="http://www.engineyard.com/blog/2010/getting-started-with-nokogiri/" >Getting Started with Nokogiri</a></li>
<li><a href="http://railscasts.com/episodes/190-screen-scraping-with-nokogiri" >Railscasts #190 Screen Scraping with Nokogiri</a></li>
</ul>
<hr />
<h2>SASS</h2>
<blockquote><p>Sass makes CSS fun again. Sass is an extension of CSS3, adding nested rules, variables, mixins, selector inheritance, and more. It’s translated to well-formatted, standard CSS using the command line tool or a web-framework plugin.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/nex3/sass" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/268-sass-basics" >Railscasts #268 Sass Basics</a></li>
</ul>
<hr />
<h2>Formtastic</h2>
<blockquote><p>Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/justinfrench/formtastic/" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/184-formtastic-part-1" >Railscasts #184 Formtastic Part 1</a></li>
<li><a href="http://railscasts.com/episodes/185-formtastic-part-2" >Railscasts #185 Formtastic Part 2</a></li>
</ul>
<hr />
<h2>Capistrano</h2>
<blockquote><p>Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake) that allows you to define tasks, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPN&#8217;s and firewalls.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/capistrano/capistrano/" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/133-capistrano-tasks" >Railscasts #133 Capistrano Tasks</a></li>
</ul>
<hr />
<h2>Omniauth</h2>
<blockquote><p>OmniAuth is a Ruby authentication framework that provides a standardized interface to many different authentication providers such as Facebook, OpenID, and even traditional username and password.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/intridea/omniauth" >Github repo</a></li>
<li><a href="http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/" >How to Use Omniauth to Authenticate your Users </a></li>
<li><a href="http://railscasts.com/episodes/241-simple-omniauth" >Railscasts #241 Simple OmniAuth</a></li>
</ul>
<hr />
<h2>Bundler</h2>
<blockquote><p>Bundler is a tool that manages gem dependencies for your ruby application. It takes a gem manifest file and is able to fetch, download, and install the gems and all child dependencies specified in this manifest. It can manage any update to the gem manifest file and update the bundle&#8217;s gems accordingly. It also lets you run any ruby code in context of the bundle&#8217;s gem environment.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/carlhuda/bundler" >Github repo</a></li>
<li><a href="http://yehudakatz.com/2009/11/03/using-the-new-gem-bundler-today/" >Using the New Gem Bundler Today</a></li>
</ul>
<hr />
<h2>resque</h2>
<blockquote><p>Resque (pronounced like &#8220;rescue&#8221;) is a Redis-backed library for creating background jobs, placing those jobs on multiple queues, and processing them later. Resque is heavily inspired by DelayedJob.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/defunkt/resque" >Github repo</a></li>
<li><a href="http://feedproxy.google.com/~r/nettuts/~3/TQXIcZXrplk/rubylearning.com/blog/2010/11/08/do-you-know-resque/" >Do YOU know Resque?</a></li>
<li><a href="http://railscasts.com/episodes/271-resque" >Railscasts #271 Resque</a></li>
</ul>
<hr />
<h2>Jammit</h2>
<blockquote><p>Jammit is an industrial strength asset packaging library for Rails, providing both the CSS and JavaScript concatenation and compression that you&#8217;d expect, as well as YUI Compressor and Closure Compiler compatibility, ahead-of-time gzipping, built-in JavaScript template support, and optional Data-URI / MHTML image embedding.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="http://documentcloud.github.com/jammit/" >Github repo</a></li>
<li><a href="http://www.ruby-on-rails-outsourcing.com/articles/2011/07/21/using-jammit-in-rails/" >Using Jammit in Rails</a></li>
</ul>
<hr />
<h2>capybara</h2>
<blockquote><p>Capybara helps you test Rails and Rack applications by simulating how a real user would interact with your app. It is agnostic about the driver running your tests and comes with Rack::Test and Selenium support built in. </p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/jnicklas/capybara" >Github repo</a></li>
<li><a href="http://opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/" >Capybara (and Selenium) with RSpec &#038; Rails 3</a></li>
</ul>
<hr />
<h2>Active Merchant</h2>
<blockquote><p>Active Merchant is an extraction from the e-commerce system Shopify. Shopify&#8217;s requirements for a simple and unified API to access dozens of different payment gateways with very different internal APIs was the chief principle in designing the library. It was developed for usage in Ruby on Rails web applications and integrates seamlessly as a plugin but it also works excellently as a stand alone library.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/Shopify/active_merchant" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/144-active-merchant-basics" >Railscasts #144 Active Merchant Basics</a></li>
</ul>
<hr />
<h2>eventmachine</h2>
<blockquote><p>EventMachine implements a fast, single-threaded engine for arbitrary networkcommunications. It&#8217;s extremely easy to use in Ruby. EventMachine wraps all interactions with IP sockets, allowing programs to concentrate on the implementation of network protocols. It can be used to create both network servers and clients.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/eventmachine/eventmachine" >Github repo</a></li>
<li><a href="http://rubylearning.com/blog/2010/10/01/an-introduction-to-eventmachine-and-how-to-avoid-callback-spaghetti/" >An introduction to eventmachine, and how to avoid callback spaghetti</a></li>
</ul>
<hr />
<h2>mustache</h2>
<blockquote><p>Inspired by ctemplate, Mustache is a framework-agnostic way to renderlogic-free views.As ctemplates says, &#8220;It emphasizes separating logic from presentation:it is impossible to embed application logic in this templatelanguage.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/defunkt/mustache" >Github repo</a></li>
</ul>
<hr />
<h2>Passenger</h2>
<blockquote><p>Phusion Passenger™ — a.k.a. mod_rails or mod_rack — makes deployment of Ruby web applications, such as those built on the revolutionary Ruby on Rails web framework, a breeze.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/FooBarWidget/passenger" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/122-passenger-in-development" >Railscasts #122 Passenger in Development</a></li>
</ul>
<hr />
<h2>Chef</h2>
<blockquote><p>Chef is a system integration framework designed to bring the benefits of configuration management to your entire infrastructure. With Chef, you can manage your servers by writing code, not by running commands. </p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/opscode/chef" >Github repo</a></li>
<li><a href="http://www.themomorohoax.com/2010/07/31/ruby-chef-tutorial" >Getting started with Chef tutorial</a></li>
</ul>
<hr />
<h2>Thinking Sphinx</h2>
<blockquote><p>A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.</p></blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/freelancing-god/thinking-sphinx" >Github repo</a></li>
<li><a href="http://railscasts.com/episodes/120-thinking-sphinx-revised" >Railscasts #120 Thinking Sphinx</a></li>
</ul>
<hr />
<h2>Wrapping Up</h2>
<p>So those were some of the awesome gems I&#8217;ve found extremely useful when I&#8217;m whipping up a web app in Ruby. I&#8217;m a 100% sure I&#8217;m missing a metric butt load of others though. Let me know about your favorite gems in the comments below and thank you so much for reading!</p>
<p><a href="http://feedads.g.doubleclick.net/~a/WL_9th0GhnHNdGv6YG9E0n0IpcU/0/da"><img src="http://feedads.g.doubleclick.net/~a/WL_9th0GhnHNdGv6YG9E0n0IpcU/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/WL_9th0GhnHNdGv6YG9E0n0IpcU/1/da"><img src="http://feedads.g.doubleclick.net/~a/WL_9th0GhnHNdGv6YG9E0n0IpcU/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/TQXIcZXrplk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/articles/web-roundups/24-extremely-useful-ruby-gems-for-web-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why you Should be using PHP’s PDO for Database Access</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/YAlDbDfVEFY/</link>
		<comments>http://feedproxy.google.com/~r/nettuts/~3/YAlDbDfVEFY/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 16:04:40 +0000</pubDate>
		<dc:creator>Erik Wurzer</dc:creator>
				<category><![CDATA[database]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=12059</guid>
		<description><![CDATA[Many PHP programmers learned how to access databases by using either the MySQL or MySQLi extensions. As of PHP 5.1, there&#8217;s a better way. PHP Data Objects (PDO) provide methods for prepared statements and working with objects that will make you f...


Related posts:<ol><li><a href='http://feedproxy.google.com/~r/nettuts/~3/NpMMwdIZ2D8/' rel='bookmark' title='Permanent Link: Build an Admin Panel with the Fuel PHP Framework'>Build an Admin Panel with the Fuel PHP Framework</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/p_LFYwxIinY/' rel='bookmark' title='Permanent Link: Rapid Application Prototyping in PHP Using a Micro Framework'>Rapid Application Prototyping in PHP Using a Micro Framework</a></li>
<li><a href='http://feedproxy.google.com/~r/nettuts/~3/cCcgjNI0wlQ/' rel='bookmark' title='Permanent Link: Testing your PHP Codebase with EnhancePHP'>Testing your PHP Codebase with EnhancePHP</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<a href='http://rss.buysellads.com/click.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=12059&c=1827114289' ><img src='http://rss.buysellads.com/img.php?z=1260013&k=d754f1e9ba63a736ba8ff5ece958f7dd&a=12059&c=1827114289' border='0' alt='' /></a><p>Many PHP programmers learned how to access databases by using either the MySQL or MySQLi extensions. As of PHP 5.1, there&#8217;s a better way. <a href="http://www.php.net/manual/en/intro.pdo.php">PHP Data Objects</a> (PDO) provide methods for prepared statements and working with objects that will make you far more productive!</p>
<p><span id="more-12059"></span></p>
May of 2010
<hr />
<h2>PDO Introduction</h2>
<blockquote>
<p>
&#8220;PDO &#8211; PHP Data Objects &#8211; is a database access layer providing a uniform method of access to multiple databases.&#8221; </p>
</blockquote>
<p>It doesn&#8217;t account for database-specific syntax, but can allow for the process of switching databases and platforms to be fairly painless, simply by switching the connection string in many instances.</p>
<div class="tutorial_image"><img src="http://d2o0t5hpnwv4c1.cloudfront.net/693_pdo/pdo-to-db.png" alt="PDO - db abstraction layer" width="600" height="125" /></div>
<p>This tutorial isn&#8217;t meant to be a complete how-to on SQL. It&#8217;s written primarily for people currently using the mysql or mysqli extension to help them make the jump to the more portable and powerful PDO.</p>
<h3>Database Support</h3>
<p>The extension can support any database that a PDO driver has been written for. At the time of this writing, the following database drivers are available:</p>
<ul>
<li>PDO_DBLIB ( FreeTDS / Microsoft SQL Server / Sybase )</li>
<li>PDO_FIREBIRD ( Firebird/Interbase 6 )</li>
<li>PDO_IBM ( IBM DB2 )</li>
<li>PDO_INFORMIX ( IBM Informix Dynamic Server )</li>
<li>PDO_MYSQL ( MySQL 3.x/4.x/5.x )</li>
<li>PDO_OCI ( Oracle Call Interface )</li>
<li>PDO_ODBC ( ODBC v3 (IBM DB2, unixODBC and win32 ODBC) )</li>
<li>PDO_PGSQL ( PostgreSQL )</li>
<li>PDO_SQLITE ( SQLite 3 and SQLite 2 )</li>
<li>PDO_4D ( 4D )</li>
</ul>
<p>All of these drivers are not necessarily available on your system; here&#8217;s a quick way to find out which drivers you have:</p>
<pre name="code" class="php">
print_r(PDO::getAvailableDrivers());
</pre>
<hr />
<h2>Connecting</h2>
<p>Different databases may have slightly different connection methods. Below, the method to connect to some of the most popular databases are shown. You&#8217;ll notice that the first three are identical, other then the database type &#8211; and then SQLite has its own syntax.</p>
<div class="tutorial_image"><img src="http://d2o0t5hpnwv4c1.cloudfront.net/693_pdo/connection_string.png" alt="Connection String" width="600" height="125" /></div>
<pre name="code" class="php">
try {
  # MS SQL Server and Sybase with PDO_DBLIB
  $DBH = new PDO("mssql:host=$host;dbname=$dbname, $user, $pass");
  $DBH = new PDO("sybase:host=$host;dbname=$dbname, $user, $pass");

  # MySQL with PDO_MYSQL
  $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);

  # SQLite Database
  $DBH = new PDO("sqlite:my/database/path/database.db");
}
catch(PDOException $e) {
    echo $e-&gt;getMessage();
}
</pre>
<p>Please take note of the try/catch block &#8211; you should always wrap your PDO operations in a try/catch, and use the exception mechanism &#8211; more on this shortly. Typically you&#8217;re only going to make a single connection &#8211; there are several listed to show you the syntax. $DBH stands for &#8216;database handle&#8217; and will be used throughout this tutorial.</p>
<p>You can close any connection by setting the handle to null.</p>
<pre name="code" class="php">
# close the connection
$DBH = null;
</pre>
<p>You can get more information on database specific options and/or connection strings for other databases from <a href="http://www.php.net/manual/en/pdo.drivers.php">PHP.net</a>.</p>
<hr />
<h2>Exceptions and PDO</h2>
<p>PDO can use exceptions to handle errors, which means anything you do with PDO should be wrapped in a try/catch block. You can force PDO into one of three error modes by setting the error mode attribute on your newly created database handle. Here&#8217;s the syntax:</p>
<pre name="code" class="php">
$DBH-&gt;setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
$DBH-&gt;setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$DBH-&gt;setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
</pre>
<p>No matter what error mode you set, an error connecting will always produce an exception, and creating a connection should always be contained in a try/catch block.</p>
<h3>PDO::ERRMODE_SILENT</h3>
<p>This is the default error mode. If you leave it in this mode, you&#8217;ll have to check for errors in the way you&#8217;re probably used to if you used the mysql or mysqli extensions. The other two methods are more ideal for DRY programming.</p>
<h3>PDO::ERRMODE_WARNING</h3>
<p>This mode will issue a standard PHP warning, and allow the program to continue execution. It&#8217;s useful for debugging.</p>
<h3>PDO::ERRMODE_EXCEPTION</h3>
<p>This is the mode you should want in most situations. It fires an exception, allowing you to handle errors gracefully and hide data that might help someone exploit your system. Here&#8217;s an example of taking advantage of exceptions:</p>
<pre name="code" class="php">
# connect to the database
try {
  $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
  $DBH-&gt;setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

  # UH-OH! Typed DELECT instead of SELECT!
  $DBH-&gt;prepare('DELECT name FROM people');
}
catch(PDOException $e) {
    echo "I'm sorry, Dave. I'm afraid I can't do that.";
    file_put_contents('PDOErrors.txt', $e-&gt;getMessage(), FILE_APPEND);
}
</pre>
<p>There&#8217;s an intentional error in the select statement; this will cause an exception. The exception sends the details of the error to a log file, and displays a friendly (or not so friendly) message to the user.</p>
<hr />
<h2>Insert and Update</h2>
<p>Inserting new data, or updating existing data is one of the more common database operations. Using PDO, this is normally a two-step process. Everything covered in this section applies equally to both UPDATE and INSERT operations.</p>
<div class="tutorial_image"><img src="http://d2o0t5hpnwv4c1.cloudfront.net/693_pdo/prepare-bind-execute.png" alt="2 to 3 step insert and update" width="600" height="125" /></div>
<p>Here&#8217;s an example of the most basic type of insert:</p>
<pre name="code" class="php">
# STH means "Statement Handle"
$STH = $DBH-&gt;prepare("INSERT INTO folks ( first_name ) values ( 'Cathy' )");
$STH-&gt;execute();
</pre>
<p>You could also accomplish the same operation by using the exec() method, with one less call. In most situations, you&#8217;re going to use the longer method so you can take advantage of prepared statements. Even if you&#8217;re only going to use it once, using prepared statements will help protect you from SQL injection attacks.</p>
<h3>Prepared Statements</h3>
<blockquote class="pullquote pqRight">
<p>Using prepared statements will help protect you from SQL injection.</p>
</blockquote>
<p>A prepared statement is a precompiled SQL statement that can be executed multiple times by sending just the data to the server. It has the added advantage of automatically making the data used in the placeholders safe from SQL injection attacks.</p>
<p>You use a prepared statement by including placeholders in your SQL. Here&#8217;s three examples: one without placeholders, one with unnamed placeholders, and one with named placeholders.</p>
<pre name="code" class="php">
# no placeholders - ripe for SQL Injection!
$STH = $DBH-&gt;("INSERT INTO folks (name, addr, city) values ($name, $addr, $city)");

# unnamed placeholders
$STH = $DBH-&gt;("INSERT INTO folks (name, addr, city) values (?, ?, ?);

# named placeholders
$STH = $DBH-&gt;("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
</pre>
<p>You want to avoid the first method; it&#8217;s here for comparison. The choice of using named or unnamed placeholders will affect how you set data for those statements.</p>
<h3>Unnamed Placeholders</h3>
<pre name="code" class="php">
# assign variables to each place holder, indexed 1-3
$STH-&gt;bindParam(1, $name);
$STH-&gt;bindParam(2, $addr);
$STH-&gt;bindParam(3, $city);

# insert one row
$name = "Daniel"
$addr = "1 Wicked Way";
$city = "Arlington Heights";
$STH-&gt;execute();

# insert another row with different values
$name = "Steve"
$addr = "5 Circle Drive";
$city = "Schaumburg";
$STH-&gt;execute();
</pre>
<p>There are two steps here. First, we assign variables to the various placeholders (lines 2-4). Then, we assign values to those placeholders and execute the statement. To send another set of data, just change the values of those variables and execute the statement again.</p>
<p>Does this seem a bit unwieldy for statements with a lot of parameters? It is. However, if your data is stored in an array, there&#8217;s an easy shortcut:</p>
<pre name="code" class="php">
# the data we want to insert
$data = array('Cathy', '9 Dark and Twisty Road', 'Cardiff');

$STH = $DBH-&gt;("INSERT INTO folks (name, addr, city) values (?, ?, ?);
$STH-&gt;execute($data);
</pre>
<p>That&#8217;s easy!</p>
<p>The data in the array applies to the placeholders in order. $data[0] goes into the first placeholder, $data[1] the second, etc. However, if your array indexes are not in order, this won&#8217;t work properly, and you&#8217;ll need to re-index the array.</p>
<h3>Named Placeholders</h3>
<p>You could probably guess the syntax, but here&#8217;s an example:</p>
<pre name="code" class="php">
# the first argument is the named placeholder name - notice named
# placeholders always start with a colon.
$STH-&gt;bindParam(':name', $name);
</pre>
<p>You can use a shortcut here as well, but it works with associative arrays. Here&#8217;s an example:</p>
<pre name="code" class="php">
# the data we want to insert
$data = array( 'name' =&gt; 'Cathy', 'addr' =&gt; '9 Dark and Twisty', 'city' =&gt; 'Cardiff' );

# the shortcut!
$STH = $DBH-&gt;("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
$STH-&gt;execute($data);
</pre>
<p>The keys of your array do not need to start with a colon, but otherwise need to match the named placeholders. If you have an array of arrays you can iterate over them, and simply call the execute with each array of data.</p>
<p>Another nice feature of named placeholders is the ability to insert objects directly into your database, assuming the properties match the named fields. Here&#8217;s an example object, and how you&#8217;d perform your insert:</p>
<pre name="code" class="php">
# a simple object
class person {
    public $name;
    public $addr;
    public $city;

    function __construct($n,$a,$c) {
        $this-&gt;name = $n;
        $this-&gt;addr = $a;
        $this-&gt;city = $c;
    }
    # etc ...
}

$cathy = new person('Cathy','9 Dark and Twisty','Cardiff');

# here's the fun part:
$STH = $DBH-&gt;("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
$STH-&gt;execute((array)$cathy);
</pre>
<p>By casting the object to an array in the execute, the properties are treated as array keys.</p>
<hr />
<h2>Selecting Data</h2>
<div class="tutorial_image"><img src="http://d2o0t5hpnwv4c1.cloudfront.net/693_pdo/fetch_obj_array.png" alt="Fetch data into arrays or objects" width="600" height="125" /></div>
<p>Data is obtained via the ->fetch(), a method of your statement handle. Before calling fetch, it&#8217;s best to tell PDO how you&#8217;d like the data to be fetched. You have the following options:</p>
<ul>
<li><strong>PDO::FETCH_ASSOC:</strong> returns an array indexed by column name</li>
<li><strong>PDO::FETCH_BOTH (default):</strong> returns an array indexed by both column name and number</li>
<li><strong>PDO::FETCH_BOUND:</strong> Assigns the values of your columns to the variables set with the ->bindColumn() method</li>
<li><strong>PDO::FETCH_CLASS:</strong> Assigns the values of your columns to properties of the named class. It will create the properties if matching properties do not exist</li>
<li><strong>PDO::FETCH_INTO:</strong> Updates an existing instance of the named class</li>
<li><strong>PDO::FETCH_LAZY</strong>: Combines PDO::FETCH_BOTH/PDO::FETCH_OBJ, creating the object variable names as they are used</li>
<li><strong>PDO::FETCH_NUM:</strong> returns an array indexed by column number</li>
<li><strong>PDO::FETCH_OBJ:</strong> returns an anonymous object with property names that correspond to the column names</li>
</ul>
<p>In reality, there are three which will cover most situations: FETCH_ASSOC, FETCH_CLASS, and FETCH_OBJ. In order to set the fetch method, the following syntax is used:</p>
<pre name="code" class="php">
$STH-&gt;setFetchMode(PDO::FETCH_ASSOC);
</pre>
<p>You can also set the fetch type directly within the ->fetch() method call.</p>
<h3>FETCH_ASSOC</h3>
<p>This fetch type creates an associative array, indexed by column name. This should be quite familiar to anyone who has used the mysql/mysqli extensions. Here&#8217;s an example of selecting data with this method:</p>
<pre name="code" class="php">
# using the shortcut -&gt;query() method here since there are no variable
# values in the select statement.
$STH = $DBH-&gt;query('SELECT name, addr, city from folks');

# setting the fetch mode
$STH-&gt;setFetchMode(PDO::FETCH_ASSOC);

while($row = $STH-&gt;fetch()) {
    echo $row['name'] . "\n";
    echo $row['addr'] . "\n";
    echo $row['city'] . "\n";
}
</pre>
<p>The while loop will continue to go through the result set one row at a time until complete.</p>
<h3>FETCH_OBJ</h3>
<p>This fetch type creates an object of std class for each row of fetched data. Here&#8217;s an example:</p>
<pre name="code" class="php">
# creating the statement
$STH = $DBH-&gt;query('SELECT name, addr, city from folks');

# setting the fetch mode
$STH-&gt;setFetchMode(PDO::FETCH_OBJ);

# showing the results
while($row = $STH-&gt;fetch()) {
    echo $row-&gt;name . "\n";
    echo $row-&gt;addr . "\n";
    echo $row-&gt;city . "\n";
}
</pre>
<h3>FETCH_CLASS</h3>
<blockquote class="pullquote pqRight"><p>
  The properties of your object are set BEFORE the constructor is called. This is important.
</p></blockquote>
<p>This fetch method allows you to fetch data directly into a class of your choosing. When you use FETCH_CLASS, the properties of your object are set BEFORE the constructor is called. Read that again, it&#8217;s important. If properties matching the column names don&#8217;t exist, those properties will be created (as public) for you.</p>
<p>This means if your data needs any transformation after it comes out of the database, it can be done automatically by your object as each object is created.</p>
<p>As an example, imagine a situation where the address needs to be partially obscured for each record. We could do this by operating on that property in the constructor. Here&#8217;s an example:</p>
<pre name="code" class="php">
class secret_person {
    public $name;
    public $addr;
    public $city;
    public $other_data;

    function __construct($other = '') {
        $this-&gt;address = preg_replace('/[a-z]/', 'x', $this-&gt;address);
        $this-&gt;other_data = $other;
    }
}
</pre>
<p>As data is fetched into this class, the address has all its lowercase <em>a-z</em> letters replaced by the letter <em>x</em>. Now, using the class and having that data transform occur is completely transparent:</p>
<pre name="code" class="php">
$STH = $DBH-&gt;query('SELECT name, addr, city from folks');
$STH-&gt;setFetchMode(PDO::FETCH_CLASS, 'secret_person');

while($obj = $STH-&gt;fetch()) {
    echo $obj-&gt;addr;
}
</pre>
<p>If the address was &#8217;5 Rosebud,&#8217; you&#8217;d see &#8217;5 Rxxxxxx&#8217; as your output. Of course, there may be situations where you want the constructor called before the data is assigned. PDO has you covered for this, too.</p>
<pre name="code" class="php">
$STH-&gt;setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'secret_person');
</pre>
<p>Now, when you repeat the previous example with this fetch mode (PDO::FETCH_PROPS_LATE) the address will NOT be obscured, since the constructor was called and the properties were assigned.</p>
<p>Finally, if you really need to, you can pass arguments to the constructor when fetching data into objects with PDO:</p>
<pre name="code" class="php">
$STH-&gt;setFetchMode(PDO::FETCH_CLASS, 'secret_person', array('stuff'));
</pre>
<p>If you need to pass different data to the constructor for each object, you can set the fetch mode inside the fetch method:</p>
<pre name="code" class="php">
$i = 0;
while($rowObj =  $STH-&gt;fetch(PDO::FETCH_CLASS, 'secret_person', array($i))) {
    // do stuff
    $i++
}
</pre>
<hr />
<h2>Some Other Helpful Methods</h2>
<p>While this isn&#8217;t meant to cover everything in PDO (it&#8217;s a huge extension!) there are a few more methods you&#8217;ll want to know in order to do basic things with PDO.</p>
<pre name="code" class="php">
$DBH-&gt;lastInsertId();
</pre>
<p>The ->lastInsertId() method is always called on the database handle, not statement handle, and will return the auto incremented id of the last inserted row by that connection.</p>
<pre name="code" class="php">
$DBH-&gt;exec('DELETE FROM folks WHERE 1');
$DBH-&gt;exec("SET time_zone = '-8:00'");
</pre>
<p>The ->exec() method is used for operations that can not return data other then the affected rows. The above are two examples of using the exec method.</p>
<pre name="code" class="php">
$safe = $DBH-&gt;quote($unsafe);
</pre>
<p>The ->quote() method quotes strings so they are safe to use in queries. This is your fallback if you&#8217;re not using prepared statements.</p>
<pre name="code" class="php">
$rows_affected = $STH-&gt;rowCount();
</pre>
<p>The ->rowCount() method returns an integer indicating the number of rows affected by an operation. In at least one known version of PDO, according to [this bug report](http://bugs.php.net/40822) the method does not work with select statements. If you&#8217;re having this problem, and can&#8217;t upgrade PHP, you could get the number of rows with the following:</p>
<pre name="code" class="php">
$sql = "SELECT COUNT(*) FROM folks";
if ($STH = $DBH-&gt;query($sql)) {
    # check the row count
    if ($STH-&gt;fetchColumn() &gt; 0) {

    # issue a real select here, because there's data!
    }
    else {
        echo "No rows matched the query.";
    }
}
</pre>
<hr />
<h2>Conclusion</h2>
<p>I hope this helps some of you migrate away from the mysql and mysqli extensions. What do you think? Are there any of you out there who might make the switch?</p>
<p><a href="http://feedads.g.doubleclick.net/~a/ppNqYB8T00X6XvNcIVIFJshZflQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/ppNqYB8T00X6XvNcIVIFJshZflQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/ppNqYB8T00X6XvNcIVIFJshZflQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/ppNqYB8T00X6XvNcIVIFJshZflQ/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=YAlDbDfVEFY:lVI0hoxtFTQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=YAlDbDfVEFY:lVI0hoxtFTQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=YAlDbDfVEFY:lVI0hoxtFTQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=YAlDbDfVEFY:lVI0hoxtFTQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=YAlDbDfVEFY:lVI0hoxtFTQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=YAlDbDfVEFY:lVI0hoxtFTQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=YAlDbDfVEFY:lVI0hoxtFTQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=YAlDbDfVEFY:lVI0hoxtFTQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/YAlDbDfVEFY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

