Many languages have a decent way to assign or output multiple lines of text without actually making you concatenate a bunch of strings and newlines. They’re usually called “here documents” or heredocs, and in Ruby, it works line this:

    expected = <<EXPECTED
                <object width="500" height="411">
                  <param name="wmode" value="transparent"></param>
                   wmode="transparent" width="500" height="411"></embed>
                </object>
EXPECTED

(That’s from a test I was working on involving modifying an embed, but I took the long lines out for formatting reasons. I’m not sure it’s the best approach to testing, but at least there was a test – thanks, autotest!)

In the above case, I’m saying “assign this string, and keep going until you see the EXPECTED symbol. I could also have used “expected = <<-EXPECTED” and the dash would have told Ruby that I want to indent the closing token. You know, for looks.

But wait! That code has a bug! True story – it won’t run as I’ve typed it here, even though it looks totally valid.

The closing token can’t have any trailing whitespace.

If it does, you’ll get a “can’t find string ‘EXPECTED’ anywhere before EOF (SyntaxError)” error. And of course most editors aren’t set up to show invisible tokens, so you might find yourself wailing and gnashing your teeth if you haven’t run into this error before (I blog about my simple errors often, and I know they make me look a little dense at times, but it helps ensure I won’t do it again, and hopefully someone else who doesn’t have the benefit of a peer review will find it and save some time as well.)

After (finally!) figuring out why my code wasn’t working, I checked to see if the code would work if the trailing spaces matched on the setup and closing tokens – i.e. if there were two spaces after both instances of “EXPECTED” – but then you get a different error about how the first line didn’t end like it was supposed to.

Interestingly, in BBEdit, which is my editor of choice, the syntax colouring gets all screwed up when there are spaces, because BBEdit knows how heredocs are supposed to work even if you don’t, so there’s a clue too.

Ruby also has some features involving multiple heredocs starting on the same line, and some fun stuff with quotes around the tokens, but this isn’t the definitive Ruby heredoc post, just a “get out of heredoc whitespace hell” post that might prove useful to some of you.

{ 0 comments }

Autotest, Rails, and testing the lib folder

by admin on August 16, 2010

I finally installed autotest for my Rails development – if you haven’t heard about it, it might just be the thing that gets you into TATFT mode: you edit a file, and the relevant tests automatically run.  It’s like continuous integration for your development machine, basically, and I’m amazed at how much time it saves by eliminating seemingly tiny operations like remembering to launch the test runner.

The thing was though, that I wanted a certain setup for my lib folder and accompanying tests.  Before things get to the plugin/gem phase, most of my library code that’s outside of the models and controllers usually sits in lib until I figure out what I want to do with it.

To test these things, I prefer to have a separate test folder instead of using test/unit – for one thing, I usually don’t have ActiveRecord involved in these modules, so I don’t need the fixtures to run.

Getting rake to handle the lib tests is pretty simple, thanks to this this tip from Stack Overflow:


namespace :test do

desc "Test lib source"

Rake::TestTask.new(:lib) do |t|

t.libs << "test"

t.pattern = 'test/lib/**/*_test.rb'

t.verbose = true

end

end

So great, now I can run ‘rake test:lib’ and I’m golden, but that doesn’t give me automatic goodness.

For autotest to do the same thing, you need to add some mappings to your .autotest file in the root of the project:

Autotest.add_hook :initialize do |at|
  %w{.git .svn .hg .DS_Store vendor tmp log doc}.each do |exception|
    at.add_exception(exception)
  end

  at.remove_mapping(/^lib\/.*\.rb$/)
  at.add_mapping(%r%^lib/(.*).rb%) do |filename, m|
    ["test/lib/#{m[1]}_test.rb"]
  end

  at.add_mapping(%r%^test/lib/.*\.rb$%) {|filename, _| filename}

end

The remove_mapping call is the key to making this all work: when autotest runs against a Rails app, mappings are already in place thanks to the autotest-rails gem.  That gem, however, has its own opinions for how lib files get run, and by default it’ll run tests in test/unit, which isn’t what I want.  If you don’t remove that mapping, your mapping won’t check against any .rb files in lib, and you’ll spend a few hours going insane.

Thanks go out to Brandon Keepers for some sample .autotest setups that I was able to work from!

{ 1 comment }

Activating the youtube-g gem in Rails 3

August 15, 2010

Gems with underscores always seem to mess with me and this one was no exception.  Here’s what goes into the Gemfile to avoid getting NameError/uninitialized constant YouTubeG ruining your day:
gem ‘youtube-g’, :git => "git://github.com/jasondoucette/youtube-g.git", :require => ‘youtube_g’
Note the use of dashes and underscores – the :require directive is what makes this all work.
(Aside: I forked [...]

Read the full article →

Dealing with a “This site may harm your computer” block

August 13, 2010

Over the past 3 years or so, Google and, later, Firefox began taking a more active role in the fight against sites distributing malware by warning users before they allow passage to a site that they’ve detected as a possible threat.
I know this because… I had several of those sites.
Not on purpose, of course – [...]

Read the full article →

Rails ActiveRecord initial attribute values are based on column defaults

June 18, 2010

It might be time to call it a night:
So I’m testing out a location class in Rails (version 3!), and I want to make some comparison methods in the model, so I can do things like if location.empty? or location.match?(elsewhere) and so on, and it’s not working for me, so I crank out the unit [...]

Read the full article →

In praise of automated deployment

June 17, 2010

I’ve worked jobs with websites that are manually sent to the server by FTP, and I’ve worked with sites that are pushed up with a single command line call.  Guess which ones I enjoyed more?
Let’s back up a minute.  Websites are, at their core, a collection of files on a web server (yes, often many [...]

Read the full article →

Decimal numbers in Rails and MySQL

May 22, 2010

When you’re dealing with non-whole numbers in your application, there are a couple of considerations for storing them in the database.
The trouble with float
Most languages and databases have great support for floating point numbers, which from a naive perspective, would mean “numbers with a decimal point.” The trick of it is that these representations [...]

Read the full article →

Fixing iTunes “does not seem to be a valid podcast URL” errors

May 11, 2010

This is an interesting lesson in evolving standards, and evolving vigilance against bad implementations.  First, the core problem: the dreaded (hey, I dreaded seeing it this morning!) “does not seem to be a valid podcast URL” error in iTunes:
In this case, Developer Lives is in fact a dead feed (sadly,) but I fixed the problem [...]

Read the full article →