Entry tags:
Because I found it strangely interesting
Enigel found a 500 error in our errors archive that came up when someone tried to title a work "08". This was odd, since "07" and "007" worked just fine.
She tracked it to this line, which is part of the code for title sorting for works (so that they ignore 'a', 'an' and 'the' at the beginning of the title and make titles starting with numbers sort numerically):
sorted_title.gsub(/^(\d+)/) {|s| "%05d" % s}
That's some pretty complicated code, so first we have to figure out what it does. It breaks down sort of like this:
1)
sorted_title
is a string, so it could be "08", "bob", "And Then There Were None", etc.2)
gsub
is a method that uses regular expressions to replace part of a string with something else. "bob".gsub(/b/, "w")
would give you "wow", for instance. In this case, instead of having a second parameter, it uses a block. More on that in a second.3)
/^(\d+)/
is a regular expression pattern. The opening and closing forward slashes just mark the beginning and end of the pattern. The carat (^) means "the beginning of a line". The backslash plus d (\d) means "a digit from 0-9". The plus sign means "one or more of the thing right before me". So all of this adds up to "one or more digits that come right at the beginning of the line" (because for sorting purposes, we only care about the first word or number). The parentheses mean "capture this stuff so we can do something to it" -- in this case, all we care about is the number itself. 4) Next we have a block (the code in { }). |s| is a way of giving a variable name to each item that gets passed into the block. We could call it anything: |number| or |thingamajig| or |harry| - the name itself doesn't mean anything. We'll do things with s in the block, and whatever value the block returns becomes the replacement for the original number in the title.
5) Inside the block, we have the REALLY fun code.
"%05d" % s
-- this is shorthand for the sprintf method, which "returns the string resulting from applying format_string to any additional arguments." So basically, take s, apply "%05d" to it, and return the result.In context, d means "convert to a decimal number", and in this case, it's s that we're converting. The 5 tells it to expand the number to five places, and the 0 tells it to use zeroes to fill out any empty spaces.
So, the goal is to convert things like so:
7 -> 00007
50 -> 00050
001 -> 00001
1999 -> 01999
Which works... most of the time.
Where the bug comes in
I ran the individual code from irb so that I could see what the error was:
ArgumentError: invalid value for Integer: "08"
So I tossed that into Google to see what came up - thankfully, there was a page that described a similar sort of problem. I didn't understand the whole explanation right off the bat, but the gist of it was that sprintf tries to convert the value you give it to a decimal number, and if the value begins with a leading zero, it tries to convert it from octal into decimal. Octal is a number system with eight digits (0-7) the way decimal has ten digits (0-9), so 8 and 9 don't exist in octal, which means they cause an error. And thus anything from "00" to "07" works fine, but "08" or "09" will get you the sadface error page of doom.
The method it uses to do the conversion is the Integer() method, which has a different set of rules from the to_i method that can also be used to convert things to integers. Witness if you will:
> "07".to_i
=> 7
> Integer("07")
=> 7
> "08".to_i
=> 8
> Integer("08")
ArgumentError: invalid value for Integer: "08"
If you have Ruby installed, you can open irb and try that out yourself.
What I noticed while doing that is that not only does "08".to_i not choke, it also strips the leading zeroes, and thus provides a clue to a reasonable solution:
irb(main):005:0> Integer("08".to_i)
=> 8
Woo! Which translates to:
sorted_title.gsub(/^(\d+)/) {|s| "%05d" % s.to_i}
And now you can title all your works "08" and "09". I'm sure everyone will be very excited about that.
(Note: yes, if you begin your titles with numbers that (a) contain commas, or (b) have six or more digits, you can probably make the sorting go all weird. But that's a garden variety bug, so it doesn't get its own post.)
(Note 2: I keep checking to see if there's a better way to do that, but no luck so far with various string and integer methods.)
no subject
no subject
no subject
(also, maaan, there is absolutely no room in my life for learning to code, but it's not as if I don't get the urge now and then. Especially when reading fun tidbits like this!)
zsXlpHigYPH
(Anonymous) 2013-06-11 07:45 am (UTC)(link)eUlqBzaUYFQTvOJG
(Anonymous) 2013-06-09 03:09 pm (UTC)(link)no subject
PS: is your "re-boot!" icon gankable? :D
no subject
FrbSxkrOjXU
(Anonymous) 2013-06-11 08:13 am (UTC)(link)no subject
no subject
Here via lian
Would it be possible to add other articles (like ... German ones) to this list? I find it incredibly confusing to look for stroes when they're ordered differently.
PS: Sorry for the typos I likely made. I had to type this blind because of font issues.
Re: Here via lian