sinatra/sinatra — pull request #492 by floere (2012-03-23 05:04:54+00:00)
Title: Correct handling of "/:name.?:format?" and "/:user@?:host?"

This pull request adds the correct handling of the following URL path patterns to Sinatra. These are the patterns which this is about:

```ruby
Pattern | Current Regexp | Example | Should Be
"/:name.?:format?" | /^\/([^\/?#]+)(?:\.|%2E)?([^\/?#]+)?$/ | "/foo.bar" | ["foo", "bar"]
"/:name.?:format?" | /^\/([^\/?#]+)(?:\.|%2E)?([^\/?#]+)?$/ | "/foo%2Ebar" | ["foo", "bar"]
"/:user@?:host?" | /^\/([^\/?#]+)(?:@|%40)?([^\/?#]+)?$/ | "/foo@bar" | ["foo", "bar"]
"/:user@?:host?" | /^\/([^\/?#]+)(?:@|%40)?([^\/?#]+)?$/ | "/foo.foo@bar" | ["foo.foo", "bar"]
"/:user@?:host?" | /^\/([^\/?#]+)(?:@|%40)?([^\/?#]+)?$/ | "/foo@bar.bar" | ["foo", "bar.bar"]
```

## Why? / History

This is the result of a long discussion starting here:
https://twitter.com/#!/konstantinhaase/status/182480862326165504

The discussion being here:
https://gist.github.com/2154980

## What? / Code changes

I mainly touched the `base.rb` file, specifically the `Base#compile` method. My plan was to generalize some of the other cases to keep the needed changes to the code low. This plan resulted in 2 other patterns -> regexps being changed (and imho improved).

I added a quite comprehensive spec in the file `compile_test.rb`, which can be run with `ruby test/compile_test.rb`.

## Possible discussion worthy points

### /^...$/ => /\A...\z/

One bigger change is found in switching from /^...$/ to /\A...\z/, i.e. switching from line-based matching to global matching with anchoring at the beginning of the string. Two reasons:

1. I believe it to be "more correct".
2. It is thought to be more performant (for some cases, see http://www.ruby-doc.org/core-1.9.3/Regexp.html).

If this is a problem, please discuss.

### Pattern "/:name.?:format?"

I was wondering about one pattern (see header) – on an example of "/.bar" is supposed to result in [".bar", nil]. This seems strange to me – it seems to me as if it should result in a non-match, i.e. `nil`.
I changed the tests to reflect my line of thought. If this is untrue, please tell me why and I'll change the tests and add the commit to this pull request.

Thanks for reading!