Force-feeding Myself Emacs

I am a Vim guy. I run the @vimtips Twitter account. I have given Vim presentations. I maintain a couple Vim plugins (kinda). I have cultivated a list of various helpful Vim links. My point is that I really like Vim. I might even love it. Who am I kidding? I definitely love Vim.

However, I am going to use Emacs every day for the month of February.

I want to challenge myself. I want to learn more about Emacs. I want to understand why so many of our industry’s elites have, in the short history of computer programming, loyally and sometimes fanatically used Emacs. I want to have a little fun.

Thankfully, I know several people using Emacs. I asked for some advice as to how to hit the ground running on February first (via Twitter, among other means). In case you would like to try Emacs also, I thought I would document the helpful suggestions I received.

Suggestions for Getting Started

Five people responded (@tihm, @kyleashipley, @gregors, @damionjunk, and @mediocretes). Four of them recommended the Emacs Starter Kit. That sounds like a ringing endorsement!

Damion also suggested installing Emacs 24 via Homebrew (as I’m on a Mac). That lead me to the article Emacs 24 Rails Development Environment – From Scratch to Productive in 5 Minutes, from which I expect I’ll rip some ideas.

Nate (mediocretes) also suggested his fork of Expected Behavior’s common-files, and added “now with twittering-mode” which sounds both wonderful and awful.

Of course, there is Emacs' Vim Mode. I will have to try that before February has run its course.


That seems like a pretty good start. I hope. I would like to learn a little elisp, and write an extension perhaps, but I doubt I’ll get that far.

Wish me luck. If nothing else, by the end of the month, I will at least be able to say I’ve been, albeit temporarily, on both sides of the Editor War.

Combining FactoryGirl's Generated Files into One

If you are using Thoughtbot’s FactoryGirl in a Rails 3 app, you are probably accustomed to the library generating a new file per factory/model it generates. You end up with something like this:

$ ls test/factories
 things.rb other_things.rb more_things.rb omg_things.rb

I really dislike it generating a file per factory. I prefer one file in which I can see each factory I will be using in my tests. I am, evidently, the odd man out. I dug around the Interwebs a bit, unsuccessfully. This led to me fixing it myself witha Rake task:

namespace :factories do
    desc 'Combine individual factory files into a single file'
    task :combine do
        File.open(File.join(Rails.root, 'test', 'factories.rb'), 'a') do |f|
            Dir.foreach(File.join(Rails.root, 'test', 'factories')) do |factory|
                next if factory == '.' or factory == '..'
                full_path = File.join(Rails.root, 'test', 'factories', factory)
                text = File.read(full_path)
                f.write(text)
                puts "Removing #{full_path}..."
                File.delete(full_path)
            end
        end
        puts "Removing the factories directory..."
        Dir.rmdir(File.join(Rails.root, 'test', 'factories'))
        print "Done."
     end
end

I run that whenever I have generated a new model or resource (and thus a new factory file).

Using ZSH to Rename in Rails

At the Indy.rb Code Review Session (11-30-11), Dan Doezema asked if there was an easy way to rename a resource, or the related model, controller, view directory, tests, and potentially factory or fixture. We had a good laugh after someone mentioned that being one of the features that lure people to try Smalltalk, or, perhaps, the Ruby VM MagLev. The joke is that doing either of those two things is very likely a road to compromised mental health.

A Christmas Miracle!

This renaming issue was on still bouncing around inside my mind as I began reading the first day of this ZSH-focused advent calendar. Hey, look at that! Between day one and day two, one can piece together a nice line for renaming the files related to a resource in Rails.

$ cd project_root
$ zmv '(**/)old_name(*)' '$1new_name$2'
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#   deleted:    app/controllers/old_names_controller.rb
#   deleted:    app/models/old_name.rb
#   deleted:    app/views/old_names/new.html.haml
#   deleted:    test/unit/old_name_test.rb
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#   app/controllers/new_namess_controller.rb
#   app/models/new_name.rb
#   app/views/new_names/
#   test/unit/new_name_test.rb
no changes added to commit (use "git add" and/or "git commit -a")

Santa’s Little Helper

That is only half of the problem, though. In fact, it’s arguably the easier-solved of the two halves, whether you use Bash, ZSH, or something completely different. How are we going to edit the content of the files? After the above command, we’re still stuck with this:

$ vim app/models/old_name.rb
class OldName < ActiveRecord::Base
  # ...
end

More command-line work to the rescue!

$ git ls-files --other --exclude-standard | xargs sed -i '' 's/OldName/NewName/'
$ vim app/models/old_name.rb
class NewName < ActiveRecord::Base
  # ...
end

Great! Two lines of terminal work and we’ve reached our goal!

Good Enough

This isn’t perfect. You still might have to change other references to the class, such as a has_many :old_items line in another class, or something similar. If you have a better method you’ve been employing (short of installing an IDE), I would love to hear it!

Y U NO LIKE VERGE

Today, Anthony Panozzo mentioned Verge’s new “qualifying question” policy, in which you essentially must be a startup employee or founder to attend. I seemingly took that opportunity to pile on Verge, like some kind of entitled asshole. That wasn’t my intention, I swear! At least, it wasn’t consciously my intention. Let me clarify.

Quick aside: Matt Hunckler and company have put in good, hard work on this event. I do not mean to disparage him, others who helped, or those who attend. I am not saying the event isn’t a worthwhile event. SPOILER ALERT: I’m saying it’s not my thing, basically.

Living in an Alternate Reality

Verge used to be called Hackers & Founders. Unfortunately, calling an event Hackers & Founders creates a set of expectations. Let me quote from the original Hackers & Founders site:

It’s mostly a chance to get together with hackers who are founding or are interested in founding startups. Many of us hang out at Hacker News. So, if you’re in the area and interested in chatting with people of like mind, please stop by. We’d love to get to know you.

… and, from the description of a recent meeting:

Topics of conversation include hackery in general, startups, shiny new technologies we’re playing with, recent articles on Hacker News and miscellaneous cool stuff.

That is what I expected when I first attended a meeting. It wasn’t quite that, but it was fairly casual, and in the back of a bar/restaurant. It had an intimate feeling to it.

I think I probably should have, both in this instance, and in general, a more open mind. I think there is a good chance I went in wanting Mountain View’s Hackers & Founders, and I wasn’t willing to settle for less.

Love What You Got

I wanted to like Verge, and attended a couple other events. I had a fine time. I mean, beer, a festive atmosphere, Earthhouse, excited people… it’s easy to enjoy. Afterward, however, I always felt like the event wasn’t really for me. I also felt that I should continue to support the thing, because it’s good for Indy. (Of course, then I opened my big mouth / typing fingers on Twitter today.)

It’s hard to explain what about Verge didn’t hit the groove for me. Again, I think it’s because I was still wanting Hackers & Founders. I wanted, “Man, we’re using Node.js to build this awesome real-time client-smiting application. Yeah, it’s evented as hell!” … uh, or something. Instead, it is more high-level, more business-y, more network-y, more… more…? Seriously, I am not sure I can properly articulate my problem.

You Don’t Need Me

When Anthony and Kyle Shipley began discussing Verge, and the qualifying question policy, this morning, I jumped up to say I didn’t like this incarnation of Verge, basically. You can start with this tweet, if you’d like to read more. Also, read this blog post from Anthony.

Anthony, in that post, says that this makes Verge more interesting for him. It essentially targets him directly, now. That is a good thing! Someone feeling like Verge is more relevant is, I’m sure, exactly what Matt was going for. That it also excludes people fairly directly is also what Matt was targeting. Matt is always really nice to me, even when he explicitly invites me to stuff and I don’t attend. I am guessing he wasn’t expecting that I would feel excluded. Still, it’s a good thing. Creating a group who feels explicitly included is important. Excluding people is an acceptable consequence, I think. You don’t need me. You need the Anthonys, Matt Gordons, Kyle Shipleys, etc.

What About Hackers & Founders

Does this leave space open for a new meeting that is in the spirit of the original Hackers & Founders? I think so. I have a serious question for those who might be interested, though. Does the Indy Hackers Bar Meet do that sort of thing already? Once a month we get together at a bar and chat over beers and food. The biggest difference I see is that I have never made Indy Hackers even almost focused. A few of us talked about posts on Reddit last time — we’re talking poorly drawn comics and dumb pictures with dumber captions. However, we also talked about what we’re doing at/for work lately, etc. The Venn diagram would be a huge circle labeled Indy Hackers Bar Meet Topics, with a little circle inside it labeled Hackers & Founders Topics. Is a combination of the Indy Hackers Bar Meet and Indy.rb, Indy.js, et cetera, good enough?

I don’t want to change Indy Hackers Bar Meets. So, what do you think? Do we need a Hackers & Founders meeting, in the same vein as Mountain View’s Hackers & Founders?

Deprecation warnings for proxy_owner in Rails 3.1

In Rails, you are used to doing something like this:

has_many :assignments do
  def root
    proxy_owner.assignments.where(:ancestry => nil).first
  end
end

This way, if you call parent_record.assignments.root, the root method acts on the array of assignments that belong to that parent. It’s nice. However, in Rails 3.1 you will see a big scary message in your logs, or in your test output.

DEPRECATION WARNING: Calling record.assignments.proxy_owner is deprecated. Please use record.association(:assignments).owner instead. (...)

I will admit that it is not very frightening, actually. It is mostly merely annoying… annoying as hell. Get out of my test output!

The working solution that I found looks like this:

has_many :assignments do
  def root
    @association.owner.assignments.where(:ancestry => nil).first
  end
end

This functionality is now defined in collection_proxy.rb, which was quite a bit of help in finding this solution. Bid those deprecation warnings adieu!

PS – I do not know whether this is the core-team accepted solution. I am certainly happy to see a better one!

Learned or Re-learned in My First 60ish Days as a Freelancer

Though it’s only been 60ish days [1], I have finished a few projects,some done well, maybe one done not-so-well. As I have battled my way through the fog of war, I think I have learned a few things worth mentioning. I have learned where I stand on the issue of payment: hourly or fixed-bid — with one possible exception. I re-learned that over-communicating is better than under-communicating. Finally, maybe most importantly, I learned that even when you lack any motivation to get things done, you can get things done.

Now, this isn’t all I learned. Freelancing has already been fantastic for my education and evolution as a developer. These are the notable,might-be-fun-to-discuss things. On to the show:

Fixed Bids > Hourly Work…

After 60ish days, I’ve decided a fixed bid is better than an hourly arrangement. One pro is the customer knows how much it’s going to cost beforethe project starts, which, it seems to me, typically results in a more comfortable customer. When the customer is more comfortable, I am more comfortable. Surprises can be fun, but not so much surprise invoices. Another check in the fixed-bid column is I can require 50% of the project’s cost upfront, which makes me happy, confident, comfortable, and excited to get started on the project.

I also enjoy the opportunity to attempt to “beat” my bid. In other words, I want to be more efficient than I thought I could be when I made the bid. I want to win. I want to deliver the same high quality final product the customer expects more efficiently than I thought I would. I think people call that a WIN/WIN. This is the primary reason I like fixed bid projects.

That said…

Except When Things Goes Awry

When a project is in a bad way, piling up like so many cars on a busy freeway, it’s easy to think “clearly I should only do hourly arrangements because: Wow! This sucks.” This is an obvious reaction, but, man, it is strong. It can also further sap your motivation, your gumption, as you begin resenting every hour you’re spending on that project. However, the things you can learn on a Pile-Up Project constitute a whole post of their own. A Pile-UpProject is a great chance to learn things that will be useful inwinning the next project.

So, forget it, fixed bid is still the greater.

Over-communicating is Way Better Than Under-communicating

Not asking questions that need answered, assuming an answer to a question you didn’t ask, and worrying about being annoying by asking too many questions are all things that I should not do. I know those. I knew those. I must have forgotten those. I re-learned them in the past 60ish days. You know a sure-fire way to create a Pile-Up Project? Do those things. Man, I’m angry about this. It doesn’t matter how many times it happens, I hate realizing I am repeating mistakes. Hate it. What is the consequence of over-communicating? What is the consequence of annoying someone? If the project gets done well, they’re going to forget they were annoyed. They might even be stoked about it. Over-communicate. Just… over-communicate. Honestly, it is easy.

I Can’t Always Be Motivated to Get Stuff Done, But I Can Always Get Stuff Done

I do not always sit down at my desk anxious to begin the day, excited to work on what it is that I need to work on that day. Some days, I don’t want to even think about the project about which I must absolutely think that day. You can’t always have that gumption [2]. You can always get stuff done, though. It’s difficult, and I’m not great at it. It is most difficult when I’ve just poured my coffee, opened my laptop, and realized I’ll probably have to put in 12 hours that day. Shit. If I don’t do something simple, like grab an index card and write down a list of things I need to get done, the day could go quite poorly. You know what I do every morning now? I grab a freakin' index card and write down what I need to get done.

I Cannot Wait to Learn More

I think I have learned some valuable things, and I am very excited to learn more in the next 60ish days. I suspect that freelancing is an incredibly effective way to learn stuff, as it is very much a classic “sink or swim” situation, a trial by fire, probably yet another cliché that I cannot recall at the moment. Maybe the most important nugget, though, is that it is a lot of fun.

[1] – It’s been more than 60 days now, but this essay was conceived at around day 63.

[2] – I am warming up a post about Zen and the Art of Motorcycle Maintenance, which speaks to gumption (approximately motivation) and its blockers.

Thank you to Dave Jones and Mike Rogers for reviewing, critiquing, and helping me to revise this essay.

DataMapper, Rails 3, and Multiple Databases

DataMapper is awesome. It’s flexible, you define the properties in the model itself, it deals with all sorts of columns, it can create UUIDs easily, it is fantastic for dealing with legacy, or just not designed with Rails’ ActiveRecord in mind databases. Hell, it shoveled my driveway, hooked up my cable, and delivered our beautiful, 7 pound, 2 ounce baby boy last Tuesday. (I kid! I don’t have a baby. Yet.)

It can also connect to multiple databases, even when used as the ORM in a Rails 3 app. Unfortunately, this isn’t mentioned on DataMapper’s website, that I could find. However, people with their wits about them (I am not in that set of people) might think to check out the README for the dm-rails project on Github. In there, it shows how to lay out your database.yml properly. It’s important. Go see it. Go. I’ll wait.

I mention this, and forced you to go look, mostly to help someone searching frantically. You there. Guy who has been searching for this frantically in futile frustration for an hour: Your journey is over. Let’s move on.

I had to do a bit of work to get RSpec and Cucumber behaving correctly. I want my test databases, or repositories, cleared after each test. I solved RSpec first, so we’ll start with that. My spec/spec_helper.rb looks something like this:

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'

Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  config.mock_with :rspec

  config.before(:each) do
    DataMapper::Model.descendants.each do |model|
      DataMapper.repository(model.default_repository_name).adapter.execute("SET foreign_key_checks = 0")
      DataMapper.repository(model.default_repository_name).adapter.execute("TRUNCATE TABLE #{model.storage_name}")
    end
  end
end

Clearly the code above is specific to MySQL. If you’d rather avoid shackling a specific database server to your app’s ankle, you might try something like database_cleaner.

The interesting part is probably DataMapper.repository(model.default_repository_name). I define self.default_repository_name differently for models that aren’t using, well, :default. That allows this to work (among other things in DataMapper). I recommend it. For instance:

class SecondaryUsinThing
  include DataMapper::Resource

  def self.default_repository_name
    :secondary
  end
  ...
end

I needed Cucumber to do some of this crazy junk also, of course. The dm-rails gem recommended a before and after block to add to a features/support/datamapper.rb, but I had to add a bit to mine to make it work.

Before do
   DataMapper::Model.descendants.each do |model|
     DataMapper.repository(model.default_repository_name).adapter.execute("SET foreign_key_checks = 0")
     DataMapper.repository(model.default_repository_name).adapter.execute("TRUNCATE TABLE #{model.storage_name}")
  end
  [:default, :secondary].each do |repository|
    DataMapper.send("repository", repository) do |repo|
      transaction = DataMapper::Transaction.new(repo)
      transaction.begin
      repo.adapter.push_transaction(transaction)
    end
  end
end

After do
  [:default, :secondary].each do |repository|
    DataMapper.send("repository", repository) do |repo|
      repo.adapter.pop_transaction.rollback rescue nil
    end
  end
end

Familiar, right? That should get your testing mojo rising. It’s basically opening the door for DataMapper, so he can come in and repaint your nursery while teaching your newborn sign language, or one of his many other talents.

Checking all Checkboxes with Capybara

This could be useful to someone searching the Interwebs for a solution. Hopefully it will save someone some time, as it took some time to figure it out. Looking back, I can see where someone might find it obvious. I didn’t, for some reason.

The following is how I accomplished it, using a CSS selector:

When /^I choose all of the damn checkboxes$/i do
  all('li.checkboxes input').each {|ch| check(ch[:id]) }
end

This requires that the checkbox input elements have a unique id attribute. You might, having some knowledge of Capybara’s Element class, think that you can just use #path, which returns an elements XPath string, in place of [:id]. That’s what I thought, and I welcome you to try it — what kind of hackers would we be if we believed it every time someone said something wasn’t possible? I, unfortunately, was unable to make it work. The check method reported that it could not find an element with said path (or XPath).

I’d love to hear it if you have better luck!

PPL30 Recap

It was 30 days. Thirty days gone. Thirty days of so little sleep as to feel like 60. Thirty days of so little liesure time as to feel like 15. Thirty days, each of which was determined to inflict exhaustion.

It was fun, though.

What Day Was Your Favorite?

The most frequent question asked of me with regards to the PPL30 is “Of the things you covered, what was your favorite?”. That has proven a more difficult question to answer than I had anticipated. I remember the first week, but vaguely. The last time I touched Redis was last year, right? However, it’s worth spending some time reviewing my own posts, in the hope that they will spurn memories and feelings to guide me to my favorites. In the end, there were two things that I’ve held onto through all the memory loss:

C

What?! C? Interesting? Are you mad? No. No I am not. Listen: I mentioned it when I reviewed it — there’s just something about C that I like. It feels powerful. It feels macho. It feels close to the metal. I’ve always felt inferior for only learning enough C to pass a course. Therefore, the first task I’m assigning to myself upon completion of the PPL30 is to finish The C Programming Language, or K&R.

Lisp

There were two Lisps on the list: Clojure, and Scheme. Between the two of them, Lisp was really the winner of the PPL30, if my affection was the prize. I enjoyed them so much that, upon completion of the final article (which covered Scheme), I ordered a used copy of The Little Schemer, which is sitting beside me now (and hardly seems ‘used’, much to my delight). Lisp seems an elegant and powerful family of languages, and I greatly look forward to diving deeper. Though Lisp is often considered impractical, it sometimes takes the impractical to open ones eyes to the practical possiblities lying elsewhere.

Honorable Mentions

C and Lisp are merely the two things I immediately put on my ‘to do list’ after git pushing the final PPL30 article. Several of the things I covered I intend to work with again. In fact, I’ve been using ZSH since I finished the ZSH article. Until recently, Unicorn and Nginx were in use on the CI server at work. This blog uses some features of HTML5. I want to use Redis and Riak together (despite it seeming ridiculous). I think I’ll go ahead and convert vimtweets.com to Rails 3 and DataMapper. Node.js is pretty badass — if I could just dream up a project on which to use it. Oh, there’s LowPro.

If you’re keeping track, that’s days 30, 25, 22, 21, 17, 14, 13, 8, 2, and 1.

Would You Do It Again?

Pssssshhhhhh no. Not at this rate or scale. Not for 30 days straight. Listen: I learned a lot. It was great. I’m quite happy I did it. However, it’s a grind. One hour a day? Please. I’d estimate three hours each on average, including writing time. I lost at least 1 hour of sleep every weekday. Coffee was my savior.

You should try it. What? Did you not just say that you wouldn’t do it again? Yeah, I said that. I can say that, because I’ve done it. Have you done it? Okay. Well, do it.

All joking aside, do it. It’s intense. You will learn something new every single day. Writing each article forces you to really know the material about which you’re writing (even if it’s only a fraction of the whole subject). You can get a good look at all of those things you’ve been telling people you want to learn. “Oh, Node.js? Yeah, I’m totally going to check that out.” When? “Man, I’ve been meaning to play with ZSH. I’m going to do that soon.” Soon, huh? You mean, “I’m going to check that out when I can’t ignore it any longer”. Just do 30 days, and tell everyone you’re going to do 30 days. Write that first blog post. You know what? Do 14 days. Hell, I might do a couple sets of 5 week days this fall to catch up.

Are You Glad You Did It?

Absolutely. I am really glad I did it. I learned a ton, I had a lot of fun, and it’s spawned some great conversations since it began. I also learned how much I can get done when I really need to get something done! Just try it. What’s 30 days in a lifetime? It’s not even 10% of the year. Try it. You’ll be happy you did.


While you’re at it, go remind Tim on his blog or on Twitter that he needs to finish the final third of his PPL30.

Posterous theme by Cory Watilo