Commit
There were two issues here that * String#length was used to determine the Content-Length resulting in off-by-one failures in expected length assertions. * The specs were using body.to_s to convert bodies to Strings. In Ruby 1.8, #to_s is like #join; in Ruby 1.9, #to_s is like #inspect
- Loading branch information
There are no files selected for viewing
7 comments
on commit 3576a34
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 dkubb’s suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It really is everywhere throughout the codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve even found myself using this idiom in other projects. :-P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we don’t extend core classes in Rack but, really, is there any downside to adding something like this in rack/utils.rb:
class String alias_method :bytesize, :size unless ''.respond_to? :bytesize end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m usually the first to decry monkey-patching, but I don’t have a problem with that suggestion. I’d say that’s perfectly acceptable. It doesn’t break the idiom for anyone else using it, and it simplifies a lot of repetitive code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. It’s different from, say, monkey patching #each in to 1.9. Adding a method like #bytesize that did not exist in 1.8 and that’s supported in 1.9 with the exact same semantics is probably one of the only places I’m okay with a library extending core objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its a slippery slope, and its got razors at the bottom.
There’s nothing special about the name bytesize. Just because rails didn’t donkey patch it into String doesn’t mean that some other guy out there didn’t. Maybe he has a “DSL” where he defined bytesize globally to return the number of bytes a string would take when reencoded into utf-8 from jcs, or the number of bytes the string will take when encoded into a protocol header.
He’s going to have problems when he tries to port to 1.9, but those are his problems. If Rack starts silently using his crazy bytesize definition, his problems become yours.
Anyhow, just define Rack::size(s) as a module function, and use it, its only 2 more characters than the ruby1.9 form:
size = body.size # 1.8
size = body.bytesize # 1.9
size = Rack::size body # compatibility wrapper
You can conditionally define it to return either size or bytesize depending on the ruby version, thus avoiding the overhead of continual respond_to? checks, AND having code that works perfectly with ruby 1.8 even when someone does have a weird bytesize method in their String.
This is such a common idiom, perhaps it should be wrapped up into a Rack::Utils.content_length_for method?