Davis W. Frank's blog
Ask for Help
"Rubymine seems to have lost my RSpec stack trace? Spec from the command line is fine."
Check the run command & try reverting to the default options?
"What's our favorite 'copy to clipboard' code these days?"
Zero Clipboard - jQuery version - is the one that lets you bind the Flash code to any HTML element. That's the one you want.
"Can you use Jasmine to test a MongoDB map/reduce?"
Yes! It just uses JS objects, so you can unit test your code with Jasmine no problem. We recommend you add a couple of integration tests to make sure everything is connected properly.
Interesting Things
- The cmdparse gem has now been released under LGPL. This gem gets pulled in as a dependency for some other gems, but was GPL before. It should now be easier to deal with if you're license-wary
- Having memory leaks in your JavaScript? Try Leak Helper! It's a simple enumeration of objects off of
window, not catching objects inside closures, but it still helped a team find a set of circular references that were confounding the garbage collector.
Ask for Help
"How do you handle jQuery, new HTML5 elements, and IE6/7?"
Other than "I don't", how do you deal with building large article elements and then attach them to the DOM? It's icky since older IE's don't handle elements it doesn't know about. Do you have any suggestions?
"Are you using AuthSTMP on an app hosted at EngineYard? Is it working?"
Something changed and our configuration is no longer working. Not sure why.
Interesting Things
- RubyGems 1.4 is out. There are tips on how to upgrade nicely with RVM. But you might want to wait if you're using Ruby 1.9.
- Our friends at Irrational Design have launched Secret Goals and want you to share your good & horror stories about New Years' Resolutions.
Interesting Things
find_in_batches has Evil Scopiness
ActiveRecord::Base#find_in_batches() (and therefore #find_each()) is applying a scope around the block it is given, which applies to any subsequent find call on that model:
Let's say we have a Comment model that act_as_tree so comments can be threaded. In the following code:
Comment.find_each(:conditions => "comments.state = 'published'") do |comment|
puts comment.parent.content
end
The association call to .parent will also have the scope {:conditions => "comments.state = 'published'"} applied to it. This can have highly unexpected side-effects.
The way to get around this is:
Comment.find_each(:conditions => "comments.state = 'published'") do |comment|
Comment.with_exclusive_scope(:find => {}) do
puts comment.parent.content
end
end
Easy Ruby profiling
If you're profiling Ruby code often, here's a code snippet that can be useful:
Ask for Help
"What's the best way to use Bundler and Rubymine?"
Rubymine 2.5 supposedly supports Bundler. Our default workstation install now uses RVM to manage Ruby interpreters & Gemsets, Rubymine 2.0 sees each interpreter/gemset as a separate Ruby SDK. So RVM manages our gem bundles.
Interesting Things
- Nokogiri v1.4.2, really needs JRuby 1.5.1 to work properly
A JRuby project had an issue where they upgraded Nokogiri, but got a "Can't find this function pointer" message. It turns out that the issue was an out-of-date libxml. The solution was to upgrade JRuby to 1.5.1, which they did with this addition to their Chef scripts:
execute "install_libxml2_2.7.6" do
command 'ACCEPT_KEYWORDS="~amd64 ~x86" emerge =libxml2-2.7.6'
not_if { FileTest.directory?("/var/db/pkg/dev-libs/libxml2-2.7.6") }
end
Interesting Things
iOS3 and hardware-accelerated CSS
CSS 3D Transforms are accelerated with hardware on iOS (3.2), but not the 2D ones. So if you want to take advantage of hardware, break out your linear algebra and add an extra dimension:
div {
-webkit-transition: -webkit-transform 1s ease-in;
-webkit-transform: translate(10, 0); /* NOT ACCELERATED */
}
...will be slow. While this:
div {
-webkit-transition: -webkit-transform 1s ease-in;
-webkit-transform: translate3d(10, 0, 0); /* ACCELERATED */
}
...will be crazy fast and smooth.
Also of note, the opacity CSS property is accelerated on iOS 3.2 and greater, iPhone and iPad.
BOOM!
Cached Taggings
Using act_as_taggable_on? There is an un/poorly-documented option for caching your taggings:
Say you have tv_shows tagged with genres. If you add a migration like this:
add_column :tv_shows, :cached_genre_list, :string
The acts_as_taggable_on looks for this column and on save updates it with a comma separated list of the associated tags. Thus when you're then reference in your view you can reference:
tv_show.cached_genre_list
BOOM!
Restart Rubymine to find your new specs
If you're using the latest Rubymine EAP, and you create a new spec file but can't seem to get Rubymine to execute it, just restart Rubymine. BOOM! And you'll be able to run your specs.
S3, Net::HTTP and JRuby
A project on has workers that manipulate PDF files in a pipeline. Each processing step stores its result on Amazon S3. Subsequent processing steps start by fetching the previously stored pdf using net/https. Occasionally the fetched PDFs are truncated and invalid.
After much digging and headscratching, the problem appears to have been JRuby 1.3.1. Moving the app over to JRuby 1.5.1 BOOM! fixed the issue and the PDFs are now all fine.
Ask for Help
"Does anyone have experience with Google Custom Search v. Google Site Search?"
The results sets appear to be different and I don't expect them to be...
Interesting Things
Heroku's Console runs in production mode
This means that, unlike script/console on your local box, the Rails Environment doesn't reload completely before you start hacking away. So if you're expecting changes to be live, like migrations, they won't be until you redeploy, restart your app heroku restart, and then run the console.
Request Log Analyzer & Rack::Bug
If you're doing some performance tuning on your Rails app make sure to check out Request Log Analyzer. It's great for helping show you all the stupid things you didn't realize you were doing that was making your requests slow. Another great tool for this type of analysis is Rack::Bug.
Ask for Help
"What are people using in Rails apps for authentication via Facebook Connect?"
- Devise
- Janrain if you want something that can use many different social websites authentication; it also hooks up sharing, etc.
"There seems to be a bias against Rails Observers. Anyone know why?"
I want to use them, but whenever I look around people seem to say they don't like them any more. Anyone know why?
"Is Pivotal Tracker crashing for you in Safari??"
This is a known issue but we're having a bear of a time reproducing. We're accepting Safari stack traces over email, with bonus points for figuring out how to send us Session cookies post-crash.
Interesting Things
When using Passenger in spawn mode (to fork your workers), post-fork you MUST reopen any outbound sockets for things like Redis, Memcache, etc. Otherwise all your other connections will use the same socket. And you won't notice it until oddness starts to happen when under load and processes get the wrong responses.
For some time now, Google Chrome has been happily giving stack traces when using Jasmine! Firefox has always done this. If you're keeping score, only Safari refuses to give you stack traces in your failing Jasmine specs.
Interesting Things
If you are overriding to_json in any of your Rails models you should read Jonathan Julian's blog post which explains the purpose of as_json vs to_json.
Choice quote:
Enter ActiveSupport 2.3.3. Now the creation of the json is separate from therendering of the json. as_json is used to create the structure of the JSON as a Hash, and the rendering of that hash into a JSON string is left up to ActiveSupport::json.encode. You should never use to_json to create a representation, only to consume the representation.
as_json is also easier to test because it returns a Ruby Hash instead of a String.
Interesting Things
- The Node.js guys have announced the Node.JS Knockout a "build an app in 48 hours" in the spirit of the Rails Rumble. You and your team of up to 6 people build a server-side JavaScript application in 2 days and host it on Heroku. Follow the action on Twitter: @node_knockout
Help
In a Webrat/Selenium test how do we close a window in order to return focus to the previous window?
At any time, you can eval some JavaScript, so you could just call window.close(). Or since you're using Selenium, why not just bust out some Selenium calls to close windows and/or change focus.
Interesting Things
- Keep your OAuth Nonce values simple.
The Twitter Api, which is requiring all clients to move to OAuth for authentication by June 30, 2010, like all OAuth systems requires a nonce value for every call. This value is supposed to be random and unique for each request you make.
While there are many ways to generate a random ASCII value, our recent experience with Twitter's OAuth system shows that a nonce value should not include a '%' character - which would happen if your value has any non-URL-safe character. Twitter will return you a 401 error and tell you that your signature and token cannot be verified.
We've filed a bug with Twitter. But until then, keep your nonce value to ASCII letters & numbers and the calls will work just fine.
