目次 < 前へ | 次へ >

ホワイの(感動的)rubyガイド

 why the lucky stiff / 青木靖 訳

拡張パック No. 1
 

トラのチョッキ(Irbの基本的な説明つき)

 

昔、あるところに、チョッキを着たトラがいました。

しかし、それは最大の問題というわけではありませんでした。

なぜなら、地球が太陽に突っ込もうとしていたからです!!

しかし科学が分らない彼は、そんなことを知りません。

「そういうことやってる時間のない人もいるんだよ」

彼はまた、このEchelon 3500という名前の女の子型ロボットのことがとても好きでした。

簡単に言うと、彼女のことを愛していたのです。だからもし彼女が当時起きていたロボット大戦争へと戦いに行かなければならないのでなかったなら、彼女と結婚していたことでしょう。彼女は仲間のロボットたちのために、名誉の戦死を遂げました。

トラのチョッキの話にはすぐに戻ってきます。その前にRubyをインストールしておきましょう・・・

だけど地球が間もなく太陽と衝突するんだってことは忘れないようにしてください。

Rubyの最新版を自分のコンピュータにインストールして、(感動的)ガイドの例を追いかけ、いろんなことをすぐ実際にやれるようにしよう! (そう、いろんなことをだ!)

  • Microsoft Windowsを使っているなら、Windows用Rubyインストーラをダウンロードする。この「ワンクリック」インストーラを実行すれば、Rubyがセットアップされ、 ついでに小さなテキストエディタや追加のライブラリといった便利なソフトウェア一式も合わせてインストールされる。
  • AppleのMac OS Xを使っているなら、Rubyはすでにインストールされているかもしれない。OS XのVersion 10.2と10.3にはRubyが入っている。しかしその場合でも、この本の例が間違いなく動くように、Rubyをアップグレードすることをお勧めする。そのためには安定版ディスクイメージをダウンロードする。このイメージを使うにはOS X 10.3 (Panther)とXCode Toolsが必要になる。
  • FreeBSDではRubyはportシステムに入っている。実際、もしportupgrade を使ったことがあるなら、Rubyはすでにインストールされている。portupgradeを書いたのは非常に才能のあるRubyの中心的開発者の1人の武者晶紀 なので、pkgtools.confをハックすればRubyの勉強ができるよ。
     cd /usr/ports/lang/ruby18
     sudo make install
    
  • RedHatMandrake Linux用にはRuby RPM がある。それからXimianのRed CarpetからでもRubyは手に入れられたはずだ。
  • Debianならapt-get install ruby を実行する。
  • Gentooならemerge rubyを実行する。
  • その他のLinuxUNIX プラットフォーム、あるいは(ディスクイメージが使えない)OS Xの場合には、最新のソースコードをダウンロードする。たとえば ここにある: Ruby 1.8.2。解凍してコンパイルするには以下のようにする:
     tar xzvf ruby-1.8.2.tar.gz
     cd ruby-1.8.2
     ./configure
     make
     make install
    

    (上のコマンドはRubyをソースコードからインストールするためのものなので、susudo を使ってmake installを実行できる権限を得る必要があるかもしれない。)

Rubyがインストールできたか確認するには、コマンドシェルを開いてruby -vを実行する。Rubyが正しくインストールされていれば、バージョン情報が表示される。

 ruby 1.8.2 (2004-12-25) [i386-mswin32]
  • Microsoft Windowsでコマンドシェルを開くには、スタートメニューで「ファイル名を指定して実行...」を選び、cmdと入力し、OKをクリックする。するとコマンドシェルウィンドウが出てくる。
  • Mac OS Xでコマンドシェルを開くには、Applications > UtilitiesTerminal プログラムを実行する。

OK、コマンドシェルは開いたままにしておいて。地球を太陽への落下から救えたら必要になるから。

 

OK。みんな準備はいい?

そういうわけで、外はばかみたいに暑くなったため、トラは日陰を求めてタキシードショップに入りました。

チョッキが欲しい気がして、店員を呼ぶためにベルを鳴らしました。

しかしそのベルは実際には巨大な氷銃に繋がっていたのでした。

それで太陽がしばらく凍り付きました・・・地球が跳ね返るのに十分なくらいの間。

そのあと、店員がトラの新しいチョッキを持ってやってきました!

トラもきっと感心したに違いありません!

彼は1000%愛を深めました!!

しかしそれは店員ではありませんでした! ECHELON 3500だったのです!

全部作り直されて、足には最新式のロケットブースターが付いていました!!  燃料補給し、大気圏を突き抜ける準備万端です!

 

RubyにはIrbというすごく便利なツールがついている。インタラクティブRubyだ。コマンドシェルでirbと入力してみよう。

 irb(main):001:0>

上のようなプロンプトが出るはずだ。これはIrbのプロンプトで、ここでRubyのコードを入力してEnterを押すと、そのコードが実行される。

では、Irbプロンプトで3000 + 500を実行してみよう。

 irb(main):001:0> 3000 + 500
 => 3500
 irb(main):002:0>

この例3000 + 500は合法なコードだ。ただ答えを変数に代入していないだけだ。Irbは実行したコードが返す値を出力する ので、これは別に問題ない。

Irbというのはすごい電卓だ。

 irb(main):002:0> ( ( 220.00 + 34.15 ) * 1.08 ) / 12
 => 22.8735
 irb(main):003:0> "1011010".to_i( 2 )
 => 90
 irb(main):004:0> Time.now - Time.local( 2003, "Jul", 31, 8, 10, 0 )
 => 31119052.510118

最初の例はちょっとした算数のデモで、220.00足す34.15かける1.08割る12を計算している。2番目の例は2進数列を10進数に変換している。3番目の例は現在 時刻(now)と2003年7月31日午前 8:10 の間の秒数を計算している。これらに対するIrbからの答えはすべて、アスキー文字の矢印で指し示す形で表示される。

 

プロンプトを読む

プロンプトは確かにまごつかせるものだというのは分る。ちょっと分析してみることにしよう。実際すごくシンプルなのだ。プロンプトは3つの部分からできていて、コロンで区切られている。

最初の部分はirb(main)となっていて、実行しているプログラムの名前を示している。2番目の部分は行番号で、入力したRubyの行数を表している。3番目は深さのレベルだ。閉じる必要のあるステートメントを開くときに深さのレベルは1増える。Irbはコードが完結していなければそれと分かり、プロンプトの末尾がアスタリスクに変わる

 irb(main):001:0> bell = :pressed         #ベル = 押された
 => :pressed
 irb(main):002:0> ice_gun =               #氷銃
 irb(main):003:0*   if bell == :pressed   #ベル == 押された 
 irb(main):004:1>     :on
 irb(main):005:1>   else
 irb(main):006:1*     :off
 irb(main):007:1>   end
 => :on

if文を始めたときに深さのレベルが1に増えているのに注意してほしい。それからアスタリスクが継続行を表わす仕方も見てほしい。

 

プロンプトを変える

この プロンプトの見かけを好きになってもらう必要はない。私はあなたに何を強いるつもりもないし、あなたがハックしたいと思うなら、お手伝いしよう。

Irbには他のプロンプトもあって、そちらの方があなたの好みに合うかもしれない。irb --prompt simpleを試してみて。そうするとIrbはごく基本的な矢印のセットでもてなし てくれるようになり、ステータスレポート抜きでコードを書けるようになる。

 >> %w(my best friend's arm) #私の親しい友達の腕
 => ["my", "best", "friend's", "arm"]
 >>

Rubyにはいくつかのプロンプトがある。simpleプロンプトは上で見たものだ。xmpプロンプトはプロンプトなしで、答えの矢印をインデントする。(これは印刷したときにきれいに見えるように意図されている。) nullプロンプトではプロンプトがまったく出ない。プロンプトを設定するには、--promptオプションでプロンプトの名前を指定すればいい(つまりirb --prompt nullのようにする)。

自分でプロンプトを定義することもできる。Irbは中身を完全にカスタマイズできるのだ。conf オブジェクトはIrbのすべての構成情報を持っている。この構成情報にはプロンプトを制御するためのものも含まれている。

 >> conf.methods.grep /prompt/
 => ["prompting?", "prompt_s", "prompt_s=", "prompt_c", "prompt_c=", 
     "prompt_i", "prompt_mode", "prompt_i=", "prompt_mode="]

プロンプトをちょっとした飾りの付いた行番号にしてみよう。

 >> conf.prompt_i = "%3n :> "           # 通常のプロンプト
 >> conf.prompt_s = "%3n .%l "          # 文字列継続行のプロンプト
 >> conf.prompt_c = "%3n .^ "           # コード継続行のプロンプト
 >> conf.return_format = "    => %s\n"  # 答えの矢印

これはIrbのプロンプトの4つの部分だ。文字列継続行のプロンプトはEnterを打ったときに文字列がまだ閉じていない場合に表示される。%3n で行番号に3文字確保される。%lは継続される文字列の種類を表示する場所を確保する。(二重引用符の文字列を継続する場合には二重引用符が表示され 、正規表現を継続する場合にはスラッシュが表示される。)

その他のはプロンプトのちょっとした飾りだ。たとえばコード継続行の場合にはキャレット(^)を表示して、コード行の始まりである上の行を指し示すようにしている。

Irbのカスタマイズと構成情報のファイルへの保存の仕方について、もっと詳しいことはIrbガイドに書かれている。これはインターネットをさまようあなたの目に無料で提供され ている「プログラミングRuby」の一部だ。

 

タブによる補完

Irbのあまり語られることのない機能の1つに便利なタブ補完がある。これは現在のところ幾分タブーな話題で、それというのもWindowsで使えるようにするのはちょっと した恐怖なためだ。(いえいえ、怖がらなくていいよ。ではみなさん、右を見て。)

LinuxかFreeBSDを使っているなら、タブ補完はすぐに使えるはずだ。OS Xを使っているなら、間違いなく最新の1.8にアップグレードして、Irbを起動するとき、次のように指定する。

 irb --readline -r irb/completion

基本的には、あなたがタブを打つとき、Irbはあなたの打とうとしていることを推測しようとする。 [].col の後にタブを打ってみて。Irbが仕上げをして[].collectとし、 カーソルを末尾に置いてあなたがさらに打ち続けられるようにしてくれる。

候補が複数ある場合には、タブを打っても何も起らない。しかし2回タブを打つと、Rubyは選択可能な候補の完全なリストを表示する。

これは何かのオブジェクトのメソッドをすべて見たいというときに使える。好きな数字に続けてドットをタイプし、タブを2回打ってみよう。

  >> 42.
                42.floor                   42.next                    42.step
  42.__id__     42.freeze                  42.nil?                    42.succ
  42.__send__   42.frozen?                 42.nonzero?                42.taint
  42.abs        42.hash                    42.object_id               42.tainted?
  42.between?   42.id                      42.prec                    42.times
  42.ceil       42.id2name                 42.prec_f                  42.to_f
  42.chr        42.inspect                 42.prec_i                  42.to_i
  42.class      42.instance_eval           42.private_methods         42.to_int
  42.clone      42.instance_of?            42.protected_methods       42.to_s
  42.coerce     42.instance_variable_get   42.public_methods          42.to_sym
  42.display    42.instance_variable_set   42.quo                     42.truncate
  42.div        42.instance_variables      42.remainder               42.type
  42.divmod     42.integer?                42.respond_to?             42.untaint
  42.downto     42.is_a?                   42.round                   42.upto
  42.dup        42.kind_of?                42.send                    42.zero?
  42.eql?       42.method                  42.singleton_method_added  
  42.equal?     42.methods                 42.singleton_methods       
  42.extend     42.modulo                  42.size  

では 次に、Kernel:: の後にタブを打ってみて。すべてのコアメソッドが出てくる。この機能を覚えておいて、いつでも使うようにしよう。

Except the robot flew away and the ice gun went on and on...

あいにくと、トラはEchelon 3500を繋いでおかなかったので、彼女はどっか別なところへ飛んで行ってしまいました。

氷銃は付けっぱなしにしてあったので、みんな町から逃げなければなりませんでした。

ところで、この物語はデトロイトで起きるのですが、今起きている、というわけではありません。 

OK、最後にもうひとつだけ話して、そうしたらこのすごいテクノロジーであなたのことを悩ませるのをやめにしよう。だけどこれは大声で言わなきゃならない。だから身を伏せて いて!  私は世界に向かって伝える。その本は空から降ってくる—赤い太字のクレッシェンド の

((ri))

(Rubyの電話番号案内、あるいは555-1212†、あるいは、ええ、オペレーターさん、ベオグラードに繋いでください—私はここにいるから—誰かが出るまでひたすら#キーを押し続けている・・・)

†555-1212は米国の電話番号検索サービス

そしてRiが電話を取る。「こちらRiです。クラスとコロンをお願いします」

あなたは急いで「私はインスタンスメソッドです、オペレーターさん。Enumerable#zip」

 ri Enumerable#zip

遅延もなく、テレタイプディスプレイに次のように表示される(あまりに早いので、高いところに座っていた猫でさえ首を巡らし、あくびをしてから、マイケル・ドーン以来もっとも露骨に偉大な る者に贈られる優勝カップを手渡す)。

 --------------------------------------------------------- Enumerable#zip
      enum.zip(arg, ...)                   => array
      enum.zip(arg, ...) {|arr| block }    => nil
 ------------------------------------------------------------------------
      Converts any arguments to arrays, then merges elements of _enum_
      with corresponding elements from each argument. This generates a
      sequence of +enum#size+ _n_-element arrays, where _n_ is one more
      that the count of arguments. If the size of any argument is less
      than +enum#size+, +nil+ values are supplied. If a block given, it
      is invoked for each output array, otherwise an array of arrays is
      returned.

         a = [ 4, 5, 6 ]
         b = [ 7, 8, 9 ]

         (1..3).zip(a, b)      #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
         "cat\ndog".zip([1])   #=> [["cat\n", 1], ["dog", nil]]
         (1..3).zip            #=> [[1], [2], [3]]

これは要約なしのRuby辞書機構だ—ただ尋ねるだけというパワーが、あなたの指先にあるのだ—「頭金不要の適切な説明の終身提供」について聞いたことがないなんて言わせない!

何かのクラスについて、その説明をすべてのメソッドの完全な案内付きで見るためには、容赦ないトラクタービームに捉えられもがいてパニックを起こしているどんな宇宙飛行士 をも落ち着かせることのできるとても心安らぐ声で、コマンドシェルにri Classと伝えるだけでいい。

クラスメソッドのヘルプを見るには、ri Class::methodと平手打ちを食らわせる。

インスタンスメソッドにはドットではなく#マークを使う。(ドットだとクラスメソッドともインスタンスメソッドとも解釈できるので。)  つまりri Class#methodのようにする。

クラスのすべての広がり、一番上から地球の中心に至るまでの完全なリストが、 ri -cで得られる。

そしてテキストだけでなく、HTMLも作ることができる: ri -Tf html String#gsub > gsub.html

多彩なANSIで表示することもできる: ri -Tf ansi String#gsub これは最後で最高だ。

 

Riのスイッチボードに入る

Riの背後では人の声のコーラスが歌っていて、それは主としてデイブ・トーマスだ。彼はProgramming Rubyの著者であり、Rubyのアメリカでの育ての親だ。

Riはそのみずみずしい情報を、Rubyが構築されたコードそのものから摘み取っている。Ruby本部のファイルキャビネットにあるそれぞれのコードファイルには、詳細なコメントが あって目に見えるものすべてを記述している。

Rubyのdate クラスには、こんな風にコメントを付けられたメソッドがある。

 # Get the time of this date as [hours, minutes, seconds,
 # fraction_of_a_second]
 def time() self.class.day_fraction_to_time(day_fraction) end

 # Get the hour of this date.
 def hour() time[0] end

 # Get the minute of this date.
 def min() time[1] end

このコメントがRiに現れるのだ。ri Date#timeとタイプしてみよう。

 -------------------------------------------------------------- Date#time
      time()
 ------------------------------------------------------------------------
      Get the time of this date as [hours, minutes, seconds,
      fraction_of_a_second]

Riでメソッドがどのように動くのかだいたいのところは知ることができる。しかしそのためには、プログラマがメソッドやクラス定義の前のコメントに簡単な説明を書 いている必要がある。メソッドを書くときにはいつでも、メソッドの前のコメントに簡単な説明をつけておくことをおすすめする。いつか、そのメソッドのRiドキュメントを生成する ことになるだろう。

あなたのコメント記述をより良いものにするために使える特殊文字がいくつか用意されている。たとえば、パラグラフをインデントしてアスタリスク*かハイフン-を頭につけ ておくと、そのパラグラフは箇条書きだと解釈される。あなたの記述がHTMLに変換されると、それがHTMLの順序なしリストになっているのがわかるだろう。

 # Get the time of this date as an Array of:
 # * hours
 # * minutes
 # * seconds
 # * fraction_of_a_second
 def time() self.class.day_fraction_to_time(day_fraction) end

後にピリオドがつく数字で始まるリストは、番号つきリストとして解釈される。アンダースコアで囲むと強調語になり、アスタリスクで囲むと太字になり、プラス記号で囲むと コードワード(タイプライター体)になる。いくつかのスペースでインデントしたブロックは例になる。これらのルールすべてを合わせたものがRDocと呼ばれている。

以下に挙げるのは、私のRedClothというプロジェクトの中のinitialize メソッドのRDocだ。インデントされた例や、クラス名やメソッド名の両脇にプラス記号があるのに注意してほしい。

 #
 # Returns a new RedCloth object, based on +String+ and
 # enforcing all the included +restrictions+.
 #
 #   r = RedCloth.new( "h1. A <b>bold</b> man", [:filter_html] )
 #   r.to_html
 #     #=>"<h1>A &amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt; man</h1>" 
 #
 def initialize( string, restrictions = [] )
     @lite = false
     restrictions.each { |r| method( "#{ r }=" ).call( true ) }
     super( string )
 end

RDocのルールの完全な記述は、READMEMarkupの項にある。

 

自分のRiを作り出す

しかしRiは自動的にあなたのファイルを読んではくれない。あなたは押しやって、道を示してやる必要がある。スキャンしたいコードのあるディレクトリに行って、RDocツールを実行する。

 cd ~/cvs/your-code
 rdoc --ri-site

そうしたら、ri YourClassを試してみて、記述がちゃんと表示されるか見てほしい。HTMLのドキュメントを作りたければ、次のようにする:

 cd ~/cvs/your-code
 rdoc

~/cvs/your-code ディレクトリにはdoc ディレクトリができていて、あなたのクラスのHTMLドキュメントが入っている。index.htmlで喜ばしいニュースを見てほしい。

それでは。これであなたも一枚かむようになったわけだ。Rubyの世界へようこそ。

 

ねえ、みんな氷銃のことをまだ残念に思ってる?

トラのことは大目に見てあげてください。彼はスーパーヒーローというわけではありません。そんな力はないのです。

彼は新しい場所に引っ越したようです。

いえいえ、メープルシロップはデトロイトに置いていきました!

 

 

Magic Ways シリアル

「誰もその謎がわからない・・・」

ウーン、この辺に店があったと思うんだけど。

また会いましょう。

 

ページをめくる。