The weirdest code I've seen recently
I was kicking around in ActiveResource::Base recently and it took me a good solid ten minutes to figure out why the prefix method didn’t recur infinitely.
def prefix(options={})
default = site.path
default << '/' unless default[-1..-1] == '/'
# generate the actual method based on the current site path
self.prefix = default
prefix(options)
end
def prefix_source
prefix # generate #prefix and #prefix_source methods first
prefix_source
end
def prefix=(value = '/')
# Replace :placeholders with '#{embedded options[:lookups]}'
prefix_call = value.gsub(/:\w+/) { |key| "\#{options[#{key}]}" }
# Redefine the new methods.
code = <<-end_code
def prefix_source() "#{value}" end
def prefix(options={}) "#{prefix_call}" end
end_code
silence_warnings { instance_eval code, FILE, LINE }
rescue
logger.error "Couldn't set prefix: #{$!}\n #{code}"
raise
end
Do you see it? When prefix is called, it calls prefix=, which redefines prefix and returns. prefix in turn returns by calling not itself but the newly-created method of the same name.
I am not known for my low tolerance of metalanguage hackery (exhibit). But I do have my limits, and this exceeds them; calling it needlessly obfuscatory would be kind. Or am I wrong? Is there no better way to provide a method with the same semantics?
Marketing Ruby
Scheme, a variant of Lisp popular in academic settings, has no download link on its extremely minimalist home page. If you click Implementations, it will list about fifty and recommend about ten. Visit the Ruby homepage and you are presented with a modern, polished, attractive site and a large, friendly Download Ruby link.
Marketing isn’t always about advertising. If you believe in a product, present it to the world in a way that makes it easy for others to believe in. It’s easy to be cynical about appearances, but they are, here and now as they have ever been, important. This principle is extended deeply into the Ruby language itself. From a technical standpoint, Ruby does very little that other languages don’t, but the metaprogramming hooks it makes available to users are straightforward and user-friendly and make its users feel immediately powerful. The elaborate contortions (do watch the presentation if you can, it’s awesome) that the language itself must go through in order to provide a convenient interface to the user doesn’t detract from the net result. Simplexity sells.
Ruby and, now, Rails have been around for long enough that it seems, at least to me, that most people who were ever going to have an opinion on it now do so. But accusations of hype are and always have been overblown; I would go so far as to call that particular brand of cynicism a kind of intellectual laziness convenient to those don’t understand a phenomenon and don’t particularly want to. Regardless of whether or not Ruby and/or Rails are here to stay (and I think they are, but then, I’m an optimist), it would be foolish to ignore the lessons here.
Posted in Professional | no comments |
Speeding up ActiveResource
I’ve been knocking around ways to speed up ActiveResource recently. My colleague Tim Cochran discovered that you take a big performance hit from Hash.from_xml (which uses XmlSimple to transform the parsed XML into a hash with a particular structure) and I’ve knocked up a couple of alternatives, one for libxml-ruby and one for Hpricot. I haven’t packaged them up into a plugin yet, but I’ll attach the raw source, and hopefully that’ll help someone.
There’s already at least one other attempt to adapt libxml to ActiveResource floating around, but as far as I can tell it doesn’t work: it doesn’t place the resulting XML in a form that allows ActiveSupport to successfully undasherize the keys, deserialize primitives by their type attribute, and place the result in an ActiveResource object (though it is of course possible that I configured the library incorrectly). I’ve tested the parsers below against the corresponding XmlSimple call and I know that they succesfully deserialize into the desired end result.
- libxml (extends XML::Document with a to_hash method, roughly 5-10x faster than XmlSimple)
- hpricot (extends Hpricot::Doc with a to_hash method, roughly 3-5x faster than XmlSimple)
Use them like this:
module ActiveSupport
module CoreExtensions
module Hash
module Conversions
module ClassMethods
# libxml
def from_xml(xml)
xml.gsub!(/\s*\n\s*/, '')
typecast_xml_value(undasherize_keys(XML::Parser.string(xml).parse.to_hash))
end
# hpricot
def from_xml(xml)
typecast_xml_value(undasherize_keys(Hpricot.XML(xml).to_hash))
end
end
end
end
end
end
Posted in Professional | no comments |
Six Months with NetBeans on Rails: A Retrospective
I’m at RailsConf this weekend, capping a six-months engagement delivering a couple of Rails apps written using NetBeans as our team’s primary Ruby editor. We ended up with it because the client requested that we do our all development work in Ubuntu 6.06, and because we couldn’t build a consensus around a more lightweight editor like Vim or jEdit. I thought I’d share some of my thoughts on it for anyone’s who’s interested in switching.
Executive Summary
There’s a lot to love and a fair amount to hate, but it’s a solid alternative to TextMate if you’re not on a Mac.
Stuff I liked
- The basic refactoring support is surprisingly handy. Until I got back the ability to rename classes and methods I hadn’t realized I’d missed it. I’m told that Aptana can perform similar tricks, but it’s been a while since I’ve tried it out.
- Likewise, the ability to jump directly to a class definition is handy, although it isn’t perfect. (If you have more than one class of the same name defined but located in different files or scoped to different modules it can’t figure out which one, exactly, you’re referencing, which I suppose is understandable.)
- RSpec support! A must-have. And the ability to jump back and forth between test and class… most of the time.
- If you’re a Vi user, the jVi plugin is almost worth the price of switching purely on its own. It’s a truly excellent piece of software, with an enormous amount of tweakability and really support for Vi constructs, and one of my complaints with Vim itself has always been that it lacks good project/directory browsing support, and yes, I’ve tried the Project plugin… again and again and again.
- It knows to insert an “end” when I hit enter after a block or method definition. Just a stupid small thing, but I miss it now when I don’t have it.
Stuff I didn’t like
- It opens up a new output window each time you hit Shift-F6 to run a test, leading to a million open output windows after you’ve been using it for a while. This is an enormous pain in the ass, and it’s compounded by the problem of really poor tab management support in the section of the IDE that displays your previous test runs. This is my single biggest complaint.
- The “jump to file” functionality doesn’t insert automatic wildcards the way TextMate does. This drives me absolutely nuts and it’s something I miss desperately.
- Method autocomplete doesn’t work well and is far more trouble than it’s worth. I turn it off almost immediately.
- It does not, and here I am being charitable, have the most attractive design on the face of the planet. I realize that by stating this I am probably slagging the work of some diligent UI designer somewhere, and I realize that you have to work within the constraints of Swing themes across multiple platforms. But it doesn’t stack up well next to the clean design of TextMate, or the brand new, achingly sexy (YMMV) MacVim.
Lessons Learned
- Use a nightly build, and keep it fresh. It’s the only way to get support for stuff like RSpec. The nightly builds have been stable and make for happy funtimes.
- Spin up your dev server on the command line rather than using the builtin server runner. Maybe it’s just me, but using an IDE for this just doesn’t seem worth the trouble.
If you’ve spent any time working with Ruby in NetBeans I’d be curious to hear about it.
Posted in Professional | no comments |
Waitin' for the spam to come rolling in
Aaron says, in the comments:
You’d better put a captcha or something on here soon. I predict that you can survive about 15 days without it before each and every post is overrun with spam comments.
Call it an experiment. I started this blog last Thursday. If by next Friday I don’t have bot spam then… well, I guess I’ll continue to be lazy. If I start to see some then I’ll know that the world has discovered my existence and put up a CAPTCHA.
I’m using Typo as my blog software, which is written in Ruby on Rails, which I know well, so theoretically I could go in and hack together my own solution. I wrote a math CAPTCHA some time ago as an experiment; maybe it’s time to dust it off.
Aaron Leans On PISA
Air reports that work continues apace on PISA, a web application designed to ease short-term financial planning and money management for struggling, irresponsible twentysomethings like ourselves. For a couple of months we were working furiously on it but I found I had to drop the commitment due to insane amounts of schoolwork.
I still really like the idea of the project, but I was surprised by how difficult it is to make financial calculations that are both helpful and reasonably accurate. Our thesis was essentially that there should be a metric, The Number, which accurately reflects the amount of “spending money” in one’s pocket on any given day. A brief quote from our project wiki:
The Number
The amount of money you have available in your pocket, on any given day, to spend on whatever you like. Calculated after bills and budget have been factored in.
Our second thesis is that when you are building an application geared towards irresponsible twentysomethings you cannot count on conscientious and reliable data input.
It turns out that you have to resolve all sorts of very difficult things before this becomes feasible. You need an accurate budget, calibrated reliably from week to week. You need a reasonably good description of the transactions that have occured in your day-to-day bank account. You need to figure out credit card charges and debts. And so forth.
We think we have a reasonable solution and it looks like Air’s churning away on it. I look forward to seeing what he comes up with and I’ll let you know if he releases a public prototype.
Fun with hosts, virtual and otherwise
I’ve had a glorious time setting this thing up, a time of sunshine and love. Blessed are the editors of config files, for only they live life to its fullest.
I had originally wanted this blog to be a subdirectory of the main domain but after hours of effort I’ve largely given up. It essentially comes down to aesthetics–do I prefer blog.brianguthrie.com, or brianguthrie.com/blog–which I freely admit is a highly esoteric issue, especially given that the former is considerably easier to set up. But I followed these instructions to the letter, and many others, and I found that no matter what I did, all of the URLs worked fine within Mongrel and were completely broken after they got passed through the proxy.
Once you’ve gotten so deeply into the problem that you start to classify the explanatory articles in your browser by their color scheme it’s probably time to look for a simpler solution. Perhaps someday I will move this blog to another URL, but I fear, dear reader, that today is not that day.