Happy New Year
describe "Year 2008" do
it "should be happy" do
Date.new(2008, 1, 1).year.should be_happy
end
end
Best wishes to all my readers for a happy 2008!
describe "Year 2008" do
it "should be happy" do
Date.new(2008, 1, 1).year.should be_happy
end
end
Best wishes to all my readers for a happy 2008!
I hope this helps someone. After installing Leopard, I had some repair work to do. Here is a summary of what I’ve done.
First, ruby and gem both worked, which made me happy.
Next, I re-created the usual directories in /usr/local to install software there. My intention was to install ruby there by building it from source, but I ran into problems I just didn’t feel like trying to solve, so instead, I decided to stick with the stuff that Apple shipped with Leopard.
I use PostgreSQL, so I needed to re-build and re-install that. Since my TextDrive server uses v8.0.x, I decided to install a version from the same minor release level, which was 8.0.14. I downloaded that from here and installed it with the usual commands:
./configure make sudo make install
This installed PostgreSQL into /usr/local/pgsql/*. I then added some configuration to /etc/profile to make PostgreSQL available on the system path.
PGHOME=/usr/local/pgsql export PATH=/usr/local/bin:/usr/local/sbin:$PGHOME/bin:$PATH export PGDATA=$PGHOME/data
After re-starting my shell, I could use the PostgreSQL utilities, so I then initialized the data directory. Since I use the user postgres to manage my databases, I initialized
sudo mkdir /usr/local/pgsql/data sudo chown -R postgres /usr/local/pgsql/data su - postgres initdb /usr/local/pgsql/data exit
Next on the list was installing the postgres gem, which I learned how to do here. With that done, I could try running one of my Rails applications again. Of course, I couldn’t do that as my normal user jbrains because of this
mel:jbrains.info jbrains$ createdb weblog_development createdb: could not connect to database template1: FATAL: user "jbrains" does not exist
I want to be able to drop and create databases as jbrains to make it easier to run tests through rake, so I added the user in PostgreSQL.
su - postgres mel:~ postgres$ createuser -a -d -P jbrains Enter password for new user: Enter it again: CREATE USER exit
Next I created my Rails development database and migrated it to the current schema version. Finally, I could run the legacy tests and my new specs.
createdb weblog_development rake db:migrate rake test rake spec
In the process, rake identified some missing gems, which I installed and froze to the project. After that, I could resume work on my Rails projects. I’m keeping an eye on this space for instructions on building Ruby on Leopard.
I would like to thank heartily all the people who published instructions to help me get back to this point relatively quickly. I don’t know what I’d do without you guys. If you ever meet me, remind me that I owe you a beer.
I am running a session entitled Refactoring: Where Do I Start? at the first Agile Development Practices conference. Although I plan to speak for a few minutes, I’d like to spend most of the time answering your questions and refactoring some real code on stage. As a result, I’d like your code! I have a sample code base to refactor, but I’d rather refactor your code, to show everything that goes into refactoring: learning a code base, making some initial small refactorings, then envisioning how they can collect into something bigger and more significant. I put out the challenge to you, then: give me your code and I’ll refactor it!
Here are the guidelines:
A request: if you can send the code to me as an Eclipse project, that would be great. It’s not absolutely required, but it would help. If I can’t get the code compiling and running in Eclipse within 15 minutes, I’ll probably give up and move on.
If you have a code base you’d like to send me, please e-mail me at refactoring the beautiful at sign diasparsoftware the dazzling dot com and I’ll give you instructions where to send the code. Thanks!
Since I have been spec-driving Rails code, and since I have very limited table space at home right now, I have been experimenting with something I’d never liked before: an electronic test and refactoring list. So far, it’s not too bad.
Like many people, I like to avoid keeping lists in my head, since I tend to forget things. Normally, I use an index card and write tests from the top and refactorings from the bottom, crossing each out as I perform them. It works well. So well, in fact, that I generally question anyone who attempts to use an electronic system, rather than a paper system. The idea, of course, is that we tend to fixate on electronic systems, whereas we use paper systems simply and quickly. Using the computer for anything that doesn’t benefit from automation seems counterproductive to me. Still, since we’re low on table space, I’ve had to try something else, and RSpec gives me the opportunity to maintain a test list without having to implement multiple failing tests (or specs) at once.
With RSpec, one can describe a test with prose without implementing it, simply by invoking it without a block.
describe "The thing I'm spec-driving" do it "should do something important" it "should do something else important" it "should do this third, equally important, thing" end
When it’s time to implement the spec, add the corresponding block. In the meantime, RSpec reports the other specs as “pending”, rather than attempting to execute them. I had never thought it was a good idea, before, but I’ve been trying it recently, and I’m less annoyed by it than I used to be. That might be because I’m more comfortable spec-driving than I was years ago when I started; but it might just be because my personal taste has changed. I can’t say. What I can say is that I haven’t managed to get lost yet, and it takes little extra effort to describe a handful of specs up front. If it starts bothering me, I’ll be sure to describe my experience.
Recently, I integrated Textile into this blog via RedCloth. As I started to write articles in my Adventures in RSpec series, I found I wanted to use footnotes. Since Textile supports them, I figured I was in luck; however, I soon found a hyperlink collision when two fragments of Textile markup appear on the same page, each with the same-numbered footnote. RedCloth simply generates a hyperlink to target fn1 for footnote #1, so if there are two footnote #1s on the same page, they both link to target fn1, making it the equivalent of a race condition.
I looked for guidance to the Textpattern folks. A certain Mary told me that Textile has fixed this problem, but likely RedCloth has not. After some investigation, I agreed that this was the case. I looked through the Textile source, to the extent I can understand PHP, and saw their fix was simple: keep a table of footnote numbers to unique IDs, then use the unique ID in place of the number in the hyperlink and target. I figured that I could do that.
It took a couple of hours, and I’ll spare you the details. Here is what I wrote:
require 'digest/sha1'
class UniqueFootnoteIdGeneratingRedCloth < RedCloth
def initialize(markup)
@footnote_ids_by_number = {}
super(markup)
end
def next_footnote_id
# SHA1 isn't significant; I just figured it'd make a good unique ID
Digest::SHA1.hexdigest(rand(2**64).to_s)
end
def to_html(*rules)
self.scan( /\b\[([0-9]+?)\](\s)?/ ) do |match|
@footnote_ids_by_number[$1] = next_footnote_id
end
super
end
private
def footnote_ref(text)
text.gsub!( /\b\[([0-9]+?)\](\s)?/ ) do |match|
"<sup><a href=\"#fn#{@footnote_ids_by_number[$1]}\">#{$1}</a></sup>#{$2}"
end
end
def textile_fn_( tag, num, atts, cite, content )
atts << " id=\"fn#{ @footnote_ids_by_number[num] }\""
content = "<sup>#{ num }</sup> #{ content }"
atts = shelve( atts ) if atts
"\t<p#{ atts }>#{ content }</p>"
end
end
I ended up copy/pasting more code than I wanted to, so I’ll have to submit something to why for his perusal. Perhaps this will make it into a future version of RedCloth.