Posted on

Rails Mountain Lion Errors

Mountain Lion 10.8

The Problem

If you’re starting rails server on Mountain Lion you might be encountering errors like these:

$ thin start
>> Using rack adapter
/Library/Ruby/Gems/1.8/gems/rmagick-2.13.1/lib/RMagick2.bundle: dlopen(/Library/Ruby/Gems/1.8/gems/rmagick-2.13.1/lib/RMagick2.bundle, 9): Library not loaded: /usr/lib/libltdl.7.dylib (LoadError)
  Referenced from: /Library/Ruby/Gems/1.8/gems/rmagick-2.13.1/lib/RMagick2.bundle
  Reason: image not found - /Library/Ruby/Gems/1.8/gems/rmagick-2.13.1/lib/RMagick2.bundle
	from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.2/lib/active_support/dependencies.rb:251:in `require'
	from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.2/lib/active_support/dependencies.rb:236:in `load_dependency'
	from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.2/lib/active_support/dependencies.rb:251:in `require'
	from /Library/Ruby/Gems/1.8/gems/rmagick-2.13.1/lib/rmagick.rb:11
	from /Library/Ruby/Gems/1.8/gems/bundler-1.0.18/lib/bundler/runtime.rb:68:in `require'
	from /Library/Ruby/Gems/1.8/gems/bundler-1.0.18/lib/bundler/runtime.rb:68:in `require'
	from /Library/Ruby/Gems/1.8/gems/bundler-1.0.18/lib/bundler/runtime.rb:66:in `each'
	from /Library/Ruby/Gems/1.8/gems/bundler-1.0.18/lib/bundler/runtime.rb:66:in `require'
	from /Library/Ruby/Gems/1.8/gems/bundler-1.0.18/lib/bundler/runtime.rb:55:in `each'
	from /Library/Ruby/Gems/1.8/gems/bundler-1.0.18/lib/bundler/runtime.rb:55:in `require'
	from /Library/Ruby/Gems/1.8/gems/bundler-1.0.18/lib/bundler.rb:120:in `require'
	from config/application.rb:9
	from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
	from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
	from config/environment.rb:2
	from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
	from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
	from config.ru:3
	from /Library/Ruby/Gems/1.8/gems/rack-1.4.1/lib/rack/builder.rb:51:in `instance_eval'
	from /Library/Ruby/Gems/1.8/gems/rack-1.4.1/lib/rack/builder.rb:51:in `initialize'
	from config.ru:1:in `new'
	from config.ru:1

The Cause

Mountain Lion removes the /usr/lib/libltdl.7.dylib.

The Solution

1) Install XCode 4.4+ through the app store
2) Install the XCode Command Line Tools

XCode > Preferences > Downloads > Components


3) Make sure you have homebrew installed and run this:

brew uninstall imagemagick
brew install --fresh imagemagick

4) Then to recompile the gem against the new version of imagemagick:

gem pristine rmagick

Follow me on Twitter: @pdenya

Posted on

Audibly: Audio Recording for Everyday Use

Audibly

We’ve developed a utility for quickly and easily creating and sharing recordings from your mac desktop.

Audibly is a menubar application that lets you record audio anytime by holding a hotkey.
When you’re done recording the audio will be available on your desktop (like a screenshot).
We also upload the recording to the cloud and put a shareable link to it on your clipboard.

Check it out at audibly.nextmarvel.net.

Posted on

An iOS match game for my kids

Ocean Match

There are a lot of games in the app store available for entertaining young kids but the majority of them aren’t ideal for kids or parents. I built a simple match game for my kids that addresses a few common shortcomings of existing kids apps.

Important differences for me as a parent

  • No way for kids to get out of the game other than the home button. There are no ads, promos, in app purchase buttons, settings, start buttons, additional screens, or anything else. If the app is open all you see is the game board ready to play.
  • No sounds. This app does not make noise even when the kids are adjusting the volume and flipping the sound/vibration toggle.
  • It’s a universal app so you don’t need to buy it again on the ipad.
  • Has pictures of real animals and entertains the kids. Ok, maybe this one isn’t a differentiator.

I did my best to make it worth the 99 cents.


Ocean Match!



Animal Match!


Posted on

15-30 Second Page Loads in Rails 3 Development Environment

Original Photo: http://www.flickr.com/photos/ralphandjenny/2485969363

The Problem

Rails development environment has incredibly slow page loads while production is fast. And when I say slow, I mean 15-30 seconds. Rails server will likely report the page as loading in under a second but it’s still taking 30 secons to show up.

The Cause

DNS problems. Nothing to do with rails, this is just the environment that’s not working. If your DNS is working correctly and you’re seeing page loads a bit faster than what I’m describing (3-8 seconds) check out rails-dev-boost

The Solution

Verify that you can ping the domain name you’re browsing to. I had some problem with my /etc/hosts file that a little bit of experimentation resolved.

If you found this helpful you might like to follow me on Twitter

Posted on

Everyday Grep

grep ss 2

Grep is well known and commonly used command line search function that far too many people aren’t taking advantage of. The purpose of this article is to give technically inclined folks easy to follow examples to speed up work. I’ll also discuss speed concerns because no one wants to wait 8 seconds for a search to finish.

Getting your feet wet: single file search

Searching a single file for a string is about as simple as it gets so lets jump right into it. The syntax is:

grep [search string] [file]

Here’s an example

grep "header" log/dev.log

Responds with:

Dec 09 17:16:24 Send header "Content-Type: text/plain; charset=utf-8"
Dec 09 17:16:24 "Pragma: public: 1"
Dec 09 17:16:24 Send header "Content-Type: image/png"

Case insensitive search

Adding the -i flag to grep makes it search without case sensitivity

grep -i "HeAdEr" log/dev.log

Responds with:

Dec 09 17:16:24 Send header "Content-Type: text/plain; charset=utf-8"
Dec 09 17:16:24 "Pragma: public: 1"
Dec 09 17:16:24 Send header "Content-Type: image/png"

Learning something useful: recursive search

The previous example could be done casually in a text editor. Searching all the files in a directory is also doable but from some text editors (the ones I use at least) it’s not quite as easy. The -r flag indicates recursion but I’ll be combining it with the -i flag in the examples below to retain case insensitive search.

grep -ri "iboutlet" .  

Responds with:

./InspectAppDelegate.h:@property (nonatomic, retain) IBOutlet UIWindow *window;
./InspectAppDelegate.h:@property (nonatomic, retain) IBOutlet TemplateListTableViewController *templateListController;
./InspectAppDelegate.h:@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
./LoginViewController.h:    IBOutlet UITextField *usernameField;
./LoginViewController.h:    IBOutlet UITextField *passwordField;    
./LoginViewController.h:    IBOutlet UITextField *subdomainField;        
./LoginViewController.h:@property (nonatomic, retain) IBOutlet UITextField *usernameField;
./LoginViewController.h:@property (nonatomic, retain) IBOutlet UITextField *passwordField;
./LoginViewController.h:@property (nonatomic, retain) IBOutlet UITextField *subdomainField;
./ProjectAddViewController.h:@property (nonatomic, retain) IBOutlet UITextField *projectNameField;
./ProjectDetailsImageViewController.h:@property (nonatomic, retain) IBOutlet UIImageView *imageView;
./ProjectDetailsImageViewController.h:@property (nonatomic, retain) IBOutlet UIImage *image;
./ProjectDetailsTextEditViewController.h:@property (nonatomic, retain) IBOutlet UITextView *answerField;
./ProjectDetailsTextEditViewController.h:@property (nonatomic, retain) IBOutlet UILabel *fieldName;

Special cases: getting a list of files

Recursive search is great but it can give you tons of results from the same file which isn’t ideal in all cases (eg: log files). Getting a list of the files which contain matches rather than a list of matches can be done by adding the -l flag

grep -ril "iboutlet" .

Responds with:

./InspectAppDelegate.h
./LoginViewController.h
./ProjectAddViewController.h
./ProjectDetailsImageViewController.h
./ProjectDetailsTextEditViewController.h

But that’s not all: additional flags

Grep is a mature and powerful tool and as expected it has far more options and uses than i’m going to go into here but I do feel compelled to list a few more flags that may be helpful.

-A 20

Prints 20 (or whatever number you specify) lines after each match.

-B 20

Same thing as -A but before each match instead of after.

-C 40

Same thing as -B 20 -A 20 (C for context).

-n  or --line-number   

Adds the line number of the match to the results.

-v or --invert-match     

Invert match (get all the results that don’t match the pattern provided).

A need for speed: making common searches faster within project directories

If you’re on OS X and you’re looking for a fast case insensitive search within a directory that shows only file names (grep -ril “pattern”) you should be using mdfind (spotlight on command line).

mdfind -onlyin . "iboutlet"

Responds with:

/Users/pauldenya/full/path/to/LoginViewController.h
/Users/pauldenya/full/path/to/ProjectDetailsTextEditViewController.h
/Users/pauldenya/full/path/to/ProjectDetailsImageViewController.h
/Users/pauldenya/full/path/to/ProjectAddViewController.h

For those times when you’re not working on OS X a pruned find function can work wonders for improving slow search in large project directories. The idea is that in many situations, not all directories under the project directory need to be searched so we come up with a list of directories that do need to be searched and put them in a function in your profile.

#this goes in ~/.bashrc or /etc/profile
function projectfind() {
    grep -ril "$1" /path/to/project/search/me
    grep -ril "$1"  /path/to/project/search/here/too
    grep -ril "$1"  /path/to/project/web/js
}
projectfind "iboutlet"

This approach is project specific which isn’t great if you’re often switching between or starting new projects. You could change “/path/to/project/” to “./” but then you’d always need to be in the root project directory for search to work. The solution here is to pipe files to search to grep and use grep to prune the list in line. Here’s an example for a function that will search within the current directory but ignore log files and css directories:

#this goes in ~/.bashrc or /etc/profile
function myfind() {
   find . | grep -vE "\.log$|css" | xargs grep "$1" 
}

You can add additional logic by adding to OR clauses to the regex used in the first grep statement or adding additional grep statements.

Posted on

Passing additional data to jQuery.Ajax callbacks

Screenshot from: http://www.loadinfo.net/

jQuery makes it effortless to make additional data available from within the jQuery.ajax callbacks (success | error | complete) because within the callbacks, this refers to the object that was passed to jQuery.ajax. Knowing this, you can provide extra parameters that jQuery.ajax will ignore but you can access later. For example:

$.ajax({
	url: ‘/‘,
	pudding: ‘chocolate’,
	success: function() {
		alert(this.pudding); //alerts chocolate
	}
});
Posted on

Brew Install Postgresql on OS X Lion

Lion

The Problem

If you’re installing postgresql via homebrew on Lion you might be encountering errors like these:

psql: could not connect to server: Permission denied
	Is the server running locally and accepting
	connections on Unix domain socket "/var/pgsql_socket/.s.PGSQL.5432"?
createuser: could not connect to database postgres: could not connect to server: Permission denied
	Is the server running locally and accepting
	connections on Unix domain socket "/var/pgsql_socket/.s.PGSQL.5432"?

The Cause

Lion comes with a version of postgres already installed and uses those binaries by default. In general you can get around this by using the full path to the homebrew postgres binaries but there may be still issues with other programs.

The Solution

If a quick fix is all you’re looking for, run this:

curl http://nextmarvel.net/blog/downloads/fixBrewLionPostgres.sh | sh

Here’s the code the previous line runs. To sum up, it moves your OS X default postgres binaries into an archive folder and symlinks the homebrew versions in place of them.

BREW_POSTGRES_DIR=`brew info postgres | awk '{print $1"/bin"}' | grep "/postgresql/"`
LION_POSTGRES_DIR=`which postgres | xargs dirname`
LION_PSQL_DIR=`which psql | xargs dirname`

sudo mkdir -p $LION_POSTGRES_DIR/archive
sudo mkdir -p $LION_PSQL_DIR/archive

for i in `ls $BREW_POSTGRES_DIR`
do
	if [ -f $LION_POSTGRES_DIR/$i ] 
	then
		sudo mv $LION_POSTGRES_DIR/$i $LION_POSTGRES_DIR/archive/$i
		sudo ln -s $BREW_POSTGRES_DIR/$i $LION_POSTGRES_DIR/$i
	fi
	
	if [ -f $LION_PSQL_DIR/$i ] 
	then
		sudo mv $LION_PSQL_DIR/$i $LION_PSQL_DIR/archive/$i
		sudo ln -s $BREW_POSTGRES_DIR/$i $LION_PSQL_DIR/$i
	fi	
done

If you enjoyed this post, follow me on Twitter

Posted on

Compiling the MySQL2 gem on OS X with any version of MAMP

Screen shot 2011-07-11 at 2.20.02 PM

There are a number of solutions for compiling mysql with MAMP on OS X but there’s a simpler solution.

  1. Download and install MySQL (any version, I did 5.5.14 which is the latest as of this writing). Choose the “Mac OS X ver. 10.6 (x86, 64-bit), DMG Archive” option.
  2. From Terminal, run the following in your rails app’s directory:

    sudo gem install mysql2 --version=0.2.6 -- --with-mysql-dir=/usr/local/mysql
    GEMDIR=`dirname \`bundle show rails\``
    sudo install_name_tool -change libmysqlclient.18.dylib /usr/local/mysql/lib/libmysqlclient.18.dylib ${GEMDIR}/mysql2-0.2.6/lib/mysql2/mysql2.bundle
  3. In your database.yml file point to MAMP’s mysql.sock file:

    socket: /Applications/MAMP/tmp/mysql/mysql.sock
Posted on

Link Shortening on Twitter.com

twitterformac

I love using the twitter web interface whenever i’m not at my primary computer but after getting used to the way Twitter for Mac handles link shortening I’m often frustrated with Twitter.com.

Twitter for Mac

The letter count of a tweet with a long link in Twitter for Mac displays what the character count will be after the link is shortened and allows me to post as is.

Twitter for Mac's Link Shortening

Twitter.com

On Twitter.com, a tweet with a long link displays the current character count rather than taking into account that the link will be shortened. There is also no way to shorten a link with the default interface and I’m unable to post because the combination of my un-shortened link and the text in my tweet is over 140 characters.

Twitter.com's Link Shortening

The Solution

I wrote a quick bookmarklet that will parse a tweet in the twitter.com interface and open it in a share window with the shortened link. While this isn’t an ideal solution it’s much faster than going to bit.ly, shortening the link and going back to twitter.com to tweet it.

The Code

var r = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
var theurl = "";
var thetext = "";
$($(".twitter-anywhere-tweet-box-editor").val().split(" ")).each(function(i,v) {
	if(r.test(v)) {
		theurl = v;
	} else {
		thetext += v + " ";
	}
});

window.location.href="http://twitter.com/share?text="+escape(thetext)+"&url="+escape(theurl);

The Bookmarklet

Twitter Shorten

Posted on

One line Javascript browser detection

cup_liquid

Browser Detection Sucks

There are a lot of good arguments for avoiding browser detection and they’re 100% correct in most cases. Anyone who’s ever seen the “Browser version does not meet minimum requirements” message while in a capable browser will agree that filtering based on user-agent should be stopped.

Browser Detection Rocks

That being said, minor or last-minute bug fixes often call for some quick javascript browser detection. There are quite a few well written, full featured libraries that accomplish this task well but when I need to check whether or not the user is in IE6 for something minor I’d rather not load an extra class.

Here are a few browser and operating system detection one liners that have served me well over the years.


//Browsers
var IE6 = false /*@cc_on || @_jscript_version < 5.7 @*/
var IE7 = (document.all && !window.opera && window.XMLHttpRequest && navigator.userAgent.toString().toLowerCase().indexOf('trident/4.0') == -1) ? true : false;
var IE8 = (navigator.userAgent.toString().toLowerCase().indexOf('trident/4.0') != -1);
var IE9 = navigator.userAgent.toString().toLowerCase().indexOf("trident/5")>-1;
var IE10 = navigator.userAgent.toString().toLowerCase().indexOf("trident/6")>-1;
var SAFARI = (navigator.userAgent.toString().toLowerCase().indexOf("safari") != -1) && (navigator.userAgent.toString().toLowerCase().indexOf("chrome") == -1);
var FIREFOX = (navigator.userAgent.toString().toLowerCase().indexOf("firefox") != -1);
var CHROME = (navigator.userAgent.toString().toLowerCase().indexOf("chrome") != -1);
var MOBILE_SAFARI = ((navigator.userAgent.toString().toLowerCase().indexOf("iphone")!=-1) || (navigator.userAgent.toString().toLowerCase().indexOf("ipod")!=-1) || (navigator.userAgent.toString().toLowerCase().indexOf("ipad")!=-1)) ? true : false;

//Platforms
var MAC = (navigator.userAgent.toString().toLowerCase().indexOf("mac")!=-1) ? true: false;
var WINDOWS = (navigator.appVersion.indexOf("Win")!=-1) ? true : false;
var LINUX = (navigator.appVersion.indexOf("Linux")!=-1) ? true : false;
var UNIX = (navigator.appVersion.indexOf("X11")!=-1) ? true : false;