tags:

views:

325

answers:

4
"foo"[0] = ?b # "boo"

I was looking at the above example and trying to figure out:

  1. How "?b" implies the character 'b'?
  2. Why is it necessary? - Couldn't I just write this:

    "foo"[0] = 'b' # "boo"

A: 

? returns the character code of a character. Here is a relevant post on this.

Ed Swangren
+9  A: 

Ed Swangren: ? returns the character code of a character.

Not in Ruby 1.9. As of 1.9, ?a returns 'a'. See here: Son of 10 things to be aware of in Ruby 1.9!

telemachus ~ $ ~/bin/ruby -v
ruby 1.9.1p0 (2009-01-30 revision 21907) [i686-linux]
telemachus ~ $ ~/bin/ruby -e 'char = ?a; puts char'
a
telemachus ~ $ /usr/bin/ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
telemachus ~ $ /usr/bin/ruby -e 'char = ?a; puts char'
97

Edit: A very full description of changes in Ruby 1.9.

Another edit: note that you can now use 'a'.ord if you want the string to number conversion you get in 1.8 via ?a.

Telemachus
Any reason I wouldn't just say 'a' instead of '?a' ?
Thanks for the irb example. The article points this out too. So in 1.9, ?a gives you the character 'a'. Isn't it an unusual and unnecessarily complicated syntax to get 'a'. Why not just: 'a'?
Ok, so it's one fewer character to write ?aMaybe that's the reason?
Ahh, I didn't know that. I haven't used 1.9 yet.
Ed Swangren
I don't think the change was made in order to make assignment easier. That said, the old behavior was convenient, and I can't think of a good case where the new version is a big help. Maybe someone else will have a clever example for us.
Telemachus
@ Ed - I've been playing with it only a little myself, but I happened to read David Black's two blog entries on differences in 1.9 and I remembered this one (mostly because it seems odd).
Telemachus
@Telemachus - Thanks. I'm going to leave the question open for a while to see if anyone can give me a reason to use ?a over 'a'. Thanks for your helpful feedback.
I would not use ?a over 'a' in 1.9 as it will just serve to confuse people, as evidenced by this thread :).
Ed Swangren
Important to note though - String#[] changed too, so the above code would produce the same effect in 1.8 and 1.9
rampion
@ Rampion: I don't follow. Which "code above" is the same in 1.8 and 1.9?
Telemachus
`?b == "boo"[0] #=> true` in 1.8 and 1.9. In 1.8 both return integers, in 1.9, both return single characters strings
rampion
+4  A: 

The change is related to Ruby 1.9's UTF-8 updates.

The Ruby 1.8 version of ? only worked with single-byte characters. In 1.9, they updated everything to work with multi-byte characters. The trouble is, it's not clear what integer should return from ?€.

They solved it by changing what it returns. In 1.9, all of the following are single-element strings and are equivalent:

?€
'€'
"€"
"\u20AC"
?\u20AC

They should have dropped the notation, IMO, rather than (somewhat randomly) changing the behavior. It's not even officially deprecated, though.

Sarah Mei
A: 

In some languages (Pascal, Python), chars don't exist: they're just length-1 strings.

In other languages (C, Lisp), chars exist and have distinct syntax, like 'x' or #\x.

Ruby has mostly been on the side of "chars don't exist", but at times has seemed to not be entirely sure of this choice. If you do want chars as a data type, Ruby already assigns meaning to '' and "", so ?x seems about as reasonable as any other option for char literals.

To me, it's simply a matter of saying what you mean. You could just as well say foo[0]=98, but you're using an integer when you really mean a character. Using a string when you mean a character looks equally strange to me: the set of operations they support is almost completely different. One is a sequence of the other. You wouldn't make Math.sqrt take a list of numbers, and just happen to only look at the first one. You wouldn't omit "integer" from a language just because you already support "list of integer".

(Actually, Lisp 1.0 did just that -- Church numerals for everything! -- but performance was abysmal, so this was one of the huge advances of Lisp 1.5 that made it usable as a real language, back in 1962.)

Ken