String.each_char

J

John

I have seen a lot of people having trouble with String not including an
iterator for each character, and rather just each byte. I include this
snippet in any code that needs to iterate over each character in a
string. Simple, elegant, and very very Ruby! Man, I love redefining
pre-existing classes.


# Now you can use the syntax:
# "foobar".each_char do ...

class String
def each_char
each_byte { |byte| yield byte.chr }
end
end
 
R

Robert Klemme

John said:
I have seen a lot of people having trouble with String not including an
iterator for each character, and rather just each byte. I include this
snippet in any code that needs to iterate over each character in a
string. Simple, elegant, and very very Ruby! Man, I love redefining
pre-existing classes.


# Now you can use the syntax:
# "foobar".each_char do ...

class String
def each_char
each_byte { |byte| yield byte.chr }
end
end

This method does not yield characters but strings. Also, it won't work
for multibyte characters. I'm not sure how /./ behaves with multibyte
chars but I'd say chances are higher that you actually get the proper
result by doing

str.scan(/./) {|chr| p chr}

Kind regards

robert
 
B

baumanj

Actually, if you want to deal with multi-byte characters, you have to
make sure to enable that mode. There are three ways to do this
(assuming you want to use UTF-8):

1. Launch ruby (or irb) with -Ku
2. Set the $-K variable to 'u'
3. Add the 'u' option to the end of a regular expression

For example:
"\350" => ?
"\266" => ?
"\243" => ?
"\345" => ?
"\221" => ?
"\263" => ?"\350\266\243" => 趣
"\345\221\263" => 味

So a UTF-8 safe each_char method could be:

class String
def each_char
scan(/./u) {|char| yield char }
end
end

Sadly, even when the KCODE is set to UTF-8, String.[] still returns
bytes, even thought the rdoc claims "If passed a single Fixnum, returns
the code of the character at that position". Is this a known issue? It
seems like there should be a way to access UTF-8 characters without
resorting to regular expressions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,663
Latest member
josh5959

Latest Threads

Top