 |
|
 |
 |
|
|
Mozilla just picked Mercurial as it's next-generation
version control system and successor to CVS. The article has the
details of the elimination process and includes creatively modified
Mortal Kombat screenshots to illustrate key points.
|
|
|
I mentioned the Nokia N95 in October, and it's finally
available. It's $750 unlocked, but it includes all sorts of really cool
stuff; Gismodo has a full review. Also, the Xbox 360
spring update includes H.264 and partial MPEG4
support. With any luck that'll allow the 360 to serve as a frontend for
the media on my network.
On the 360 front, there's also an update to Gears of War and an
imminent update to Rainbow Six: Vegas. I don't care too much
about the Gears of War update, but I've been playing Rainbow Six a lot.
So yeah, this is a great week for gadgets.
|
|
|
The KDE team is working on a Dolphin, a new next-generation file
manager. How many next-generation file managers do we need, anyway?
They still haven't finished fixing the broken ones from the last
generation. I just read
this Ars Technica preview of Dolphin, which aptly states:
In many respects, Dolphin is reminiscent of the Nautilus file browser
from the GNOME desktop environment.
Nautilus's defining characteristic has always been the uncanny ability
to waste a colossal amount of screen real estate to convey irrelevant or
redundant information. Believe it or not, some of the things I wrote
about in 2001 still haven't been
fixed.
But hey, everything old is new again, right? Check out the
awesomely efficient use of screen space in this Dolphin picture:

|
|
|
Say hello to Mercurial, my long-overdue replacement for CVS.
Unlike CVS and Subversion, Mercurial is a distributed version
control system (VCS), which means (among other things) it doesn't
have a central repository, has disconnected (non-networked)
commits, and allows you to group small changes together as "change sets".
Other well-known distributed VCSs include Bitkeeper, Git,
Darcs, and
Monotone (there are more). While searching for a CVS
replacement, I spent some time using Subversion, Monotone, and Git;
here's a brief overview of my experience with each one.
Subversion: Subversion is probably the most popular VCS, so
you're probably already familiar with it. I'll dispense with the
pleasantries and skip straight to the problems.
For the past several months I've been using a private, home Subversion
repository for small projects, snippets of code, configuration
files, scripts, and various other knick-knacks. Along the way, I
noticed several things about Subversion that bother me. For example,
until version 1.4, common operations like svn status and svn
commit were uncomfortably slow under Subversion. They're better now,
but still not as fast as I'd like. Copying and moving large groups of
files is still painfully slow (moving several hundred megabytes of
files took me well over 20 minutes).
Branching in Subversion is primitive (and slow, since it's really just
a copy). For me this is a major problem, because in addition to
revisions, I also want to use branches for quick, version controlled
staging areas for new features. That's a problem in Subversion,
because branches are expensive, and merging is kind of wimpy.
It's a genuine hassle to require network access for commits; I
regularly work remotely, and even though I have VPN access (courtesy
of OpenVPN) it's still kind of distracting to wait for common
commands like commit, add, and copy . My alternatives? Move the
repository to a public server with better bandwidth (which makes it
slower for me to access while I'm at home, plus it's not really
private any more and I'm still dependent on network connection) or
hold off on commits until I'm at home (which is contrary to committing
in small, incremental changes, my preferred modus operandi).
Finally, and most importantly, Subversion is centralized. Why? It
imposes all sorts of workflow restrictions that haven't been
necessary since VHS tapes went out of style. For example, I have
roughly five gadzillion projects in various states of brokenness and
disarray that I'm just not ready to publish. Distributed version
control systems have no central repository except one that is
designated by convention, so I can commit locally, push to my private
repository when it's convenient, and publish to the public repository
when I'm damn good and ready. Subversion can't do any of this without
cheating, of course, so I'm forced to either migrate projects to the
public repository without their history or use svndumpfilter
chicanery to bludgeon Subversion into doing something it should be
able to do out of the box. Which sounds an awful lot like trying to
copy and move files in CVS. Which is why we were supposed to upgrade
to Subversion in the first place. Oops...
(Subversion isn't all bad, by the way. It's certainly a huge
improvement over CVS. It integrates well with Rails,
Eclipse, and all the other fancy toys kids use these days.
Plus Subversion has all sorts of nifty extensions like TortoiseSVN
and Trac. I use Subversion daily at work. I just need things
Subversion doesn't support by design).
I'd be derelect in my blog posting responsibilities if I didn't
mention SVK, a distributed VCS built on Subversion that supports
repository mirroring and disconnected operation. I can't say much
about SVK because I don't have much experience with it, although I'm
fairly sure SVK has neither the speed nor the power of Mercurial and
Git. Personally, I don't really see the point of keeping Subversion
around for the sake of keeping Subversion around, particularly in lieu
of Subversion's marvelously atrocious track record with repository
corruption.
Monotone: I wanted to like Monotone. I stumbled across a
reference to it in the SQLite documentation, and spent several
months putting up with Monotone's warts after Linus plugged it on the
LKML. I like the extensive documentation, simple
command-line interface, Lua hooks, proper Windows support.
Internally, Monotone makes extensive use of strong cryptographic
primitives, which I wholeheartedly support.
Unfortunately, Monotone is slow. Dog slow. An initial repository pull
(checkout, in CVS parlance) is so slow that a many Monotone
users provide a publicly downloadable snapshot of the initial pull
instead. The last time I used Monotone, the crypto certs were their
own special blend; I'd prefer either OpenPGP or X.509.
(Oddly enough, my first look at Mercurial was right after I started
testing Monotone. I wasn't initially interested in Mercurial because
I was still stuck on Monotone. I didn't feel like Mercurial offered
much more than Monotone, and I hadn't fully appreciated the speed
difference between the two).
Git: Git was (is) right at the top of the list. It's fast,
possibly (probably?) even faster than Mercurial. It has features
Mercurial doesn't support (rebase, for example, although I believe that can
be clumsily emulated with bundle and unbundle). Keith Packard
wrote a post titled "Repository Formats Matter",
advocating Git for X.org. His post briefly mentions Mercurial and in
a positive light, but dismisses it prematurely for what I think is a
completely asinine reason; old, obscure ftruncate() bugs in the
Linux kernel (see this post on the Mercurial
mailing list for a more thorough rebuttal of Keith Packard's
ftruncate() sillyness).
I only have two real gripes with Git: the Windows support sucks (it
half-works via cygwin, which doesn't really count), and the
command-line interface makes me feel stupid.
The second one is the deal-breaker for me. While I may not be
Mensa material, I've spent enough time using version control that I
feel like I should be able get at least the gist of a new VCS in a
couple of minutes, be comfortable with it within a day or so, and
proficienct with it within about a week.
I don't really think that's unreasonable. Even if it is, so what? A
VCS is a tool, one that's supposed to make my life easier. If I
can't use it without consulting the documentation every couple of
minutes then it's just getting in my way.
I simply refuse to waste my time learning the nuances of an interface
that is complex for no other reason than the programmer couldn't see
far enough past their own idiosyncratic whims to long enough provide
an interface without the learning curve of a black diamond ski slope.
This is particularly true for an application like Git that has few,
if any, tangible benefits when compared to it's more intuitive
counterparts.
The silver lining here is that I eventually stumbled on Mercurial. And
by stumbled, I mean Richard (richlowe) told me about it
(just like he told me about Vim, Screen, Mutt, Ruby, and
a whole
lot of other cool stuff I use regularly). He knows a lot more about
version control software than I do, but I didn't really pay any
attention. At least not until I noticed that Mercurial seemed to be the
only free VCS that wasn't enclosed in a long and colorful string of
profanity when he talked about it.
Anyway, the more I use Mercurial, the more I like it. It meets all of
the requirements I mentioned above, plus it has the speed and power of
Git and the simplicity of Subversion and CVS. Mercurial is actively
developed, has full Windows support, and it includes extensions that add
support for PGP-signed tags and Quilt-style patch queues.
The real killer feature for me, though, is that everything I try just
works. Setting up read-only, web-accessible public repository only took
a minute or two of reading, and making an entire directory of Mercurial
repositories available only took a couple more minutes. I had
comparable experiences with branching, tagging, signing tags, and
pushing changes to multiple repositories.
The only warts I've found in Mercurial so far are minor; the web
interface needs a bit of cleanup, and there should be a straightforward
way of adding repository defaults like style, contact and archive
formats via the top-level htwebdir configuration file. The native
import features are still a bit lacking, although you can use Tailor
to convert data from all but the most esoteric or convoluted
repositories.
That's about all the advocacy I can muster up at the moment. If you're
interested in reading more about the state of distributed version
control systems, there are more detailed VCS comparisons here and
here.
Note: I've had this post sitting in my queue for months. I
just brushed off the cobwebs, cleaned up the typos, and posted it.
In that time Mercurial has picked up a bit of publicity, and development
has been moving along at a steady clip. I tried to remove the bits that
no longer apply, but let me know if I missed anything.
Edit: This article was linked on Reddit; some additional conversation (and
my responses) can be found in the comment
thread.
|
|
|
Last night I dusted off and started re-reading my copy of
"Getting Things Done" (GTD). I'm a bit overwhelmed
with projects and new ideas at the moment, so taking some time to
optimize my scheduling algorithm seemed like wise thing to do.
A bit of Googling turned up a plethora of GTD-inspired applications,
including several desktop applications (no thanks), a ton of web-based
task managers (maybe!), and even a couple of Vim-based solutions plugins (neat!).
On a whim, I decided to check out Tracks, a Rails GTD
application. Tracks was kind of a turd; the documentation
is sparse, there seem to be a couple of weird bugs, and it didn't look
so hot in my web browser (my guess is the stylesheet is pretty
Mac-specific, although I didn't poke around too much to see what the
problem was).
The attempted Tracks install wasn't a total bust, because I used it as
an opportunity to upgrade my internal web/rails VServer. I've been
using VServers at the house for quite a while now and I love them;
there's even an entry my to-do list to write a VServer post which I
haven't gotten to. Playing around with Tracks also gave me
an opportunity to set up a Mongrel cluster, which, barring one minor
hiccup, is as straightforward to configure as the documentation implies.
Next on my list was Todo.txt. Todo.txt certainly isn't for
everyone; it's a shell script and a text file, and that's pretty much
it. It's also exactly what I wanted; simple, unobtrusive, and
future-proof. I set up the AIM bot too, so I've got a couple
different interfaces for adding and viewing tasks. Google Calendar
integration would be nice, although that's probably been done too and I
just need to dig it up.
Anyway, back to reading and trying to re-shoehorn my brain into GTD and
Todo.txt.
|
|
|
I've bought two handfuls of new gadgets in the last few months.
Initially I was going to post pictures and a review of each one, but
hey, I'm lazy, and that would have cut too much into my gadget time.
Anyway, here's what's new in the land o' Pablotron gadgets:
- Samsung SGH-t809: A T-Mobile-branded Samsung D600 cell phone.
Yes, this means i've finally joined the 21st century.
- Plantronics Discovery 640: Sweet (and tiny!) bluetooth headset. Keeps
my hands free and my phone safe. I can also use it with Skype with
my snazzy no-name USB bluetooth dongle.
- Slim Devices Squeezebox V3: This bad boy lets me listen to all my
music and keep my room quiet. Slim Devices was recently aquired
by Logitech -- hopefully they don't go down the crapper because of
it. By the way, I've massaged both SlimServer and
MythTV onto the same machine using VServers; if there's any
interest I can post the gory details...
- Sony CyberShot DSC-T10: I loaned out my old digital camera and it
was returned with a dead battery, covered in dust, and without the
ability to take pictures. So far I'm pretty happy with this camera;
the wealth of features almost makes up for the annoying proprietary
sony memory crapola. Plus I eeked out a few more megapixels than
Tom, and that's always fun :).
- Cowon iAudio X5 60G: I lost my H120, so I picked up the X5.
It was time for an MP3 player with more disk space anyway. So
far, so good. I like the screen, the USB host, and the built-in
microphone. The audio quality on the H120 seemed a bit better, and
I'm not a big fan of the extremely losable dongle (I bought an extra
one, just in case). Did I mention that you need for line out, power,
and USB? What kind of crackerjack design has USB Host on the player
itself, but a dongle for line out and USB data transfer? The
default operating system is okay, but I installed Rockbox anyway.
|
|
|
I got a chance to sneak out to last week's NovaRUG. Chad was in
town for work, so he stopped by. I also got a chance to talk to
Rich and Tom as well.
Rich inadvertently used his phone as a Wiimote-style projectile weapon.
Chad went and got all famous since the last time I saw him (at RubyConf
2004)! Apparently writing a couple books and speaking all over the
world does that to you. Who knew? Anyway, I only had a little while to
catch up with him, but he dinged my for being lax on Raggle.
He'll be in town next month as well; maybe we'll have a bit more
time to hang out then.
I talked to Tom about Mercurial and VServers. I'm using both
now, and he's interested in both for RubyForge. The former as
another SCM for people to use, and the latter as a way to provide
user shell access.
|
|
|

The new version of Technorati-Ruby adds a bit of magic to return
values. Version 0.1.0 returns standard Ruby hashes. A list of
items in the returned value -- blogs from Technorati#cosmos or tags
from Technorati#tag, for example -- are returned as an array of hashes
under the the 'items' key, like so:
# find sites linking that link to me
results = tr.cosmos('pablotron.org')
# print an excerpt from each item
puts results['items'].map { |item|
[item['url'], item['excerpt']]
}
It's a simple system, and using a hash instead of a pre-defined class
reinforces the idea that the return values could be unavailable, change,
or possibly even be removed. The problem, of course, is that the hash
references in the example above clutter the code and cause it to look
more like [Perl] than Ruby.
I wanted to give the results a bit more of a Ruby feel, preferrably
without breaking backwards compatability. I came up with a solution
that I'm pretty happy with. We'll get to that in a minute; first let's
talk about monkey patching.
Monkey Patching
What is monkey patching, anyway? Wikipedia defines it as "a
way to extend or modify runtime code without altering the original
source code for dynamic languages". If you're a Rails user, you've
already been merrily enjoying the benefits of monkey patching:
>> strs = %w{monkey patch}
?> strs.map(&:pluralize)
=> ["monkeys", "patches"]`
(Hint: neither String#pluralize nor the no block/one-argument form of
Enumerable#map exist in the standard library; both are grafted on at
run-time by ActiveSupport)
Anyway, the Python community frowns on the practice. In
fact, the term "monkey patch" comes from the Python community, and is
actually meant as a pejorative. The Ruby community, on the other hand,
is more tolerant of the practice. Chad's post, "The Virtues of
Monkey Patching", is a fantastic real-world example of how
monkey patching can be beneficial. When is monkey patching appropriate,
and when should it be avoided? Here's my rule of thumb:
Paul's Rule of Monkey Patching
Libraries should not modify underlying classes at runtime unless that
is their express purpose and applications should ignore what I just
said.
How does monkey patching apply to Technorati-Ruby? Well, it doesn't, or
at least not directly. I didn't want to extend the standard library for
little old Technorati-Ruby, and I didn't really want to sub-class Hash
either. Fortunately, I had another option: just in time convenience
methods, the sneaky and verbosely-named cousin of monkey
patching.
Just in Time Convenience Methods
A just in time convenience method is a convenience method that is
added to an instance of a class, rather than the class itself.
Jamis and Marcel both have more to say about them, but here's
what they look like:
nog_str = 'delicious egg nog'
def nog_str.de_nog
gsub!(/egg nog/i, 'apple juice')
end
nog_str.class
=> String
nog_str.de_nog
=> "delicious apple juice"
As you can see, nog_str is still a String, just with a little more
personality. You can also use Object.instance_eval:
class A
private
def secret
'secret message'
end
end
>> a = A.new
>> a.secret
NoMethodError: private method `secret' called for #<A:0xb78b9fb8>
from (irb):40
>> a.instance_eval { secret }
=> "secret message"
Which brings us back to Technorati-Ruby. First, I added a bit of code
to jazz up result hashes with convenience methods:
def magify_hash(hash)
hash.keys.each do |key|
meth_key = key.gsub(/\//, '_')
hash.instance_eval %{def #{meth_key}; self['#{key}']; end}
end
hash
end
Second, I wrapped the result hashes in magify_hash. Third? There
wasn't really a third step, so I just sat around for a few minutes
feeling smug. By the way, here's that example code from the beginning,
updated to use the shiny new convenience methods:
# find sites linking that link to me
results = tr.cosmos('pablotron.org')
# print an excerpt from each item
puts results.items.map { |item|
[item.url, item.excerpt]
}
So, problem solved. Just in time convenience methods satisfy all my
requirements: they're backwards compatible, don't require me to create a
new class or sub-class Hash, and they allow users to write cleaner
code. Not bad for a sneaky pejorative.
|
|
 |
 |
|
 |
|