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"

4 Answers4

10

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
  • 19,459
  • 7
  • 57
  • 79
  • Any reason I wouldn't just say 'a' instead of '?a' ? –  Mar 18 '09 at 01:16
  • 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'? –  Mar 18 '09 at 01:23
  • Ok, so it's one fewer character to write ?a Maybe that's the reason? –  Mar 18 '09 at 01:24
  • Ahh, I didn't know that. I haven't used 1.9 yet. – Ed S. Mar 18 '09 at 01:39
  • 1
    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 Mar 18 '09 at 01:45
  • @ 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 Mar 18 '09 at 01:47
  • @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. –  Mar 18 '09 at 01:50
  • I would not use ?a over 'a' in 1.9 as it will just serve to confuse people, as evidenced by this thread :). – Ed S. Mar 18 '09 at 02:38
  • 1
    Important to note though - String#[] changed too, so the above code would produce the same effect in 1.8 and 1.9 – rampion Mar 18 '09 at 12:03
  • @ Rampion: I don't follow. Which "code above" is the same in 1.8 and 1.9? – Telemachus Mar 18 '09 at 12:42
  • `?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 Apr 29 '09 at 20:24
5

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
  • 18,154
  • 5
  • 45
  • 45
0

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

Community
  • 1
  • 1
Ed S.
  • 122,712
  • 22
  • 185
  • 265
0

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
  • 2,651
  • 3
  • 19
  • 17