Posted by trevor
Tue, 03 Jun 2008 19:19:39 GMT
Recently one of my ENTP colleagues switched me on to ack as an excellent replacement for find+grep. Being a dyed in the wool TextMate user, the first thing that popped into my head was “I need an ‘Ack in Project’ TextMate plugin”.
Unfortunately the only advertised plugin I could find was 404’ing on me. Did I do the simple thing and notify the author about the dead link? Nope. I wrote my own plugin instead.
In hindsight I have to ask… what on earth was I thinking?
Whatever. I wrote the plugin and (if I do say so myself) it’s pretty damn good.
Here’s some installation instructions for getting it from my github repository:
cd ~/Library/Application\ Support/TextMate/Bundles
git clone git://github.com/protocool/ack-tmbundle.git Ack.tmbundle
I’ve also thrown together a little (silent and slightly crappy) screencast showing it in action.
Enjoy.
Edit:
I’ve updated the wiki to include some information on getting ack to recognize new file types using Henrik’s haml comment as an example.
8 comments
Posted by trevor
Mon, 07 Jan 2008 23:00:12 GMT
This morning I checked my feed reader and was instantly transported back to 1992, when I was working for a small independent software vendor.
So please indulge me while I tell you a little bit about the company, what I learned, and what brought it all rushing back.
Read more...
Posted in code | 2 comments
Posted by trevor
Thu, 07 Jun 2007 05:24:56 GMT
Recently a changeset (6591) made its way into Rails’ trunk. A few people are blogging about how cool it is but I’m going to blog about why it’s bad.
Read more...
4 comments
Posted by trevor
Mon, 19 Mar 2007 05:03:23 GMT
A couple of times I’ve noticed people saying that uncountable names (like sheep and fish) can’t be used with resource routes in Rails. Well, they can.
# in config/routes.rb
map.resources :fish
In the above example there is a conflict between the generated url helpers for the ‘fish’ collection and the generated url helpers for members of the ‘fish’ collection. Because ‘fish’ is uncountable, both are called fish_path
or fish_url
. And because of the way routes and url helpers are created in a map.resources
call, the member url helpers override the collection ones.
So using the above example, calling fish_path()
raises an error like:
ActionController::RoutingError: fish_url failed to generate from {:controller=>"fish", :action=>"show"} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: ["fish", :id] - are they all satisifed?
Thankfully that’s not the end of it. You just have to add a :singular
argument when defining your resources:
# in config/routes.rb
map.resources :fish, :singular => :fish_instance
# in your code
fish_path() #=> /fish
new_fish_instance_path() #=> /fish/new
fish_instance_path(1) #=> /fish/1
edit_fish_instance_path(1) #=> /fish/1;edit
That’s all.
Posted in code | no comments
Posted by trevor
Tue, 17 Oct 2006 17:54:46 GMT
Here’s a little something I whipped up that’s proved useful.
Yaml is a pretty good format for storing fixture data but it can be a real pain to set up a bunch of fixtures with repeating or incrementing data. There’s a much better tool out there for that – Excel.
One way you can ease the pain of generating reams of fixture data is to build it all up in Excel and export your spreadsheets as csv files and tell Rails to use csv fixtures. Unfortunately I couldn’t find a way to have a moniker (my name for the non-indented line in your yaml fixtures) in the csv files so that I could refer to fixtures by name in my tests.
So what I’ve done is to write a little plugin and rake task that converts xls files into yaml fixtures. See:
http://svn.protocool.com/public/plugins/trunk/xls_fixtures/
Note that it requires the ‘parseexcel’ gem (as in “gem install parseexcel”) and you need to arrange your rows and columns as per the README file in the plugin.
Posted in code | 2 comments
Posted by trevor
Tue, 25 Jul 2006 17:25:42 GMT
You come across interesting stuff by browsing pastie but this tops them all.
http://pastie.caboo.se/5900/wrap
no comments
Posted by trevor
Mon, 12 Jun 2006 17:48:56 GMT
This little extension to Ruby’s Array class is making the rounds:
class Array
def sum
inject(0) { |m, v| m + v }
end
end
# Use it thusly:
[1,2,3,4,5].sum # => 15
Nice. But what if we want to sum a member of each array element, such as the ‘price_cents’ attribute on a bunch of ActiveRecord objects?
@order.line_items.collect {|x| x.price_cents}.sum
# or (my preference) using Symbol's to_proc method:
@order.line_items.collect(&:price_cents).sum
Even with the sugar that Symbol#to_proc adds, it’s just a bit… well, blech. We can do better:
class Array
def sum
if block_given?
inject(0) { |m, v| m + yield(v) }
else
inject(0) { |m, v| m + v }
end
end
end
# Now we can say:
@order.line_items.sum(&:price_cents)
That’s just so much clearer.
Update: a recent changeset in the rails trunk adds a ‘sum’ method to Enumerable. It’s different from what I present above in that it only works with a block – which is okay for me because that’s my main usage pattern anyhow.
Posted in code | no comments
Posted by trevor
Tue, 30 May 2006 23:27:05 GMT
This afternoon I was hit by a real headscratcher – documented here for future googlers looking for information on: functional tests hanging controllers subdirectories :-)
I added in some tests for controllers that were in a subdirectory (as in “./script/generate controller boo/hoo
“) and suddenly rake started hanging.
I could run individual functional tests just fine but as a suite – forget it.
The source of the problem turned out to be twofold:
- in test_helper.rb we alias the
get
and post
test methods so that we can optionally capture all of our output and run it through a validator.
- the require line that ./script/generate creates for loading test_helper.rb in your functional tests is relative to the current file’s directory. For functional tests in subdirectories you get a
require
argument ending with ”/../../test_helper” rather than the one ending with ”/../test_helper” as you do in top-level functional tests.
Even though those two different require lines point to the same file, from require’s perspective they are different – so the file is loaded twice.
And that’s a big no-no if you are doing a simple method alias without checks against doing it twice.
The bulletproof solution is to have tests use File.expand_path()
on the argument to require
. But if the generators keep spitting it out as they do now it’s one of those “pushing water uphill” situations. I smell a patch.
For now, I’m just wrapping my alias
calls with a check of self.instance_methods
to make sure the alias hasn’t already been done.
Posted in code | no comments
Posted by trevor
Mon, 29 May 2006 01:16:40 GMT
A few years back, while I was building my house, I downloaded a demo copy of Sketchup to help visualize how everything would look. It’s a fantastic tool for 3D design, one of those rare pieces of software that just makes sense.
Unfortunately it’s also software that costs about $500 USD and as much as I wanted to, I simply couldn’t justify the expense. My love affair with Sketchup was doomed to be just a few short weeks as the demo period quickly slipped away.
Sketchup did leave me with a legacy though: Ruby. It ships with a ruby interpreter and has hooks to extend the software with Ruby scripts. Had I not seen the Ruby/Sketchup integration I probably wouldn’t have given Rails a second look when I stumbled across it a year and a half (gosh!) ago.
Okay, that’s enough nostalgia. The real point here isn’t whether I owe a debt of gratitude to a 3D modeling program for more than a year of fun, full-time work with Rails…
The real point here is that Google bought Sketchup and they are releasing cut-down free versions. I think that’s pretty big news and I have absolutely no idea how I missed it.
They’ve already released the free version for PC and apparently a free version for OS X is in the works as well.
I am so chuffed about this. It’s going to make designing my kids’ backyard playstructure a breeze.
Posted by trevor
Fri, 26 May 2006 22:51:37 GMT
One of my apps has a set of controllers in an ’/admin’ directory. They all must have a :login_required
before_filter and they all must define an authorized?
method that checks if the current user is an administrator.
For a couple of reasons the idea of having a special “AdminController” which everything under ’/admin’ would inherit from (and that set up the filter and authorized? method) kind of irked me.
First, there was the name clash – AdminController becomes ‘admin’ in routes and that clashes with my directory called ‘admin’, so I’d have to choose a name like “AdminBaseController” or some-such. Blech.
Second, I just didn’t like the extra file for the base controller. Call me picky, I can take it.
What I wanted was a way to say “if the controller is in the /admin directory then it needs this filter and this method”.
Class#inherited to the rescue. Here’s what I put in /app/controllers/application.rb
:
# For all controllers in the 'Admin' namespace we set
# the login_required before_filter and define an authorized?
# method that checks user.is_administrator?
def self.inherited(subclass)
# call super first - otherwise any before_filters we add are lost
super
if subclass.name.split('::').first == 'Admin'
subclass.before_filter :login_required
subclass.send(:define_method, :authorized?, Proc.new {|user| user.is_administrator?})
subclass.send(:protected, :authorized?)
end
end
This is fine for my present needs. If controllers under /admin start to need any more shared behavior I’ll just bite the bullet and do the AdminBaseController thing – but for now this is clean and works.
Posted in code | no comments