Lightweight Language Lovers
Python vs Ruby / Python(2)
文字列を文字の連続したものと考え、「文字」と「文字のコンテナ」に分離します。
 シフトJIS1文字(英数字または漢字) を表すクラス SjisChar を新たに定義し、
 SjisChars は、SjisChar が格納されたコンテナをエミュレートします。 
SjisChars(3〜14行目)
SjisChar が格納されたコンテナをエミュレートしています。
今回実現したいのは、文字列から一文字(1バイトまたは2バイト)づつ返すことだけですので、
3.3.5 コンテナをエミュレートする から、__iter__ メソッドだけを実装しています。
SjisChar(16〜29行目)
- シフトJIS1文字(英数字または漢字) を表すクラスです。 
インスタンスの生成時(__init__)、渡された1バイトで英数字なのか漢字(2バイト文字の1バイト目)なのかを判定します。
またもや手抜きして1バイト目だけで機種依存文字、外字を判定していますが本格的には setByte2 の後に判定するべきでしょう。その場合、1バイト文字の場合もこれらの属性が正しく設定されるよう気を付けるようにします。__repr__ は、インスタンス名だけが指定された時に文字が表示されるようにするためです。
 
   1 # -*- coding: cp932 -*-
   2 """ Handle SJIS charcters"""
   3 class SjisChars:
   4 
   5         def __init__(self, s):
   6                 self.s = s
   7 
   8         def __iter__(self):
   9                 a = [c for c in self.s]
  10                 while a:
  11                         c = SjisChar(a.pop(0))
  12                         if c.isKanji:
  13                                 c.setByte2(a.pop(0))
  14                         yield c
  15 
  16 class SjisChar:
  17 
  18         def __init__(self, c):
  19                 self.value = c
  20                 d =ord(c)
  21                 self.isKanji = ((0x81 <= d <= 0x9F) or (0xE0 <= d <= 0xFC))
  22                 self.isKisyu = (d in (0x87, 0xED, 0xEE, 0xFA, 0xFB, 0xFC))
  23                 self.isGaiji = (0xF0 <= d <= 0xF9)
  24 
  25         def __repr__(self):
  26                 return c.value
  27 
  28         def setByte2(self, c):
  29                 self.value += c
  30 
  31 
  32 if __name__ == '__main__':
  33         for c in SjisChars("abcd<8a>¿<8e><9a><87>@"):
  34                 print c, c.isKanji , c.isKisyu, c.isGaiji
これをRubyで実装してみましょう。