Friday, August 31, 2012

A Quick Preview of Building Widgets with the jQuery UI 1.9 Framework

If you've been following along with the development of jQuery UI 1.9, you'll see there are a lot of changes coming. With the first release candidate out on August 24th, we might be closing in on a final release soon. Many of the existing widgets are being refactored to use the new plumbing being created in the heart of the framework: the widget factory. For developers using the UI library, there's some new widgets, better accessibility support, and localization capabilities. For widget builders, the widget factory has some great new features that makes building widgets a whole lot easier.

The two biggest changes to the factory API is the addition of _super() for inheritance chaining and _on()/_off() for simplified event binding. By adding these two concepts, the frameworks handles a lot of the complexities related to building proxies, fixing scope, and cleaning up references.

In 1.8, you had to do this to call the original destroy function defined in the base object:


destroy: function()
{
$.Widget.prototype.destroy.call(arguments);
}


Now, in 1.9, you only need to call _super():


_destroy: function()
{
this._super();
}


Now, you don't need to know the parent in the inheritance chain, deal with passing arguments, or any of the other messy detail because its all handled in the framework.

The addition of the private _on/_off event helpers is probably one of the features I'm most happy to see. Getting the scope corrected so you had a reference to the widget instance was cumbersome. Plus, you had to keep track of all your bound events and clean them up so you didn't leak memory. In 1.8, you might have done something like this to fix the scope:


_create: function()
{
...
this.element.on('click',
$.proxy(function(e)
{
// "this" refers to the widget instance
// e.currentTarget is the DOM element we bound the event to
// e.target is the actual DOM element clicked
alert(e.currentTarget.id + ' caught click event which is a ' + this.widgetName);
}, this));
...
}


This might not look that bad, but it doesn't take care of unbinding the event when the widget is destroyed. In 1.9, things are much simpler when using _on():


_create: function()
{
...
// this.element is assumed to be the target
// when nothing is passed as the first arg to _on()
this._on({
click: function(e)
{
// "this" refers to the widget instance
// e.currentTarget is the DOM element we bound the event to
// e.target is the actual DOM element clicked
alert(e.currentTarget.id + ' caught click event which is a ' + this.widgetName);
}
});
...
}


Internally, _on() corrects the scope and stores a reference to your binding so when the widget is destroyed, everything is cleaned up. What I really like about this setup is I can organize all my event handlers in one place in the widget definition and bind them all during initialization. It makes for nice, readable code:


_create: function()
{
...
this._on({
click: this._handleClick,
mouseover: this._handleMouseOver,
...
});

// Bind based on a selector
this._on('selector', {
keydown: this._handleTheOtherKey,
...
});
...
}
...

// Define event handlers ...
_handleClick: function(e)
{
alert(e.currentTarget.id + ' caught click event which is a ' + this.widgetName);
},
... more handlers ...



Other convenience features included by default in widgets created from the framework include a _delay() method which will call a function after a specified timeout with the correct scope. This method is then used in the base object to add default fade in/out effects for show and hide.

Additionally, widgets can call _hoverable() and _focusable() the identify which elements should have this behavior applied. The framework will automatically add/remove the UI theme classes to these elements.

I'm greatly anticipating the final release of the 1.9 UI library. I've already started using it in my development to help find issues and start taking advantage of all the new features.

Thursday, August 30, 2012

Javascript Patterns

I found this site while digging through the jQuery UI 1.9 source.


A JavaScript pattern and antipattern collection that covers function patterns, jQuery patterns, jQuery plugin patterns, design patterns, general patterns, literals and constructor patterns, object creation patterns, code reuse patterns, DOM and browser patterns (upcoming).




I think its a really good study for anyone working with Javascript in general or, specifically, jQuery. Sometimes being able to decompose problems into a set of patterns that you can name makes it a) easier to design and b) easier to communicate with fellow programmers.

Wednesday, August 29, 2012

MSYS/MinGW or virtualized Linux?

As I've been working with jQuery and learning about the development environment and various resources available, I've found that many of them use a lot of command line utilities to perform various tasks. Most recently, I've been utilizing Git for source control. The Git for Windows install includes a copy of MSYS so you can perform the command line tasks you might do in Linux. As I've been browsing GitHub for other jQuery projects of interest, I've noticed many of them use Grunt to handle file concatenation, compression, and testing. Grunt require Node.js to work and is installed as a global package. The Windows install of Node.js also includes a copy of MSYS. Next, I wanted to work with some markdown tools which are written in Ruby. The Windows Ruby Devkit has another copy of MSYS. So now I have 3 copies of MSYS and no consistent path setup so everything works nicely from the command line (I've modified my path environment variable quite a bit to make everything run properly). MSYS is great, having a bash like shell in Windows is exactly what I need - I can run my Windows apps, use my favorite editors, and still have a powerful scripting environment. However, there's just no centralization or consistency. If MSYS had a package manager like aptitude or yum to pull all these tools down and install them in one consistent spot, then things would be much better.

So I decided another solution was needed to give me the shell access I wanted but still have access to my local files and allow me to work with my favorite editors in Window - all on the machine I currently own.

I decide to try a virtualized Linux install to accomplish my objective. If it worked, I'd get those qualities and have a sandbox to try out some other technologies without cluttering up my main computer. A friend suggested I look at VirtualBox. Its free, so I went to https://www.virtualbox.org/wiki/Downloads, downloaded a copy and installed it.

The following instructions will get you a VirtualBox running on a Windows host with a Debian Squeeze guest mounted to your local filesystem, SSH access via PuTTY, and some starting tools like Git, Node.js, and Grunt.

Creating a new VirtualBox instance is pretty straight forward. My instructions are specifically for Debian Squeeze. I'm not going to step through all the wizard screens. There are several key points that need to be setup though so the remainder of this tutorial works. Here's some screenshots of those places and a quick description:



I selected VDI as the type and used a Fixed size instead of Variable.  Fixed will allocate all the space immediately instead of adding it as needed.



I chose a Bridged Adapter.  You can dig through the help to learn about the other ones and decide how much work you want to put into getting each setup.  This one was good enough for me so I went ahead with using it.



I had an ISO of the Debian install so I added it as a storage device so I could mount it inside a session and boot to it.



This is where you'll add the folder(s) you want to be able to access inside your virtual environment.  These will be mounted to the Linux file system later in this tutorial.

Once you have your setting ready, launch the instance, mount the installation ISO/CD and boot into the Linux install.  After completing that process, you should be able to login as root.  If you have problems getting this far, look at the VirtualBox documentation, it has some pretty good information to help work through some of the issues.

At this point, you should be logged into the console as root. I'm also assuming that during the Debian install, you added the user "vmuser".

We're going to start by ensuring aptitude is pointing to the correct source and is fully up-to-date:



## As root (from console)
## Remove any references to cdrom from here:
vi /etc/apt/sources.list

## Make sure everything is up-to-date
apt-get update
apt-get upgrade



Now, check if you have an SSH server running. The Debian install gives you the option to add this, but in case you missed it:


## Make sure you have SSH server installed
aptitude show openssh-server
Package: openssh-server
State: installed

## If not, install it
apt-get install openssh-server


Next, we want to be able to do things as root from vmuser, so install sudo and add vmuser to that group:


## Install sudo and add vmuser to the sudo group
apt-get install sudo
usermod -aG sudo vmuser


Now you want to mount folders from your host computer to the guest's filesystem:



## Mount the share
mkdir /mnt/share
mount -f vboxsf myshare /mnt/share

## Add it to fstab so its there each time
## you boot your VM:
vi /etc/fstab

## Add this line to the end of the fstab file:
myshare /mnt/share vboxsf



Now, determine your IP. With the Bridge Adapter, you will be assigned a real IP usable on your network via DHCP:


## Find your IP
ifconfig

eth0 Link encap:Ethernet HWaddr 08:00:27:b2:65:42
inet addr:10.0.2.189 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:feb2:6542/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:38883 errors:0 dropped:0 overruns:0 frame:0
TX packets:13938 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:31179355 (29.7 MiB) TX bytes:2285447 (2.1 MiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:560 (560.0 B) TX bytes:560 (560.0 B)



My IP is 10.0.2.189 so, in Windows, open PuTTY and start an SSH session to 10.0.2.189. Login as vmuser and start setting up your environment. I'll begin by creating a symbolic link to the share in my home directory:


## Open PuTTY and start an SSH connection to the VM's IP
## Login as vmuser

## Add a symbolic link to the share for convenience
ln -s /mnt/share share


You can now navigate through the directories in your share. Changes you make from Windows will be visable here - changes you make inside your Linux install will be visible in Windows.

Now, install Git:


## Install some tools!
## Install Git
sudo apt-get install git


Additionally, install Grunt. It requires Node.js, however, its not a package in the Squeeze distribution. We could pull it from Sid, but might as well just compile it from source:


## Debian Sid has Node.js as a package
## Going to follow the instruction from
## https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
## to compile it locally and install (as root):

sudo bash

apt-get install make python g++
mkdir ~/nodejs && cd $_
wget -N http://nodejs.org/dist/node-latest.tar.gz
tar xzvf node-latest.tar.gz && cd `ls -rd node-v*`
./configure
make install

## Clean up
cd ~
rm -Rf nodejs

## Now that Node.js is installed.
## Grunt can be added via Npm:
## https://github.com/cowboy/grunt

npm install -g grunt


I've been using this setup now for a while now and its been working out great. I've even installed some other tools, run other web services, and seamlessly move back and forth between my Windows environment and my Linux environment - all on the same computer.

Tuesday, August 28, 2012

Using Jekyll to Create a Site on GitHub

I wanted to try building a site on GitHub using Jekyll. I opted to utilize the Jekyll-Bootstrap (JB) as a starting point. I utilized these references as I worked on tweaking the site for my purposes.

The concept behind Jekyll is to build a templated site and then "compile" it into individual static HTML files. The input files can be a variety of formats which is convenient for writing blog posts or other pages. The primary target is for creating a blog style site. However, I already have blog, but wanted a site to link to with full demos of the projects/tutorials I write about here. Coupled with my desire to learn how to leverage GitHub and the various parts of its ecosystem, I decided that it was a perfect opportunity to learn by using Jekyll to generate this sandbox/demo site.

Since the setup is geared towards blog posts, it took a little bit to figure out how to organize my pages and get them to appear where I wanted them. There were two primary issues I had to solve:

  1. Create a hierarchy of pages organized by project and then by individual demos

  2. Leverage the tagging concept outside of blog posts. It did not want to work out-of-the-box for pages


The first problem was solvable by learning how JB was rendering pages. The default setup has a navigation menu that links to pages. If you open up _includes/themes/twitter/default.html you'll find this bit of code (if you're working with a different template, go to that directory instead):


<div class="navbar">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="{{ HOME_PATH }}">{{ site.title }}</a>
<ul class="nav">
{% assign pages_list = site.pages %}
{% assign group = 'navigation' %}
{% include JB/pages_list %}
</ul>
</div>
</div>
</div>


The include JB/pages_list is what's rendering the menu. Its setting up two variables which will probably be used inside that template to do something. So opened _includes/JB/pages_list and the helpful comments indicated that the optional group variable will filter pages that have the specified "group" variable in the YAML Front Matter block.

Now I had what I need to organize my site. I created a projects directory where I placed an index.md file and set the group to 'navigation'. This brought my projects page into the menu. On this page, I added the above code again but with group = 'projects'

... content ...
<ul class="nav">
{% assign pages_list = site.pages %}
{% assign group = 'projects' %}
{% include JB/pages_list %}
</ul>
... more content ...



Now I had a list of individual projects that I've worked on. I created a directory per project inside the projects folder and added another index.md file with the same code again. However, this time I assigned the specific project name as the group so all the related files will appear in the list:

... content ...
<ul class="nav">
{% assign pages_list = site.pages %}
{% assign group = 'colorbox' %}
{% include JB/pages_list %}
</ul>
... more content ...


The order of the lists is the same as the ordering in the filesystem. If you can map everything into this basic nomenclature, then you'll be up and running fairly quickly.

The second item is more complicated. Jekyll is not adding the tags in the YAML to the site.tags variable. As a result, the default JB tags.html page had nothing on it even though I had created some tags. I had to dig through the source to determine its absence. Technically, I really don't need the tags, but thought it would be nice. Plus, now, I can write a Jekyll plugin to do it!

I can't claim full credit for figuring out how to do this. I found an example on Brian Clapper's Brizzled blog. His hacking is more than I needed - I just wanted Jekyll to do the same thing is does for its posts. But he gave the starting point of how to pull this off.

What I'm essentially going to do is copy the code from the post class and monkeypatch the page class with that code. I'll then be able to reference the tags the same for pages as I would for posts. I added the _plugins/page.rb file and put this code in it:


module Jekyll

# Extensions to the Jekyll Page class.

class Page

# Override initialize to also
# parse the tags from the page
# chain original call

attr_accessor :tags

alias orig_initialize initialize
def initialize(site, base, dir, name)
orig_initialize(site, base, dir, name)
self.tags = self.data.pluralized_array("tag", "tags")
end

end
end


Now I thought I was really smart ... but it didn't work.

So I did some more digging and realized that the above enhancement only added the tags to the page object not to the site object. So, I needed to add a little more customization. The Site class has a site_payload function which generates the site object. Part of that process includes creating the hash of individual tags to their related posts. However, this function only performed this operation on posts. So I needed an equivalent function that performed this on pages. Below is my _plugin/site.rb file which adds the page_attr_hash function and then proxies the site_payload function to merge the results from page_attr_hash into the tags object. Since I called the original site_payload, it will contain a "tags" hash for posts. I want to merge the page's tags hash with it so, if I do happen to add posts, those tags will still work:


module Jekyll

class Site

def page_attr_hash(page_attr)
# Build a hash map based on the specified page attribute ( page attr =>
# array of pages )
hash = Hash.new { |hsh, key| hsh[key] = Array.new }
self.pages.each { |p| p.send(page_attr.to_sym).each { |t| hash[t] << p } }
hash
end

alias orig_site_payload site_payload
def site_payload
h = orig_site_payload

payload = h["site"]
payload["tags"] = payload["tags"].merge(page_attr_hash('tags'))
h["site"] = payload

h
end

end
end


Now, when I load the tags page, I have all my pages organized by tags.

So I thought I was good - I checked everything in and went to GitHub to see the fruits of my labor and ... nothing ... my tags were not there. Turns out, GitHub pages disable plugins when rendering your site. The solution: add all my site's source to a different repository, generate the site locally, and push that content to my GitHub pages repository.

Final Thoughts


Jekyll is a great tool for leveraging the GitHub platform and building a static site. If you're goal is to publish a blog style site, it works with little effort as most of the functionality is centered around publishing blog posts. If you want similar features for your pages, you will need to customize Jekyll accordingly. Jekyll-Bootstrap is a great way to spring-board your site by adding time saving tools and predefined layout templates. You don't need JB but it does have some useful pieces that will save you the effort of writing them yourself. Additionally, this setup works for Personal Pages. If you want to make it work for Project Pages, you'll have to do some more work to coordinate the changes to the gh_pages branch of your project.

If you'd like to see any of the source for the site or the actual site itself, you can access it on GitHub at github.com/bseth99/sandbox/.

Monday, August 27, 2012

Getting Jekyll installed on Debian Squeeze

I've been trying to learn Jekyll to build my personal site on GitHub.  Getting it setup on Debian proved to be more difficult than I expected.

Installing Ruby was easy.  It didn't install the gem package manager so I needed to add it separately.  Save yourself some time and run (as root):


apt-get install ruby rubygems


This also adds the gem installer.

Then run:


gem install jekyll


Now, all the docs related to Jekyll say run:


jekyll --server


And everything will be great.  However, on Debian, it can't find the program. 

Gems seem to not install in (or near) your $PATH.  You have to add /var/lib/gems/X.Y/bin (in my case X.Y == 1.8, replace with what ever version you installed) to your $PATH.  The best place is /etc/profile so all users get it.  You can also symbolic link it to you ~/bin directory since that's in your path too. 

Regardless, the Internet didn't give the answer - I finally found it in a bug report as a bothersome install location.  It was closed as expected behavior (I still find it bothersome). 

So Internet, do your magic and find my post so someone's life might be a little bit easier...

Sunday, August 26, 2012

Tinkering with jQuery UI Widgets Part 1: Making Multiple Widgets Work Together

After spending some time digging into the features of the jQuery UI library. I'm really impressed with how its been constructed. The base class is a great factory for creating new widgets which are just jQuery plugins with some default structure to guide you in the "best practices" direction to building stateful, highly functional widgets. Additionally, the library has been decomposed into widgets that provide very specific behaviors that can be easily combined to create more complex functionality. This is made possible by the fact that you can chain widget calls together just like any other jQuery method/plugins and add the behaviors you need to your target element.

As an example, say I have a box on my page that I want to drag around and make resizable. Out-of-the-box, jQuery UI provides two widgets to enable this behavior - Draggable and Resizable. You can easily combined these two widgets on your box element to enable both behaviors:


$('#mybox')
.resizable()
.draggable();


Pretty easy, right? Now you can add more functionality - even responding to critical events defined by each widget:


$('#mybox')
.resizable({
maxHeight: 500,
maxWidth: 500,
minHeight: 100,
minWidth: 100
})
.draggable({
grid: [50, 50],
stop: function (e, ui)
{
alert('done dragging!');
}
});


As you can see, just by combining some of the built-in UI widgets, you can build some pretty sophisticated logic just by combining two (or more) widgets together.

In part 2, we'll explore how to encapsulate this new behavior into a custom widget: ColorBox.

Friday, August 24, 2012

Javascript: parseInt() quirky or misused?

Ensuring you are using the correctly typed variables before using the + operator is important in Javascript. If your intent was to numerically sum them and your variables are strings, you'll end up with a concatenated string. Nothing is worse than having c = a + b in your code and spend an hour debugging only to find out that a and b were concatenated as a string instead of numerically summed. In a loosely type language, this is one place where a different, explicit operator is needed for string concatenation. Using + for both numeric addition and string concatenation causes nothing but headaches. Its one feature that I like about PHP - . is used as the string concatenation operator and + is for summing numbers. Types are converted to enable either operation as needed.

However, in Javascript, we must ensure a variable is the correct type before trying to sum two values. A common approach is to use the parseInt() function to ensure you're working with numbers instead of strings. However, it seems that few (and at one point in time myself included) are unaware that the function actually takes a second argument. Omit it and you may get unexpected results in some situations:



// This is OK
parseInt('1');
parseInt('8');
parseInt('9');
parseInt('10');
parseInt('11');

// This is fine until 8 and 9
parseInt('01');
parseInt('08');
parseInt('09'); // This will be zero
parseInt('10'); // This will be zero
parseInt('11');

// This is OK
parseInt('01', 10);
parseInt('08', 10);
parseInt('09', 10);
parseInt('10', 10);
parseInt('11', 10);

// These are NaN
parseInt('ABC');
parseInt('ABC1');

// This is 1
parseInt('1ABC');



You can tinker with this code on JSFiddle if you'd like to see it in action.

So way the odd behavior for '08' and '09'? In the description of parseInt() on w3schools, it states the behavior of the function if the second parameter is omitted from the call:
If the radix parameter is omitted, JavaScript assumes the following:

  • If the string begins with "0x", the radix is 16 (hexadecimal)

  • If the string begins with "0", the radix is 8 (octal). This feature is deprecated

  • If the string begins with any other value, the radix is 10 (decimal)



So everything is fine until you start having leading zeros in your strings. As soon as the string has a leading zero, it starts doing strange things.

Additionally, if the string can not be parsed to a number (no leading numbers in the string), NaN is returned so you can't just blindly sum the result without checking for that exception.

As alternative to parseInt(), type coercion can be used to force a variable to a numerically typed value:


(+ ''); // equals 0
(+ '1'); // equals 1
(+ '8'); // equals 8
(+ '08'); // equals 8
(+ 'ABC'); // equals NaN
(+ 'ABC1'); // equals NaN
(+ '1ABC'); // equals NaN


Here, everything works fine as long as the string is really a full number in string form. If anything is non-numeric, the result will be NaN. The exception seems to be empty string evaluates to zero. parseInt() will return NaN for empty string.

So how do you ensure you always get a number no matter what value is in the variable? parseInt() is easy to fix by adding 10 as the second parameter. However, I'm lazy and tend to forget it and it doesn't solve the problem of getting NaN in certain situations. Coercion avoids the function call entirely, but is unable to handle any alpha characters.

One solution is just to create a wrapper function:



myParseInt(s)
{
var t = parseInt(s, 10);
return isNaN(t) ? 0 : t;
}


This solution assumes you always want to work with base 10 values and the cases that result in NaN will be mapped to zero. If you want to parse hexadecimal strings, you can still use the built-in parseInt() as-is.

A slightly more aggressive approach is to proxy parseInt() and modify its behavior. Here is a blended approach that will use parseInt() if a radix is provided or just use type coercion. A final check is performed to ensure a numeric value is always returned (paste this into the JSFiddle provided earlier to see the change):



(function ()
{
var _parseInt = parseInt;

parseInt = function(s, r)
{
var t = (r ? _parseInt(s, r) : (+ s));
return (isNaN(t) ? 0 : t);
}

})();



This should only be used when you know it won't cause issues with other code that might be checking for NaN and branching differently than on a zero value.

Regardless of how you choose to handle the process of converting strings to numbers, knowing how each approach behaves will enable you to correctly handle each case and apply the correct logic to obtain the desired result.

Thursday, August 23, 2012

Choosing a Javascript Library - jQuery vs YUI3

Back in 2006, I started tinkering with the YUI javascript library and set out to build a one page UI framework that I could use to build data-driven web applications.  I was inspired by how well Yahoo Mail was able to mimic certain qualities of a desktop mail client and decided that it was time to move away from page-to-page navigation with some AJAX enhancements to a one-page approach with all dynamic DOM manipulations to create that desktop feel.  I looked at several Javascript libraries that normalized AJAX and DOM access/manipulation but ultimately decide that YUI had what I needed plus some nice basic widgets to build around.

Fast-forward several years and YUI 2 is now EOL and being replaced by YUI 3.  As I've now written a lot of code with the YUI 2 library and various other enhancements of my own,  it was time to re-evaluate what I wanted to do based on my prior experience.  For several years now, I've been monitoring the maturity of the jQuery library - both in breadth of functionality and the community of developers - and am impressed by its approach and growth.

Its lightweight and does not force you into any predefined framework pattern.  The core library has just the right amount of functionality to effectively work with the DOM, handle events, and manage AJAX requests.  With the addition of jQuery UI, you get the foundation necessary to build highly dynamic web sites using best practices to extend jQuery with complex, stateful widgets.  Adding the third-party developed jQueryMX library adds further rigor to your application design with a well thought out set of MVC base classes and functionality.

You will find many similarities between YUI 3 and jQuery.  Both libraries have very similar methods to select DOM elements, iterate over those collections, bind events, and manage AJAX connections.  YUI 3 also establishes a widget design pattern and MVC base classes out-of-the-box.  YUI 3 is clearly influenced by jQuery's approach.  The original methods present in YUI 2 are basically gone replaced by a much more desirable set of methods for working with the DOM.

I see two major differences between jQuery and YUI 3:

  1. YUI 3 seems to be attempting to be a complete Javascript based framework with well defined patterns for constructing widgets and wiring them together to interact with the user.  The jQuery library does not attempt to assume what type of application you're building or dictate how you should build that application.  Instead, it provides the basics and then allows you or others to build on that foundation (the addition of jQuery UI does add some formal patterns to widget development - its clear that some order is needed to establish good behaviors).

  2. jQuery seems to have a much larger contributing community.  On GitHub, jQuery has 2091 forks and 16,350 watchers while YUI 3 has 399 forks and 1892 watchers.  YUI 3 does have a Gallery which contains community contributed enhancements which must be approved by the YUI Team.  jQuery also has a plugin site (or did - as of this time its being redesigned) but does not require approval (you will have to follow some guidelines to get published).


Ultimately, I've decided that I want a library that establishes a basic framework to extend it without too many assumptions about how that should happen and has a large community building enhancements to extend it.  However, everyone has a different problem to solve and a different approach to solving that problem.  Use you're own judgement to assess and pick what will work best for your project.