You've got a lot of Gal

Yet another blog about Ruby, Rails, Javascript, Apple, Malteses and Shih-Tzus by Gal Steinitz

This site is completely static. It was last generated with Octopress and Jekyll on Sep 02, 2013 and hosted on github pages.

Jasmine Debugging: Actual Line Numbers in Error Messages

If you’re using Pivotal Labs’ excellent Jasmine javascript BDD testing framework you may run into this. With Rails 3 Asset Pipeline, jasmine concatenates your js files into a single file - and therefore the line numbers on your stack traces are not useful (they will show the concatenated line numbers).

For example, you may see an error from the concatenated application.js line #17,403 instead of home.js line #15. To get jasmine to reference the javascript files individually and thereby provide more informative error messages, add this in config/initializers/jasmine.rb:

1
2
3
4
5
6
7
8
9
module Jasmine
  class Config
    def src_files
      Rails.application.assets["application"].dependencies.map do |asset|
        "assets/" + asset.logical_path
      end
    end
  end
end

NOTE: This only works if your application.js requires all your javascript files and doesn’t include any javascript itself.

“Rails New” Causes Segfault Using Ruby 1.9.3 on Lion

My setup: RVM, MacPorts, OSX Lion ..and “rails new” causes a segfault! Stack trace seems to indicate its coming from the bundle install, specifically from net/http. Some googling suggests this is caused by https:// in the gemfile, and can be fixed by modifying it to http://. However since this is during the rails new - thats not possible. No one solution I found addressed my particular issue, so I’ll document what worked for me, it may help you! 1. In xcode, Preferences –> Downloads –> Command Line Tools –> Install 2. Install openssl via RVM: [sourcecode] rvm pkg install openssl [/sourcecode] 3. Reinstall ruby 1.9.3, forcing GCC and the newly downloaded OpenSSL. The -C just means “use these configuration options” [sourcecode] rvm reinstall 1.9.3 -C –with-gcc=gcc –with-openssl-dir=~/.rvm/usr [/sourcecode] References: https://github.com/rails/rails/issues/4766 http://stackoverflow.com/questions/9626729/how-do-you-install-build-ruby-1-9-3-on-osx-lion

Easter Egg? Cause Git to Say: “Already Up-to-date. Yeeah!”

Git responses are usually very straightforward and to the point, but today I got git to say “Yeah!” by telling it to merge something it just merged. To get your git to be a little silly too:

Immediately after doing a merge, look at that last merge commit

1
2
3
4
5
6
7
8
$ git log -n1

commit 76c4ac19c545fdc9d20c43beb358c47c0d84185a
Merge: 2619f49 0f71f1f
Author: someone@somewhere.com
Date:   Fri Jun 17 17:36:10 2011 -0700

[master] Merge branch 'release'

Then…tell git to merge the same two SHA’s again

1
2
$ git merge 2619f49 0f71f1f
Already up-to-date. Yeeah!

This is using git v1.7.5.4 command line, on OSX.

When Did This Feature Go Live? (Starring Git)

It can be very useful to be able to answer this question accurately.

To do this, add code to your deploy script that tags every production deploy with git. Example:

1
2
3
  timestamp = Time.now.strftime('%Y-%m-%d/at/%H.%M')
  tag_name = "deploy/#{timestamp}"
  `git tag #{tag_name}; git push origin #{tag_name}`

Now, if the question ever comes up when a particular feature went live, you can determine this down to the minute. Find a commit that was part of this feature. For example, a new header design:

1
   git log --grep="header"

Now you can use the –contains switch to find the earliest tag that contained this particular commit:

1
   git tag --contains <SHA>

See my previous post on git for more useful git commands.

Useful but Lesser Known Git Commands

Therefore, here are some of my favorite, useful git commands:

Diff of a Diff

Looking at the diff representing one commit is old news.

1
git show <SHA>

Comparing a single file between two commits (or branches) is also not uncommon:

1
git diff branch1 branch2 -- path/to/filename.ext

However - if the files were pretty far in the two branches to begin with - and you’d just like to compare the CHANGES introduced by two commits (a diff of a diff), one way is this:

1
diff <(git show SHA)  <(git show SHA)

git log with diffs

Oft overlooked feature:

1
git log -u

Can be useful if you’d like to track the history of a certain file, and view all the changes:

1
git log -u -- path/to/filename.ext

git log, tracking renames

By default - viewing the history of a specific file with git log only goes as far back as when the file was created - or renamed.

If you’d like to track it back past any number of renames / moves:

1
git log -u --follow -- path/to/filename.ext

This can get pretty slow for larger repos, which I imagine is why its not on by default.

View a file in a branch, without actually checking it out

If you’re working on a file and wish to view that same file in another branch, you can avoid extra stashes & checkouts and just “peek” into that branch:

1
git show branch2:path/to/filename.ext

Note the syntax of branch:file without spaces, which is unusual.

Recommit a commit?

You may want to do this if the commit message is really bad (what are some of the worst messages you’ve seen? A whole other blog post…) and it’s already been pushed remotely.

Git doesn’t like letting you do this, you can’t commit changes to files that haven’t been changed. You can’t cherry-pick a commit if all the changes are already in place. You could do a revert and then a re-revert - but semantically that might even be worse in the history - it implies there was a problem with the code.

Another approach: Branch, amend, merge

1
2
3
4
5
6
git checkout master
git checkout -b tmp_branch
git commit --amend
git checkout master
git merge tmp_branch
git delete -D tmp_branch

you’ll end up with a duplicate commit, and a merge commit - but it gives you the opportunity to provide more verbose info on that 2nd commit message. In this example the commit in question would be at the tip of master, but any commit in history should work - just branch your tmp_branch off of whichever commit needs amending.

Common Ancestor

1
git merge-base branch1 branch2

Shows you the one shared commit where these two branches diverged. In the git “file system”, any two commits - no matter on which branch will have a shared ancestors. It’s sort of like evolution.

This can be useful if you’re in the middle of resolving a merge conflict, and you feel like the 3 pane diff GUI is not providing you with enough information. Open up a 2nd terminal, find the common ancestor and then diff the file in question between the branch and the common ancestor, to see exactly whats changed.

List of commits that exist in one branch but not in another

I like this syntax because it reads well to me as a developer. Show me commits that are in branch1 that are not in branch2:

1
git log branch1 ^branch2

If you or your group does a lot of cherry-picking or rebasing, then this won’t always work - because those operations create a new SHA - and the above depend on the SHA being the same. Start using merges instead if possible, then the usefulness of the above will become apparent.

You can use similar syntax to determine if a single commit is part of a branch or not:

1
git log -n1 commit ^branch

If the commit is part of the branch, it will show you nothing. If it is not part of the branch…it will show you the commit.

Make an exiting branch tracking

If a branch was started locally and was then pushed remotely. You probably found out soon enough that its not set up to track so well - compared to a branch that started remotely. To get it all set up:

1
git branch --set-upstream foo upstream/foo

(Thanks to this stackoverflow.com article for this last one)

Google’s Spell Check API Stopped Working - Here Is the Fix

Google’s undocumented, unpublished, not-for-public-consumption Spell Check API stopped working. How dare they? Well turns out the fix is simple, after using Charles to debug the HTTP requests of the Google Toolbar spell checker, I narrowed down the difference between my calls and theirs to a missing host header. Added that back in and everything works again. Usage: (I don’t parse the XML, because I’m just passing it to a flash client): [sourcecode language=”ruby”] => puts Spell.check(‘does it worka?’) <?xml version="1.0" encoding="UTF-8"?><spellresult error="0" clipped="0" charschecked="14"><c o="8" l="5" s="1">works work wok worker woke</c></spellresult> [/sourcecode] Source: [sourcecode language=”ruby”] require ‘rubygems’ require ‘builder’ require ‘net/http’ require ‘net/https’ module Spell HOST_HEADER = ‘www.google.com’ HOST_POST = ‘google.com’ PATH = "/tbproxy/spell?lang=en&hl=en&v=2.0f" def self.check(text) http = Net::HTTP.new(HOST_POST,443) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE headers = {"Host" => HOST_HEADER} data = get_xml_payload(text) response_headers, response_data = http.post(PATH, data, headers) response_data end private def self.get_xml_payload(text) xml = Builder::XmlMarkup.new xml_string = xml.spellrequest(:textalreadyclipped => "0", :ignoredups => "0", :ignoredigits => "1", :ignoreallcaps => "0") do xml.text(text) end end end [/sourcecode]

Array#only for Ruby

How many times do you use some_array.first as a way to get at the one and only member of that array? It always bugged me that this can be error prone - if the array has more than one component you’ll never know about it, and the .first method isn’t semantically describing what you are doing - grabbing the one and only member. If you add this somewhere in lib/initializiers, you get the .only method [sourcecode language=”ruby”] class Array def only raise "called Array#only with array of length #{self.length}" if self.length>1 self.first end end [/sourcecode] which provides a more semantic description of what you’re trying to do: [sourcecode language=”ruby”] >> [].only => nil >> [1].only => 1 >> [1,2,3].only RuntimeError: called Array#only with array of length 3 [/sourcecode]

Update to “Fire and Consume Custom Global Events in jQuery”

Update 9-8-2012: Global events with Backbone JS

This is an update to a previous post

jQuery 1.4 is out, and the undocumented syntax I described for triggering and responding to global events has changed. You can still use the same pattern. When firing a global event, bind to any element on the DOM, such as ‘body’ or document:

1
2
$(document).bind("sneeze",function(){})
$.event.trigger("sneeze");

This is a great way to decouple code and when used like a messaging system, can really clean up your code.

SQL Quiz

I enjoyed this interactive javascript quiz from perfectionkills.com, and thought it would be fun to create an interactive SQL quiz.

 

You can head on over directly to my SQL quiz or preview the questions here.

 

Given the following two tables: [sourcecode language=”text”] select * from a; select * from b; +——+——-+ +——+——-+——+ | id | label | | id | label | a_id | +——+——-+ +——+——-+——+ | 1 | Alpha | | 1 | I | 1 | | 2 | Beta | | 2 | II | 1 | | 3 | Gamma | | 3 | III | 2 | +——+——-+ +——+——-+——+ [/sourcecode] What would be the result of each of the following SQL statements….. (continued) Head over to the interactive SQL quiz to match the queries with the results.

Cleaner CSS Browser Targetting With Simple-useragent Gem

I just posted the “simple-useragent” gem, which provides the ability to for cleaner browser specific CSS targeting*. This is for rails projects but the concept can work anywhere. For example, instead of the targeting IE7 with your CSS with [sourcecode language=”css”] /* IE7 */ *:first-child+html #content { height: 500px; } [/sourcecode] You can now do this: [sourcecode language=”css”] .ie7 #content { height: 500px; } [/sourcecode] To take advantage of this, you just need to add the following to your body tag: [sourcecode language=”ruby” htmlscript=”true”] <body class=’<%=UserAgent::browser(request)%>’> [/sourcecode] * Admittedly targeting CSS to a specific browser is a bad practice that should generally be avoided. For more details about why browser detection in general is a bad idea, see www.quirksmode.org/js/support.html. However sometimes there is no choice - especially under time constraints.
Additionally, simple-useragent makes the following methods available to you: [sourcecode language=”ruby” htmlscript=”true”] UserAgent::is_desktop? UserAgent::is_mobile? UserAgent::is_blackberry? UserAgent::is_iphone? [/sourcecode] The is_mobile? and is_desktop? methods are using a minimalistic approach, converted from the python script here: http://gist.github.com/88057. The theory is that since there are a lot more mobile user agents than there are desktop user agents (hundreds or even thousands) - we detect the known list of desktop user agents, and if its not one of those we assume that it is mobile. It works surprisingly well in the vast majority of cases. So far I’ve only seen it fail with spoofed or malformed user agents. To install: [sourcecode language=”bash”]gem install simple-useragent[/sourcecode] The gem is hosted on gemcutter - if you don’t have gemcutter as a source you’ll have to add it [sourcecode language=”bash”]gem install gemcutter gem tumble [/sourcecode]
source at http://github.com/galori/simple-useragent Update: Thanks to an anonymous commenter on rubyflow for pointing out a jQuery version of this: jquery.platformselector.