Community Garden?
So, out of a certainly level of idle curiosity, a few months back I decided to contact my community league1 to find out what would be involved in getting a Community garden started in my area. Community gardens are, to me, an intriguing concept: get access to some land (either city property or donated private property), get members of the local community together, and then grow food! Of course, it’s particularly interesting to me as a guy who’s always lived in a small house with little to no room for a garden, leaving a community garden as the only option I’d have to get access to a decent sized plot of land. And I suspect, deep down, I’m actually a closet hippy yearning for a commune…
Of course, there’s no shortage of community gardens in the city, but gaining access to them can be tough, and none are particularly close to my home. Meanwhile, I live along a rather large hydro corridor, which means a ton of seemingly under-utilized greenspace, in a neighbourhood dominated by small homes with tiny yards, or high density residential in the form of three-story condo blocks who, needless to say, have no yard at all. So it would seem like the kind of area where a community garden would flourish.
And so I emailed my local community league, and then promptly put the whole idea out of my mind. I tend to have a short attention span like that. So colour me surprised when a few weeks later I received a reply from the current league webmaster indicating that she’d be very happy to bring the idea to the league board… she just had one question: would I be willing to take point on this project?
And it may be totally crazy, but… I said yes. So, she’ll be bringing the topic up to the board this week, and all signs indicate that they’ll provide their support, which means the ball may actually start rolling on this.
Uhoh.
-
Fun fact: community leagues in Edmonton are quite powerful compared to similar organizations in other cities (Edmonton was also the first city in Canada to adopt these kinds of organizations). If you want to have an influence on politics in your area, the two most important things you could possibly do are a) vote for your city councillor, and b) get involved in your community league, as they typically handle park development (including skating rinks, playgrounds, and so forth), manage local community programs, and get involved in land use and transportation issues. ↩
-
Sometimes You Actually Have To Rewrite It
So, a couple years back I started doing some subcontracting work for a buddy of mine who runs a little ColdFusion consultancy. As part of that work, I took ownership of one of the projects another sub had built for one of his client, and the experience has been… interesting.
See, like PHP and Perl, ColdFusion has the wonderful property of making it very easy for middling developers to write truly awful code that, ultimately, gets the job done. And so it is with this project. My predecessor was, to be complementary, one of those middling developers. The codebase, itself, is a total mess. Like, if there was a digital version of Hoarders, this code might be on it. But, it does get the job done, and ultimately, when it comes to customers, that’s what matters (well, until the bugs start rolling in).
Of course, as a self-respecting(-ish) developer, this is a nightmare. In the beginning, I dreaded modifying the code. Duplication is rampant, meaning a fix in one place may need to be done in many. Side effects are ubiquitous, so it’s difficult to predict the results of a change. Even simple things like consistent indentation are nowhere to be found. And don’t even dream of anything like automated regression tests.
Worse, feeling no ownership of the code, my strategy was to minimally disturb the code as it existed while implementing new features or bug fixes, which meant the status quo remained. Fortunately, around a year ago I finally got over this last hump and made the decision to gradually start modernizing the code. And that’s where things got fun.
One of the biggest problems with this code is that data access and business logic are littered throughout the code, with absolutely no separation between data and views. And, remember, it’s duplicated. Often. So the first order of business? Build a real data access layer, and do it such that the new code could live beside the old. Of course, this last requirement was fairly easy since there was no pre-existing data access layer to live beside…
So, in the last year, I’ve built at least a dozen CFCs that, slowly but surely, are beginning to encompass large portions of the (thankfully fairly simple) data model and attendant business logic. Then, as I’ve implemented new features or fixed bugs, I’ve migrated old business logic into the new data access layer and then updated old code to use the new object layer. Gradually, the old code is eroding away. Very gradually.
Finally, after a year of this, after chipping away and chipping away, finally, while there’s still loads of legacy code kicking around (including a surprising amount of simply dead code… apparently my predecessor didn’t understand how version control systems work–if you want to remove code, remove it, don’t comment it out!), the tide is slowly starting to turn. More and more often, bugs that need to be fixed are getting fixed in one place. New features are able to leverage the object layer, cutting down development time and bugs. And some major new features coming down the pipe will be substantially easier to build with this new infrastructure in place. It’s really incredibly satisfying, in a god-damn-this-is-how-it-should-be sort of way.
The funny thing is, this kind of approach goes very much against my natural instincts. Conservative by nature, I’m often the last person to start rewriting code. However, if there’s one thing this project has taught me (along with a couple wonderfully excited, eager co-workers), it’s that sometimes you really do have to gut the basement to fix the cracks in the foundation. And sometimes, you just gotta tear the whole house down.
- (https://b-ark.ca/SSi_SS)
Well, yet another long blogging hiatus. So what’s so important that I would take the time to author yet another scintillating installment? Why, a knitting project, of course!
Review: Last Chance to See
New York Times bestselling author Douglas Adams and zoologist Mark Carwardine take off around the world in search of exotic, endangered creatures.
Join them as they encounter the animal kingdom in its stunning beauty, astonishing variety, and imminent peril: the giant Komodo dragon of Indonesia, the helpless but loveable Kakapo of New Zealand, the blind river dolphins of China, the white rhinos of Zaire, the rare birds of Mauritius island in the Indian Ocean. Hilarious and poignant—as only Douglas Adams can be—Last Chance to See is an entertaining and arresting odyssey through the Earth’s magnificent wildlife galaxy.
Douglas Adams is, of course, most famous for his work on the Hitchhiker’s Guide to the Galaxy books, but if there was one piece not related to HHGTTG by DNA that I wish people would read, it would be this one.
Mr. Adams was deeply fascinated with the natural world, and this love for the world around him absolutely shines through in this book, wherein Mr. Adams records his experiences traveling the world, encountering various endangered species in their natural habitat. His wonderful observational skills, and more importantly, incredible talent for putting those observations on paper in his wry, witty way, allow him to truly draw the reader into his experiences, and to feel his awe and reverence for the things he, well, had a rare chance to see.
At once sad and hopeful, I think some of his best writing is done in this volume.
Mr. Adams has said he was most proud of this book. If you ask me, he was right to be.
Update (2020-02-26):
Now, eight years later, I have to admit, this book still leaves me feeling incredibly bitter sweet.
On the one hand, the Kakapo has seen genuine success, with the Kakapo Recovery programme demonstrating the power of intense intervention to save endangered species. On the other hand, the Northern white rhinoceros is now completely extinct, having disappeared in the wild and died off in captivity.
I will forever be sad that Douglas Adams died as young as he did. However, I can’t help but wonder how he’d feel if he saw how little progress we’ve collectively made in honouring and protecting the world in which we live.
A Vim Tip - localvimrc
Inspired by vim: revisited, I thought I’d finally get around to writing up another blog post, this time focused on one of my favorite Vim plugins: localvimrc.
As even the most basic Vim user knows, Vim, upon startup, sources a file in the user’s home directory called .vimrc (sometimes _vimrc or other variants, depending on the platform). Traditionally, this file is used to store user customizations to Vim. We’re talking things like settings, user-defined functions, and a whole raft of other stuff. But it has a rather annoying limitation: it’s global. Of course, it’s possible to condition a lot of settings based on filetype and so forth, but ultimately this isn’t useful if you want to be able to specify settings at a project-level (for example, build settings, search paths, fold settings, etc). And this is where the localvimrc plugin comes in.
With localvimrc loaded, Vim, upon opening a new file or switching buffers, will search up through the directory hierarchy, starting from the location of the file, to find a file named .lvimrc. If such a file is found, the file is sourced just like any other vimrc file. So now, you can place those project-specific configuration items in a .lvimrc in the top-level folder of your project, and voila!, you’re good to go.
Of course, this alone is pretty damned useful, but there’s another somewhat less obvious but handy feature of localvimrc files: they make it possible to find the root directory of your project. And that is exceptionally useful for a few purposes:
- You can set up CommandT to always search from the top of your project, regardless of where you invoked Vim. I love this because I tend to navigate around in the shell and then edit files willy-nilly.
- You can configure project-level build commands which understand how to jump to the top of your project to run them.
- You can set up the Vim search path so that gf always works.
- You can load up project-wide cscope and ctags files.
- Probably lots of other stuff.
So, how does this work? Well, below is a sample of one of my lvimrc files:
if (!exists("g:loaded_lvimrc")) let g:loaded_lvimrc = 1 let s:rcpath = expand("<sfile>:p:h") exec "map <leader>t :CommandTFlush<cr>\\|:CommandT " . s:rcpath . "<cr>" exec "set path=" . s:rcpath . "/**" endif
The first thing you’ll notice is the guard. The lvimrc file is loaded whenever a buffer switch occurs, so this allows you to control which things are evaluated every time the file is sourced and which are only executed once.
Anyway, the real magic is in the subsequent lines. First, we use the expand() command to get the canonical path to the file being sourced (remember, this is our .lvimrc file, so this will be the top-level directory of our project). Then, we use that information to remap the CommandT command to run from the top-level project directory. Nice!
And, as I mentioned, you can do a lot of other things here. You can see the second line sets up our search path so we can gf to files in the project, as an example. Personally, I actually created a function in my .vimrc file called LocalVimRCLoadedHook(rcpath) that contains a lot of standardized logic for handling projects. You can find samples of all that on my Vim-Config GitHub Project.