English

String#rot13

先日 NetNews で rot13 なる単語を見かけました. どん な操作かは名前から想像がつきますが, Jargon File によるとアルファベットを 13 個だけ前 or 後にずらす事の ようです. 記事を読むときにワン・クッションおいてほしいときに, 使われる (使われた?) そうです. ^L と同じ意味合いですね.

私の使っている News reader ではどうやって rot13 すればいいのかわか らなかったので, Ruby で rot13 するメソッド String#rot13 を作ってみました.

バラして, 処理して, 繋げるというと, とりあえず思いつくのは Enumerable#collect. String クラスは Enumerable モジュールをインクルードしています. ですが, String オブジェクトに直接 collect メソッドを 使うとなんとなくうまくいかなかった (?) ので, split("") で一旦 Array オブジェクトにしてから collect し, 処理してから join("") することにしました. 文字列に日本語が含まれていても, String#split はよきに計らっ てくれるようです.

$ ruby -ve 'p "aiうえo".split("")'
ruby 1.4.2 (1999-09-18) [i586-linux]
["a", "i", "う", "え", "o"]

ね. きちんと分かれるれてるでしょ.

あとは collect 内でアルファベットをを 13 だけずらして やればいい. アルファベットのみ, それも大文字, 小文字で処理を分けること に注意すると, こんな感じでしょうか? ずらす文字数は, 13 以外でもいけま す.

#!/usr/local/bin/ruby
# rot13.rb
# $Id: rot13.uhtml,v 1.3 2000-01-02 09:52:46+09 msato Exp $
# 1999/12/17 14:42:48 msato
# Algorithm of 'rot13' is described in Jargon File
# http://www.tuxedo.org/~esr/jargon/html/entry/rot13.html

class String
  def rot(num = 13)
    return self.split("").collect { |ch|
      if /^[a-z]$/ === ch
	((ch[0] + num - 'a'[0]) % 26 + 'a'[0]).chr
      elsif /^[A-Z]$/ === ch
	((ch[0] + num - 'A'[0]) % 26 + 'A'[0]).chr
      else
	ch
      end
    }.join("")
  end

  alias rot13 rot
end

if __FILE__ == $0
  while line = gets
    p line
    p line.rot13
  end
end

日本語にも "転 25" なんてアルゴリズムがあると面白いかもと か思いましたが. 次の実験で道の険しさを知りました :-p

$ ruby -ve 'p "あ".succ'
ruby 1.4.2 (1999-09-18) [i586-linux]
"ぃ"
$ ruby -ve 'p "あ".succ.succ'
ruby 1.4.2 (1999-09-18) [i586-linux]
"い"


[うさぎ印] おたより, お待ちしています

sato.mshr@gmail.com