Programatically get the version of an egg
The documentation for pkg_resources does not make it 100% obvious how to get the current version of a Python egg. To do so:
pkg_resources.get_distribution(egg_name).version
The documentation for pkg_resources does not make it 100% obvious how to get the current version of a Python egg. To do so:
pkg_resources.get_distribution(egg_name).version
Print a dot for every four lines of output, also logging to output.log.
LOGFILE="output.log"
LOGPIPE="/tmp/$$.tmp"
trap "rm -f $LOGPIPE" EXIT
mknod "$LOGPIPE" p
sudo tee <"$LOGPIPE" -a "$LOGFILE" | awk '{ if (NR % 4 == 0) printf "."; system("") }' &
exec 1>>"$LOGPIPE" 2>&1
When you create a ruby lambda it is bound the the scope it was defined in. Therefore, if you create it in the class scope, you cannot access instance variables or protected instance methods.
To execute the lambda in your instance’s scope, use the instance_eval method:
Inspired by Brandon Keepers, what follows is a self contained script that will play a single Hallelujah after you commit.
To make it work, place it in your repository’s .git/hooks directory as post-commit and chmod it executable.
One of the curious absences in the Mac SDK is the ability to invoke a thread that targets a method with multiple arguments.
If you want to use [+ NSThread detachNewThreadSelector:toTarget:withObject:] you either have to refactor your function to a) take a collection like an NSArray or NSDictionary or b) call an intermediary function which then makes the call on that thread. You would half-expect a method like [+ NSThread detachNewThreadSelector:toTarget:withObjects:] to exist.
In order to get round this, I created the SEThreadInvocation object which blends a NSThread and a NSInvocation together.
You can then call your method like so:
While working on WineLedger for the iPhone I spent a lot of time trying to work out why duplicate ‘ghost’ entries would sometimes appear when merging two NSManagedObjectContexts:

As I inserted a new entry, two copies would appear: One would remain stuck, while the second would correctly update when you edited it. As soon as the app was restarted the ghost entry would miraculously vanish. To add to the confusion, this behaviour would only occur when I used the camera to take a photo via UIImagePickerController.
After a lot of trial and error I finally discovered that the main view was being unloaded from memory as soon as you took a picture. Using the camera causes a huge memory spike as the phone stores the high resolution image.
This shouldn’t be a problem, but as the view loads back into memory the NSFetchedResultsController does a fetch. This initial fetch loads the full set of results (including the freshly inserted object), and then the delegate methods proceed to perform a nice slide animation when the two contexts are merged, inserting the object into the UITableView again.
The fix for this problem is to insert a guard to check to see if the NSFetchedResultsController already has some managed objects before it does a fetch on viewDidLoad.
if (self.fetchedResultsController.fetchedObjects == nil)
{
NSError * error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
script/consumer:
#!/usr/bin/env ruby
def pidfile
@pidfile ||= File.expand_path(File.join('..', '..', 'tmp', 'pids', 'consumer.pid'), __FILE__)
end
case ARGV.first
when 'start' then
require 'rubygems'
require 'rake'
ENV['QUEUE'] ||= '*'
ENV['RAILS_ENV'] ||= 'production'
load(File.expand_path(File.join('..', '..', 'Rakefile'), __FILE__))
Process.detach(consumer = Process.fork do
begin
Rake::Task['environment'].invoke
Rake::Task['resque:work'].invoke
rescue Exception => e
$stdout.puts([e, *e.backtrace].join($/))
end
end)
%x(echo "#{consumer}" > #{pidfile})
when 'stop' then
%x(kill `cat #{pidfile}`)
%x(rm #{pidfile})
else
puts 'usage: script/consumer start|stop'
endIf you are reinstalling git for Snow Leopard, don’t forget to nuke MacPorts. Leaving an old version on your machine will cause the git compile process to spit out various incorrect architecture errors:
ld: warning: in /opt/local/lib/libz.dylib, file is not of required architecture
ld: warning: in /opt/local/lib/libiconv.dylib, file is not of required architectureRemove MacPorts with the terrifyingly brutal:
sudo rm -rf \
/opt/local \
/etc/manpaths.d/macports \
/etc/paths.d/macports \
/Applications/DarwinPorts \
/Applications/MacPorts \
/Library/LaunchDaemons/org.macports.* \
/Library/Receipts/DarwinPorts*.pkg \
/Library/Receipts/MacPorts*.pkg \
/Library/StartupItems/DarwinPortsStartup \
/Library/Tcl/darwinports1.0 \
/Library/Tcl/macports1.0Once you have removed MacPorts, the compile process should be as easy as:
make configure
./configure --prefix=/usr/local
make prefix=/usr/local all
sudo make prefix=/usr/local install
git config --global user.name "[user.name]"
git config --global user.email "[user.email]"And when you are done, don’t forget this little gem for adding pretty colours to your git output:
git config --global color.ui "auto"After installing Snow Leopard all of my native code gems broke horribly, complaining that they were now on the wrong architecture. To re-install every gem automatically, I used:
sudo gem list | awk '{print $1}' | xargs sudo gem installI just expanded the Flyweighted Object class to support keyword arguments:
import weakref
import cPickle
class FlyweightedObject(object):
_pool = weakref.WeakValueDictionary()
def __new__(klass, *args, **kwargs):
if not hasattr(klass.__init__, 'im_func'): raise 'cannot flyweight an object which has no python constructor'
arguments = {}
constructor = klass.__init__.im_func
arguments_missing = constructor.func_code.co_argcount - len(args) - 1
if arguments_missing > 0:
args += constructor.func_defaults[-arguments_missing:]
varnames = constructor.func_code.co_varnames[1:]
for i in range(len(varnames)):
varname = varnames[i]
arguments[varname] = kwargs.get(varname, args[i])
key = cPickle.dumps((klass, arguments))
instance = klass._pool.get(key, None)
if instance is None:
instance = object.__new__(klass)
klass._pool[key] = instance
return instance
def __getnewargs__(self):
if hasattr(self.__class__.__init__, 'im_func'):
constructor = self.__class__.__init__.im_func
return tuple(getattr(self, attr) for attr in constructor.func_code.co_varnames[1:])
return tuple()