MacRuby and Checking a Path is a Directory
MacRuby is awesome, but some aspects are very much Obj-C with Ruby lipstick. One of these is the use of pointers being set by functions as secondary effects. In Ruby we would just return multiple return values. Obj-C can’t do this, so sometimes it assigns to pointers.
I just ran into this when trying to determine if a file path is a directory or file. The obj-c approach is to use:
NSFileManager#fileExistsAtPath:isDirectory
where isDirectory sets a pointer to YES or NO.
In MacRuby we might do the following (wrapped in a convenience function):
def directory?( path )
bool = Pointer.new_with_type( 'B' )
file_man = NSFileManager.new
file_man.fileExistsAtPath( path, isDirectory:bool )
bool[0]
end
Ta da.
Stubbing Geocode with FactoryGirl
Google doesn’t seem to like it when our geocoded models hammer their geocoding API during our test runs so we should stub out the geocoding call. To do so:
FactoryGirl.define do
factory :place do
name { Randgen.name }
kind 'city'
timezone 'Mountain Time (US & Canada)'
enabled true
after_build { |place| place.stub!( :geocode ).and_return( [1,1] ) }
after_create { |place| place.stub!( :geocode ).and_return( [1,1] ) }
end
end
GeekTool and iCal
I use GeekTool to display quite a few items on my desktop, it’s a fantastic utility. For fun I’ve put together a Ruby script for use with GeekTool that displays iCal events: GeekCal.
Download the script, make it executable, set it up as a shell script in GeekTool et voila. Calendar events on the desktop.
Rcov, NaN, and Fatal Crashes
Seems its possible to crash the current version of rcov hard under certain circumstances (version as of this writing: rcov (0.8.1.2.0)). If you find it crashing with:
ruby(17057,0xa0124720) malloc: *** error for object 0x5b1a602: Non-aligned pointer being freed
*** set a breakpoint in malloc_error_break to debug
/opt/local/lib/ruby/1.8/rss/rss.rb:274: [BUG] Segmentation fault
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9]
…
rake aborted!
NaN
Check to see if you have any empty helper files that don’t have any coverage. I had a couple that resembled the following. Removing them removed the “divide by zero” issue that causes the crash:
module ProductHelper end
Update
Scratch that, it doesn’t entirely fix the issue. I’ve also implemented Stew Welbourne’s hack for round_to_tenths(decimal) in MetricFu but that too does not seem to be a complete solution. The seg fault still happens, though intermittently (sometimes it runs through the complete test suite, sometimes it doesn’t).
The search continues.
mysql2sqlite.rb
Introducing mysql2sqlite.rb, a Ruby script for converting MySQL databases into Sqlite databases.
Based on my googling of the web, I figure I’m one of perhaps five people in the world who’ve ever wanted to do this conversion but in case you’re number six, here you go.
Usage is pretty straight-forward. It can either be configured via command-line parameters or via a specified YAML file:
./mysql2sqlite.rb database_name database_user database_password ./mysql2sqlite.rb config.yaml
and it will spit out two files: one of the raw, converted SQL and one that is the Sqlite database. For instance, if your MySQL database was called ‘clients’ you’d end up with clients.sql and clients.sqlite.
For more details and source code see the mysql2sqlite.rb project on github.
DataMapper on Red Hat EL5
Last month I started rewriting the admin reporting section of one of my sites in Merb rather than refactor the existing PHP version, for a number of reasons. The pace of development with Ruby and Merb was tremendous and within about a week and a half I had a fully-functional, extensible reporting site developed, replete with graphs and statistics. DataMapper made tying into the legacy database, with it’s rather novel table and column naming schemes, trivial. It was all tremendously satisfying and, dare I say it for a project so unglamorous, fun.
And then I tried to get it to run on our production server, which is running Red Hat Enterprise Linux 5, and the fun went away.
I first tried installing Phusion Passenger (a product I’m absolutely enthralled by) but no such luck; it had a hell of a time with the default Apache install and lack of development headers and various file locations. I wasn’t willing to muck about with the production server in a vain attempt to force it to work at the risk of the rest of the site.
Instead I figured it ought to run just fine on Rack. And every dependent gem installed with nary a hitch save for DataMapper, specifically do_mysql, which would fail to build the native extension with the following error:
In file included from /usr/include/mysql/my_global.h:83, from do_mysql_ext.c:6: /usr/include/mysql/my_config.h:15:28: error: my_config_i386.h: No such file or directory
The solution was ultimately provided by Dan Kubb:
We probably should make it so that all the DO driver specs can be run on installed gems, but in the meantime, checkout the source from git using the following commands:
git clone git://github.com/datamapper/do.git cd do/data_objects sudo rake install cd ../do_mysql ... remove the references to my_config.h in do_mysql ... rake compile spec sudo rake installThis will first install the edge version of DataObjects, and then will compile and run the specs for do_mysql, and then install it. You will want to remove all references to my_config.h from the do_mysql C libs just prior to running the specs of course.
The really important bit here: “remove the references to my_config.h in do_mysql”. That’s the magic, and with that everything was good and right and Merb was run, and the users were happy.
(For the very curious, the entire DataMapper Google Groups thread.)
Bundling Gems With Merb
As part of the deployment of my first Merb app I wanted to make sure it contained everything it would need. This is pretty easy in Merb:
thor merb:gem:install
Once that runs through and bundles all the gems in your dependencies.rb file I knew that I should have been able to simply run:
./bin/merb
and use the bundled install of Merb. But this was failing mightily with dramatic FATAL errors. Using:
./bin/merb --verbose
shed light onto the issue. It turns out that because I was doing all my development by just running merb Merb was loading necessary dependencies that I hadn’t specified explicitly in my dependencies.rb file. Dependencies like “rmagick” and “mongrel”.
Putting all the dependencies into the file and re-running thor merb:gem:install did the trick.
Incidentally, if you attempt to do something like:
thor merb:gem:install mongrel
without having mongrel specified in dependencies.rb the install will fail. This, in hindsight, makes perfect sense to me – I like that file being the authority – however the error message generated is a bit obtuse ( in this case: "Configuration could not be confirmed: Could not find RubyGem mongrel (>= 0)").
It also appears (though I’m surprised by this so I suspect my understanding of this process is suspect) that you’ll need to declare dependencies that dependent gems rely on. Again in my case to get gruff bundled I also had to define rmagick:
dependency "rmagick", "2.9.0" dependency "gruff", "0.3.4"
So if you’re bundling gems make sure they’re all explicitly defined and use –verbose when running Merb to double-check. And read Getting Started with Merb – Bundling Merb with your Application. It was immensely helpful.
Method_missing requires responds_to?
I believe this should be taken as dogma and followed religiously:
I reject the argument because I reject as buggy any code such that object o responds to method m but o.responds_to?(:m) => false. If you implement your own method_missing for a class, you should almost always implement your own responds_to? as well.
- Maybe
There is wisdom in them there words. Monkey-patching is (perhaps) ok, but voodoo should probably be avoided at all costs and an object that can act but won’t provide a means of letting you know without actually trying it is just plain ol’ voodoo. And programming voodoo is bad juju.
Ultrasphinx Bootstrap Error
You’re installing Ultraspinx (perhaps per these instructions from Inoshi, which are the best I’ve found thus far) and you run into this error when time comes to bootstrap your installation:
~/Sites/ticklists/: sudo rake ultrasphinx:bootstrap –trace
(in /Users/chris/Sites/ticklists)
** Invoke ultrasphinx:bootstrap (first_time)
** Invoke ultrasphinx:_environment (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute ultrasphinx:_environment
** Invoke ultrasphinx:configure (first_time)
** Invoke ultrasphinx:_environment
** Execute ultrasphinx:configure
rake aborted!
You have a nil object when you didn’t expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
I couldn’t find this one in the google anywhere. Turns out the cause of this is defining non-existent properties for indexing on your models (perhaps I’m the only one dumb enough to do that).
You’ll know if this is the cause because you’ll see something akin to this in your Rails console:
** ultrasphinx: warning: field f is not present in User
** ultrasphinx: warning: field descritpion is not present in Profile
Remove (or fix the spelling of) those and everything should work hunky-dory.
Two-weekend website: Applican
A couple of weeks ago, in the middle of getting DreamBank ready for launch I was feeling like I needed a break. Of course that meant “what can I develop in Rails over a single weekend?” See, I had an idea for an application that would fulfill a need we had at DreamBank: how to manage incoming applicants and resumes against available job positions and I was pretty sure it would go.
My one-weekend project became a two weekend project and a bunch more time was shoe-horned in here and there for bug fixes and improvements until it was finally usable. And then we really got serious about the other launch and development got forgotten; it was released and functional and – dare I say it – even useful but neglected.
I now present to you “Applican“, a Rails-based resume/applicant/job tracker designed (as much as it has been) as an internal tool for small & medium-sized companies. For more details see the proto-documentation here.
I consider the current release to be about v0.4: it works, it’s useful, it undoubtedly has bugs, they’re may not be critical, there’s definitely functionality to be added. It’s free, it’s open-sourced, it’s available on Github and it require Rails 2.1.
(Apologies to Robert Rodriguez for stealing and bastardizing one of the best lines in cinema history).