■ いつでも Ruby なんでも Ruby

このページは、Software Design 2000/7 に掲載された「いつでも Ruby なんでも Ruby」を出版社の許可を得て掲載しています。

掲載前の元原稿から HTML 化していますので、掲載された記事とは同一ではありません。 コラムの部分など、記事では掲載されていないものもありますので、お楽しみください?

テキストで記述した原稿なのですが、これを HTML へ変換するスクリプトを書いて、このページを作成しています。 もちろん Ruby を使用しています。 便利ですよ!

■ ようこそ Ruby の世界へ

Ruby は、「オブジェクト指向スクリプト言語」です。 スクリプト言語の手軽さと、オブジェクト指向的アプローチが可能な優れた言語です。 この言語を作成した方は「まつもとゆきひろ」さんです。 とてもバランスのいい言語になっています。

ここでは、最初に Ruby の特徴について説明して、その後は実際に動くスクリプトを実例に「Ruby の雰囲気」を確認してもらいます。 細かな文法的な説明はできませんが、この実例で、できるだけ「動く」完結したスクリプトをみていただき、Ruby の便利さを実感していただくことができるようにと考えています。

インストールや設定などについては、後半の方にコラムとして扱っています。

繰り返しになりますが Ruby は、スクリプト言語としての手軽さと、本格的なプログラミング言語としての要素を持ち合わせています。 ユーザの使いやすさを重点に置いて作成された言語であるため、使いやすさと便利さを兼ね備えている言語になっています。 Ruby は、とてもいい感じになっています。 抽象的な書き方ですいません。 ですが、スクリプト言語の手軽さ、オブジェクト指向言語としての能力を持ち合わせ、わかりやすい文法や便利な機能をあわせ持っている、すばらしい言語です。 Ruby は、きっとあなたをたくさんサポートしてくれるでしょう。

■ 特徴から

Ruby の作者、まつもとさんの書かれている特徴は次のとおりです。 私のコメントも追加しておきます。

Web ページの「Ruby とは」から

「Ruby オンラインマニュアル」から、より詳しい特徴です。

● インタプリタ

Ruby はインタプリタ言語ですのでプログラムを実行するためにコンパイルする必要はありません。 エディタで編集して、すぐに実行確認が可能です。 イメージしたことをすぐに記述して、実行確認がスムーズに行えるのは、思考のスピードを妨げません。

● 変数に型が無い (動的型付け)

Ruby の変数はどのような型のデータも格納する事ができますので、変数の型について心配する必要はありません。 半面、コンパイル時のチェックは弱くなります。

ここでのコンパイルというのは、インタプリタがスクリプトの実行時の前処理として、構文解析などを実施することです。 コンパイルコマンドがあるわけではありません。

オブジェクトの属するクラスは、そのオブジェクトの振る舞いをメソッドで定義します。 変数の型の問題が、入りにくいプログラミングが可能になっています。

● 変数宣言が不要

Ruby では変数を宣言無しで使う事ができます。 最初に代入した時点が、変数の宣言と初期化を行う処理と同様になります。 変数の種類 (ローカル変数、グローバル変数、インスタンス変数など) は変数名から確認できます。 変数は、基本的にローカル変数です。 このため、ローカル変数であることの宣言や、グローバル変数を多用することによる問題が入りにくくなっています。

● 単純な文法

Ruby の文法は Eiffel からわずかに影響を受けた単純なものです。 文法的に「end」で終わるため、気になる方もいるようですが、なれるとかなりすっきり記述可能です。

● ユーザによるメモリ管理が不要

Ruby はメモリ管理を自動的に行います。 どこからもアクセスされなくなったオブジェクトはインタプリタに組込みのガーベージコレクタによって回収されます。 C などの言語で、メモリ管理が一番ややこしい部分になります。 Ruby は、これらの問題を言語が引き受けるので、ユーザの負担を大きく軽減します。

● 全てがオブジェクト

Ruby ははじめから純粋なオブジェクト指向言語として設計されています。 整数のような基本的なデータ型をはじめとして、すべてのデータをオブジェクトとして統一的にとり扱えます。 ほんと、すばらしいです。

● クラス、継承、メソッド

Ruby はクラス、継承、メソッドのようなオブジェクト指向言語として基本的な機能は当然持っています。 あるデータについて、そのデータの振る舞いを関数として記述するのは、一般のプログラミング言語でも同様です。 Ruby は、手軽にクラス定義を実施することが可能で、オブジェクト指向のメリットを十分受けることができます。

● 特異メソッド

ある特定のオブジェクトにメソッドを付加することができます。 たとえば、GUIのあるボタンを押された時の動作をメソッドとして記述するような使い方ができます。 これを応用してプロトタイプベースのオブジェクトプログラミングも可能です。

● モジュールによる Mix-in

Ruby は多重継承は複雑さの源であるという見地から、意図的に多重継承を持っていません。 ですが、モジュールを使ってクラス階層を横断して実装を共有できます。 この機能を「Mix-in」と呼びます。

● イテレータ

ループの抽象化を行うイテレータという機能があります。

● クロージャ

手続きをオブジェクトとして扱う機能があります。 このオブジェクト化された手続きのことをクロージャと呼びます。

● 強力な文字列操作/正規表現

Perl をお手本とした強力な文字列操作や正規表現検索の機能があります。 やりたいと思っている多くの作業は、String クラスや Regexp クラスがほとんど機能を提供しています。 こんなこともできるの? と感動してしまいます。

● 多倍長整数

組込みの多倍長整数機能がありますので、メモリが許す限り、非常に大きな整数の演算もできます。 たとえば、400 の階乗なども簡単に計算できます。

● 例外処理機能

例外処理機能は例外的な状況への対処が簡単に書けます。

スクリプト言語としての手軽さを、この例外処理機能がさらに便利にしています。 エラーなどが起きた場合、例外が発生します。 この例外を補足しない限り、例外としてエラーメッセージが表示され、スクリプトは終了します。 エラー処理を記述しなければならない言語では、やろうとしていることについていちいちエラーの確認をしなければなりません。 言語によっては、全体の半分以上がエラー処理の記述になってしまうようなこともあります。 または、エラーが起きていているのに本質的な処理ができないことに気がつかなかったりします。 Ruby では、エラーのことを気にしないで処理を記述し、無視していいエラーだけを例外として記述することになります。

● OS への直接アクセス

Ruby は(UNIX の)ほとんどのシステムコールの呼びだし機能を持っています。 Ruby だけでシステムプログラミングも可能です。 アプリケーション的に OS の機能を利用するような場合や、システム管理的作業に利用する場合にも力を発揮します。

● ダイナミックローディング

OS が許せば、オブジェクトファイルを実行時に読み込む機能が提供されます。

■ 動くスクリプト

簡単な動くスクリプトをみていただこうと思います。 ファイルアクセスや、ネットワークへのアクセスが簡単に可能ということをみてください。

インストールについては、後述しますが、スクリプトの最初に書くおまじないについて書いておきます。 Ruby のインストール先は、デフォルトで /usr/local/bin/ruby となります。 この Ruby を使用して実行する場合には、ファイルの先頭に次のように記述してください。 これは、UNIX のお約束です。

#! /usr/loca/bin/ruby

# スクリプト

Ruby のアプリケーションによっては、次のように記述されているものもあります。

#! /usr/bin/env ruby

# スクリプト

この方法は、env(1) コマンドを利用して ruby を呼びだしています。 UNIX 系のシステムでは、env コマンドが利用可能と思いますが、この方法で /usr/local/bin 以外のディレクトリに ruby がインストールされていてもスクリプトが起動可能です。 これらの方法を使えるようにするために、ファイルにスクリプトを記述したあとに chmod(1) コマンドを実行しておいてください。

$ chmod +x rubyscript.rb

Ruby スクリプトのファイル名は、「.rb」が拡張子になります。

以下のサンプルは、次のように実行します。 「$」がシェルのプロンプトになります。

$ ./sample1.rb

または

$ ruby ./sample1.rb
ここから動くスクリプトのサンプルが続きます。 細かな文法については、フォローできないのですが雰囲気をつかんでいただけるようにできるだけ多くのスクリプトを用意しました。 これから「ファイル」と「ネットワーク」についてのサンプルをみていただいたあと、簡単な文法的な解説をしています。

■ ファイル

UNIX での cat(1) コマンドです。 引数のファイルを表示します。 ファイルを扱う場合の基本ですね。

#! /usr/local/bin/ruby

while gets
  print
end

Ruby では、手軽にファイルを扱えるように引数で渡されたファイル名や標準入力からの入力を手軽に扱えるようになっています。 ここでは変数 $_ が暗黙の変数として利用されています。 変数 $_ は特別扱いを受けることがあり、便利な機能を提供しています。 変数 $_ を使用しない場合は次のようになります。

#! /usr/local/bin/ruby

while l = gets
  print l
end

上記の例では、引数としてファイルが複数渡された場合でも、すべてのファイルを表示します。 これは、引数のファイル名をすべて扱ってくれる機能を利用しています。 個別にファイル名を扱いたい場合には、引数が ARGV (Array クラス) に入りますので、これを利用します。 ここでは、一つ一つのファイルを File クラスとして open しています。

#! /usr/local/bin/ruby

while filename = ARGV.shift
  f = File.open(filename)
  while l = f.gets
    print l
  end
  f.close
end

さらに、File クラスを利用すると、次のように open や close などの処理をまとめて実施する方法もあります。

#! /usr/local/bin/ruby

while filename = ARGV.shift
  File.foreach(filename) do |l|
    print l
  end
end

少し実用的な例としてファイルの内容を 16 進数で表示するスクリプトです。 文字コードなどを調べるときに使用可能です。

#! /usr/local/bin/ruby

offset = 0

while file = ARGV.shift
  f = File.open(file)

  while b16 = f.read(16)
    printf "%05x:", offset
    offset += 16

    b16.unpack('C*').each do |b1|
      printf " %02x", b1
    end
    print "\n"
  end

  f.close
end

実行結果は次のようになります。 head(1) を使用して、最初の 10 行だけ表示しています。

$ ruby hd.rb hd.rb | head
00000: 23 21 20 2f 75 73 72 2f 6c 6f 63 61 6c 2f 62 69
00010: 6e 2f 72 75 62 79 0a 23 20 2f 68 6f 6d 65 2f 74
00020: 65 74 73 75 2f 73 72 63 2f 72 75 62 79 2f 62 6f
00030: 6f 6b 2f 73 64 2f 77 2f 68 64 2e 72 62 0a 23 20
00040: 43 72 65 61 74 65 64 3a 20 4d 61 79 20 31 30 2c
00050: 32 30 30 30 20 57 65 64 6e 65 73 64 61 79 20 30
00060: 34 3a 34 33 3a 33 31 0a 23 20 41 75 74 68 6f 72
00070: 3a 20 74 65 74 73 75 28 57 41 54 41 4e 41 42 45
00080: 20 54 65 74 73 75 79 61 29 0a 23 20 24 49 64 24
00090: 0a 23 20 75 73 61 67 65 3a 0a 0a 6f 66 66 73 65

ファイルを 16 バイトごとに読み込み、その値を表示しています。 読み込まれたデータをコードの値として参照するために String#unpack を利用しています。

■ ネット

Web ページをアクセスする簡単なツールを書いてみます。 複数の URL を指定して、次々にその URL から情報をとりだします。 URL として次の形式をサポートしています。

http://ホスト名:ポート番号/パス名
http://ホスト名/パス名

実行方法は次のようになります。

$ ruby http.rb http://localhost/ http://www.ruby-lang.org/

スクリプトは少し長くなりますが、URL で記述されたページを直接読んでしまいます。

#! /usr/local/bin/ruby

require 'socket'

CRLF = "\r\n"

def HTTP_get(url)
  if url =~ %r|(\S+?)://(\S+?):(\d+)/(\S+)?|
    proto, host, port, path = $1, $2, $3, $4
  elsif url =~ %r|(\S+?)://(\S+?)/(\S+)?|
    proto, host, path = $1, $2, $3
    port = proto
  else
    fail "bad url(#{url})"
  end

  path = if path.nil? then '/' else '/' + path end
  http = TCPsocket.open(host, port)
  http.print 'GET ', path
  http.print ' HTTP/1.0', CRLF, 'Accept: */*', CRLF, 'User-Agent: Ruby http tool', CRLF, CRLF
  html = http.read
  http.close
  html
end

def usage
  STDERR.print "usage: #{$0} url...\n"
  exit 1
end

while arg = ARGV.shift
  if arg =~ /^((?:http):\S+)/
    url = $1.sub(%r|/index.html?$|, '/')
    html = HTTP_get(url).gsub(/\r/, '')
    print html
  else
    usage
  end
end

ネット関係のスクリプトも、Ruby はかなり手軽に作成できます。 URL 関係の処理を含めて Ruby ですべてを書いた例になります。 ネットワークでの通信部分だけならかなり簡単です。 ほんの数行で HTTP のやりとりを書いています。

次のものは、添付のクラスライブラリ net/http.rb を使用したものです。 一つのホストで複数のパスの情報をとりだします。 先ほどの例と引数などの指定方法が違いますが、ライブラリの特徴にあわせました。

実行方法は次のようになります。

$ ruby httplib.rb www.ruby-lang.org /ja/ /en/raa.html

引数には、「ホスト名」一つと「パス」を複数指定することが可能です。

#! /usr/local/bin/ruby

require 'net/http'

host = ARGV.shift
http = Net::HTTP.new(host)

while path = ARGV.shift
  arr = http.get(path)
  print arr[1]
end

応用として、同じホスト内のリファレンスを追いかけてセーブするようなスクリプトがすぐ書けそうですね。 いかがですか?

■ 少し文法的なこと

Ruby は、オブジェクト指向言語ですが、自分でクラス定義をしなくても、便利なクラスがたくさん用意されています。 関数を呼びだすようなプログラムになれていると、次のような

オブジェクト.メソッド
変数名.メソッド.メソッド.メソッド

のような書き方に戸惑うかもしれません。 これらは、「オブジェクト」の属するクラスのメソッドを呼びだしています。 なれるまで、「あれ?」と感じることがあるかもしれません。 ですが、オブジェクトに定義されているメソッドを呼びだすということは、わかりやすいと思いませんか? いまは、C++ などを利用されている方も多いと思いますので、戸惑いはないのかもしれませんね。

■ 変数の扱い

ローカル変数が基本です。 関数を定義する場合や、メソッドを定義する場合に、ローカル変数が基本になります。 これは、関数の有効範囲による問題を起きにくくしています。

変数には、特に宣言を行う必要がありません。 使用する場合は、変数に値を代入します。 これが初期化であり宣言になります。 変数が示す値がなにかはっきりするために、解釈によって不定になるようなこともありません。

■ クラス定義の便利さ

Ruby の場合、クラス定義がとても手軽です。 関数を定義するのとほとんど変わらない手間でクラス定義が可能です。 一度クラス定義をすると、とても応用範囲が広がります。 クラス定義を行うと、インスタンスの生成時にインスタンス変数を利用することでインスタンス単位にリソースの管理が可能です。 複数のオブジェクトのために個別にリソース管理を行う必要がなくなります。 例えば、ネットワークサービスを利用するプログラムを書くような場合、クラス定義をすることで複数のサービスをうまく活用することが簡単に行えるようになります。

■ Thread も便利

処理を同時に実行したい場合や、非同期的に処理したいような場合 Thread の機能は便利です。 Ruby は、OS の Thread 機能を利用せずに、アプリケーションレベルで Thread の機能を提供しています。 このため、Ruby で記述されたスクリプトは、OS の Thread 機能に依存することなく利用可能です。

次の例は、とても簡単な TCP/IP の確認用のスクリプトです。 ネットワークのあるサービスに接続して、キーボード(標準入力)からのデータを送る送る部分と、結果を表示する部分です。 Thread が入力と出力をそれぞれ担当しています。

#! /usr/local/bin/ruby

host = 'localhost'
port = ARGV.shift || 'www'

require 'socket'
require 'thread'

tcp = TCPsocket.open(host, port)

Thread.start do
  while l = tcp.gets
    print l
  end
  exit
end

while l = gets
  tcp.print l
end

次は、実行例です。 辞書検索のための NDTP というプロトコルで辞書を検索する手順を、このスクリプトで試しています。

$ ruby tel.rb ndtp
Atetsu
$A
T
1       岩波国語辞典
2       新英和・和英中辞典
3       知恵蔵
4       マイペディア
5       国語辞書
6       和英辞書
7       英和辞書
8       漢和辞書
$*
L2
$*
Pahacker*
$0
hacker
44e4:7b8
$$
S44e4:7b8
$1
h'ack・er
−[名][C]
1 荒っぽく切る人,切り落とす人[もの].
2 《口語》 ハッカー:
a コンピューターでプログラミングに取り組む[夢中になる]人.
b 不法にコンピューターシステムに侵入してデーターを改変したり盗用したりする人.

$$
Q

これで、NDTP の手順を確認ができたので、応用として辞書検索ツールを作るのは難しくなさそうですよね?

■ 情報源

Ruby についての情報は、次の URL を参照してください。

http://www.ruby-lang.org/

ここにたくさんの情報がありますし、いろいろなリンク先が紹介されています。

Ruby のメーリングリストも紹介されています。 とても盛んに情報交換が行われています。 また、このメーリングリストのやりとりを検索することができる優れものの Web サイトもあります。 ぜひ活用してください。

最後に、Ruby をこれからはじめようとしている方にちょっとアドバイスを。 どんな言語でも覚えるまでには少し時間がかかります。 Ruby のようなスクリプト言語は、とても応用範囲が広くいろいろなことができます。 もし、仕事でも趣味でもなんでもけっこうですので、「こういうのがあればいいな」と思ったら、それを自分なりに作ってみてはいかがでしょうか? 目的の 50% をとりあえず Ruby で作ってみるとか、70% まで作成できればあとはらくらくになると思います。 自分のやりたいことが複雑でも、他のアプリケーションを利用する仲立ちに Ruby を利用することも可能です。 コンピュータを使うとき、Ruby のような手軽でいろいろできる言語を使えると、とても応用範囲が広がりますよ。

■ 参考文献

Ruby のバイブルです。 基本的文法から、応用、用語集、オブジェクト指向についてまで話題豊富です。

オブジェクト指向スクリプト言語 Ruby
まつもとゆきひろ/石塚圭樹 共著
アスキー出版局
ISBN4-7561-3254-5

すべての情報は、次の Ruby ホームページからはじまります。 あなたの Ruby ライフもここから。

Ruby ホームページ
http://www.ruby-lang.org/

■ 漢字のサポート

Ruby は、漢字をサポートしています。 さすが日本産ですね。 文字コードとしてのサポート、正規表現でのサポート、漢字コードの変換を行うことが可能です。 漢字コードの変換がもともとサポートされているので、入力するファイルの漢字コードに依存することなく、漢字が扱えます。 漢字コード変換には、コマンド nkf(1) と同じ漢字コード変換機能が入っています。 引数の指定も同じ形で実施します。 次の例は、JIS コードを EUC Japan に変換します。 変換に使用したスクリプトです。

require 'nkf'

while gets
  $_ = NKF.nkf('-JeZ', $_)
  print
end

変換の過程を Ruby で作成した hex dump プログラムで確認してみました。

$ cat /tmp/j.txt
JIS コードの漢字です。
$ hd.rb /tmp/j.txt
00000000  4a495320 1b244225 33213c25 49244e34  JIS .$B%3!<%I$N4
00000010  413b7a24 47243921 231b2842 0a        A;z$G$9!#.(B.
$ ruby k1.rb /tmp/j.txt| hd.rb -e
00000000  4a495320 a5b3a1bc a5c9a4ce b4c1bbfa  JIS コードの漢字
00000010  a4c7a4b9 a1a30a                      です。.

JIS コードの漢字のファイルも、EUC Japan に変換されています。

スクリプト内で漢字コードを直接使用する場合は、-K オプションを使用します。 EUC Japan が使用されている場合は

$ ruby -Ke スクリプト名.rb

とします。

スクリプトの漢字コードに依存しますので、スクリプトの先頭に

#! /usr/local/bin/ruby -Ke
と、記述するのがいいでしょう。

スクリプトで漢字コードを設定すると、変数 $KCODE にその漢字コードが設定されます。 内部的な処理(例えば正規表現など)で、漢字コードに依存する場合は、この変数が参照されます。 もし、一部の正規表現だけ直接漢字コードを指定したい場合には、次のように「/」のあとに「n」を指定することで可能です。

#! /usr/local/bin/ruby -Ks

while gets
  if /[a-z]/n
    print
  end
end

この例では、漢字のための処理を行わない「n」を指定しています。

扱う漢字コードは次のようになっています。

n    漢字の処理をしません
e    EUC
s    SJIS
u    UTF-8

Ruby の実行オプション、変数 $KCODE、正規表現のあとに指定が可能です。

注意点として、スクリプト内に直接漢字コードを使用している場合は、Ruby の実行オプションで指定してください。 Ruby がスクリプトを構文解析するときに、漢字コードの指定がことなると、うまく実行できないことがあります。

■ システムプログラミングも

Linux のコマンド df(1) があります。 システムコールを呼びだすようなプログラミングもらくらく作成可能です。 syscall を使用すると statfs(2) のような任意のシステムコールを呼びだすことが可能です。 引数の形式は、

syscall(システムコール番号, 第一引数、第二引数...)

のようになります。 システムコール番号は、

/usr/include/sys/syscall.h

を参照ください。 引数の形式については、オンラインマニュアル

$ man 2 statfs

を参照ください。

#! /usr/local/bin/ruby

class StatFS
  def initialize(path)
    @path = path
    size = 64
    unpack_fmt = 'iiiiiiiiiiiiiiii'
    foo = ' ' * size
    syscall(99, @path, foo)
    @bsize, @blocks, @bfree, @bavail  =
      foo.unpack(unpack_fmt).indexes(1, 2, 3, 4)
  end
  attr_reader :path, :bsize, :blocks, :bfree, :bavail
end

def pr_d(dev, foo)
  blocks_used = foo.blocks - foo.bfree
  printf("%-20s %7d %7d %7d  %3d%%  %s\n",
	 dev,
	 foo.blocks * foo.bsize / 1024,
	 blocks_used * foo.bsize / 1024,
	 foo.bavail * foo.bsize / 1024,
	 if blocks_used + foo.bavail == 0 then 0
	 else blocks_used * 100 / (blocks_used + foo.bavail) end,
	 foo.path)
end

class Mtab
  def initialize
    @file = '/etc/mtab'
    @info = []
    File.foreach(@file) do |l|
      @info.push(l.split)
    end
  end
  attr_reader :file, :info
end

print 'Filesystem      1024-blocks  Used Available Capacity Mounted on', "\n"

Mtab.new.info.each do |arr|
  dev, dir, type, opt = arr
  next if dev == 'none'
  foo = StatFS.new(dir)
  pr_d(dev, foo)
end
$ df.rb
Filesystem      1024-blocks  Used Available Capacity Mounted on
/dev/hda5            1209572  816832  331296   71%  /
/dev/hda2            1546526  530560  936043   36%  /home
/dev/hda6            1888052  706635 1083824   39%  /t

■ バイナリファイルも

Linux のコマンド who(1) は、データとして /var/run/utmp というバイナリファイルを扱います。 Ruby は、手軽にバイナリファイルを扱うことが可能です。 utmp(5) のフォーマットを調べて、String#unpack で値を変換し Array#indexes で必要な値だけをとりだします。

#! /usr/local/bin/ruby

TYPE_IN, LINE_IN, NAME_IN, HOST_IN, TIME_IN = 0, 3, 5, 6, 10

UTMP = '/var/run/utmp'
UTMP_FMT = 'ssiA32A4A32A256ssllliiiiA20'
UTMP_LEN = 384

utmp = File.open(UTMP)

while utmp_line = utmp.read(UTMP_LEN)
  arr = utmp_line.unpack(UTMP_FMT).indexes(TYPE_IN, NAME_IN, LINE_IN, HOST_IN, TIME_IN)

  case arr.shift
  when 7			# USER_PROCESS
    printf("%-8s %-8s %s %s\n",
	   arr[0],
	   arr[1],
	   Time.at(arr[3]).strftime('%b %d %H:%M'),
	   if arr[2] == '' then '' else '(' + arr[2] + ')' end)
  end
end

実行結果は次のようになります。

$ ruby who.rb
tetsu    tty1     May 03 22:09
tetsu    ttyp0    May 03 22:09 (:0.0)
tetsu    ttyp1    May 03 22:10 (:0.0)
tetsu    ttyp2    May 03 22:10 (:0.0)

■ irb は便利

irb は、interactive ruby です。 Ruby の式を入力し簡単に実行することが可能です。 試したいときに、どんどん活用してください。 irb は、標準でインストールされます。 irb を実行したい場合は、ソースコードに付属する sample ディレクトリ下に irb.rb があります。 これを実行プログラムを入れるディレクトリにコピーして使用しましょう。 irb 関係のドキュメントは、ftp の contrib ディレクトリにある irb のパッケージに付属しています。

$ irb.rb
irb(main):001:0> '987654321'.split(//).sort.join('')
"123456789"
irb(main):002:0> arr = [9, 8, 7, 6, 5, 4, 3, 2, 1].sort
[1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):003:0> arr.join('')
"123456789"

■ NIFTY アクセス

ちょっと余談ですが、@nifty の会議室へのアクセスもかなり手軽にできます。 青山さんの作成された nif.rb と telnet.rb (標準添付) により、自動的にアクセスできます。 Ruby のスクリプトに組み込むことで自分なりのアクセスが行えるようになります。

id
get_pass
get_logfile_name

nif = Nifty.new({ 'id' => id
		  'password' => get_pass,
		  'Host'     => 'hrt2.nifty.ne.jp',
		  'log' => get_logfile_name })

nif.login{|c| print c}
nif.pad('pad.fgalts')
nif.forum_read("FGALTS", "1-13,16,17,19,20")
nif.pad("pad.flinux")
nif.forum_read("FLINUX", "ALL")
nif.pad("pad.funix")
nif.forum_read("FUNIX", "ALL")
nif.logout{|c| print c}
exit

ログファイルが生成されたら nif.rb により mailbox 形式で NIFTY の会議室を読み書きも可能です。 このほか普段使用している NetNews リーダを利用する方法もあります。 私の場合には、Emacs/Gnus の組み合わせで、読み書きしています。 NetNews の spool 形式に変換するスクリプトを用意することで、普段使用している NetNews の読み書きと同じにできます。

■ Emacs 使いの方へ ruby-mode

Ruby 用に ruby-mode が用意されています。 Ruby のソースコードに misc/ruby-mode.el が含まれています。 ruby-mode.el を Emacs の load-path に含まれるディレクトリへコピーし、~/.emacs に次の行を追加しましょう。

(autoload 'ruby-mode "ruby-mode" "alternate mode for editing ruby programs")
(setq auto-mode-alist (append '(("\\.rb$" . ruby-mode)) auto-mode-alist))
(setq interpreter-mode-alist (append '(("^#!.*ruby" . ruby-mode))
   				     interpreter-mode-alist))

■ Emacs 使いの方へ etags

Emacs は、タグファイルを作成することでメソッドやクラスにポインタを移動することが可能になります。 Ruby 本でも扱っていますが、Emacs 付属の etags を利用したとりあえずのシェルスクリプトです。

#! /bin/sh

etags \
 --language=none \
 --regex='/\(def\|class\)[ \t]\([^ \t]+\)/\2/' $*

■ cvs で最新ソースコードの入手

最新のソースコードを入手するのには CVS を利用します。 ネットに接続されていることが前提になりますが、32K のモデムでもサクサク入手できるので PPP 接続されている方は、ぜひ!

最初の手順は次の通りです。

内容はつぎのように書いてください。

cvs -z9
$ vi ~/.cvsrc
$ cd /home/cvs
$ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs login
(Logging in to anonymous@cvs.netlab.co.jp)
CVS password:  guest
$ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs checkout ruby

上記の手順で、最新のソースコードが入手できます。

CVS 上で修正が行われた場合、最新の状態に保つには次のようにします。

$ cd /home/cvs/ruby
$ cvs update

これだけで OK です。 修正されたソースコードを確認し最新の状態になります。 なぜ、こんな簡単なのかという理由は? 必要な情報は CVS というディレクトリに納められているためです。

■ 最近の Ruby

Linux 系のディストリビューションでは、標準スクリプト言語として Ruby を利用している Kondara などがでてきました。 標準でインストールされない場合でも、パッケージを提供しているディストリビューションもあります。 Vine Linux などもその一つですね。 このように Ruby がいろいろなところで利用できる環境が整ってきました。

書籍は、バイブルの「オブジェクト指向スクリプト言語 Ruby」がすでに出版されていますが、それ以外に 4 冊ほど予定されているそうです。 楽しみですね。

Ruby は、日本産のスクリプト言語ですが、最近海外進出をはじめています。 海外向けのメーリングリストのやりとりも盛んですし、NetNews では待望の comp.lang.ruby ができました。 コンピュータメーカの Web ページで解説が行われたり、U.S. で書籍が 2 冊出版される予定になっています。 今後どんな展開を見せるのか? ワクワクですね。

Ruby は、安定版の 1.4 系と開発版の 1.5 系があります。 現在ほぼ 1.5 系の機能拡張がクローズされて、次の安定版になる 1.6 としての準備が行われています。 開発版の 1.5 でも十分安定していますが、テスト的なインプリメントがありますので、利用される場合は注意ください。 安定版は、ruby-1.4.4 がリリースされています。 これから利用される方は、ruby-1.4.4 を利用ください。

Ruby の世界では、みなさんの参加をお待ちしています。

■ 簡単! コンパイルとインストール

ソースコードからのコンパイルはとても簡単です。 ソースコードは、Ruby のホームページへどうぞ。

コンパイルとインストールは次のような手順になります。

$ ./configure && make && make test
$ su
# make install

デフォルトでは、/usr/local/bin に ruby の本体が入ります。 動作に必要なライブラリなどは /usr/local/lib/ruby へ入ります。 これらのディレクトリを configure のオプションで修正可能です。 オプションの確認は、

$ ./configure --help

を実行してみてください。

私がいつも実施するオプションは次のようなものです。

$ CFLAGS=-O ./configure --prefix=/t --with-default-kcode=euc

--prefix=/t と指定することで、インストール先を決めています。 デフォルトは /usr/local になります。 /t というディレクトリ(パーティション)以下に自分でコンパイルしたものを入れている関係で、このようにしています。 この設定の場合、新しい Linux を入れた場合でも最低限自分でコンパイルしたものをいつでも使うことが可能になります。

■ マニュアル

Ruby のマニュアルは、HTML 形式になっています。 Web で直接参照できるものと同じものがダウンロードページから入手可能です。

Ruby ホームページ  http://www.ruby-lang.org/ja/
ダウンロードページ http://www.ruby-lang.org/ja/download.html

tarball を展開し、Web ブラウザを利用することで参照できます。 Netscape や w3m などを利用して参照ください。 次の例は、/home/httpd/html/document に展開した場合の例です。

$ w3m /home/httpd/html/document/ruby-man-1.4-jp/index.html

Netscape などで URL を指定しても参照可能です。

file:/home/httpd/html/document/ruby-man-1.4-jp/index.html

CGI にも Ruby が利用できますので、http サーバを立ち上げてマニュアルをインストールしてみてはいかがでしょうか?

いかがでしたか?


渡辺哲也(WATANABE Tetsuya): Tetsuya.WATANABE atmark nifty.com