
無料のKindleアプリをダウンロードして、スマートフォン、タブレット、またはコンピューターで今すぐKindle本を読むことができます。Kindleデバイスは必要ありません 。詳細はこちら
Kindle Cloud Readerを使い、ブラウザですぐに読むことができます。
携帯電話のカメラを使用する - 以下のコードをスキャンし、Kindleアプリをダウンロードしてください。
プログラミングRuby 1.9 −言語編− 単行本(ソフトカバー) – 2010/5/26
Ruby は、まつもとゆきひろ氏によるオブジェクト指向プログラミング言語で、楽しく生産的なプログラミングを支援する。言語本来の強力さと使いやすさに加えて、アジャイル開発との相性の良さや、Webアプリケーション開発フレームワークRuby on Railsの圧倒的な人気などに後押しされて、今では日本だけでなく世界中で使われている。
本書は、Ruby1.9 の定番解説書“Programming Ruby 1.9: The Pragmatic Programmers' Guide”を、作者自身の監訳で翻訳発行するもの。(日本語版は、言語編とライブラリ編の二分冊)
- 本の長さ450ページ
- 出版社オーム社
- 発売日2010/5/26
- ISBN-104274068099
- ISBN-13978-4274068096
この商品を買った人はこんな商品も買っています
商品の説明
著者からのコメント
私は、本書の初版と第2 版でも「まえがき」を書きました。初版ではRuby を始めた「動機」について書き、第2 版ではRuby にまつわる「奇跡」について書きました。
この版の「まえがき」では、「勇気」について書きましょう。私はいつでも、勇気ある人々を賞賛します。Ruby 周辺の人々は皆、勇敢だと思います。本書の著者たちもそうです。彼らには、当時まだあまり知られていなかったRuby という言語に飛び込む勇気がありました。新しいテクノロジーを試してみる勇気がありました。古いテクノロジーに執着し、そのまま使い続けることだってできたはずですが、彼らはそうしませんでした。新たに手に入れた材料を使って、独自の世界を構築しました。彼らは、冒険者であり、探検家であり、開拓者です。彼らの努力によってはじめて、我々はRuby という実りある成果を手にすることができたのです。
今、強く感じるのは、私がこれまでに成し遂げたことは、そうした勇敢な人たちの助けを借りてRuby というひとつの宇宙を創造したようなものだということです。この「宇宙」は、最初はエドモンド・ハミルトンによる古典SF『フェッセンデンの宇宙』に登場するミニ宇宙のようなとるに足らないものでした。しかし、今では本物の宇宙のような広大な世界になりました。数え切れないくらいの勇敢な人々がRuby を使うようになりました。彼らは、日々新しいことに挑戦し、Ruby の世界を、より良い、より大きなものにしようと努力を重ねています。私は、そうしたRuby 界の一員であることを本当にうれしく思います。
Ruby の宇宙をすべて記述しようとするならば、「世界もその書かれた文書を収めきれないであろう」(ヨハネ21:25)と思います。本書はそのようなRuby の宇宙を書き表した最初の本です。このたび、最新の情報が盛り込まれて、改版されました。どうぞ、お楽しみください。
まつもとゆきひろ, a.k.a. "Matz"
2009 年2 月、日本にて
出版社からのコメント
この日本語版は、原書の第I 部~第III 部からなる『プログラミングRuby 1.9 言語編』と、原書の第IV部からなる『プログラミングRuby 1.9 ライブラリ編』の2 巻構成になっています(原書は1 巻構成)*9。各巻の各部分にはそれぞれ特色があり、Ruby の異なる側面に焦点を当てた内容になっています。
『プログラミングRuby 1.9 言語編』の「第I 部Ruby の基礎」はRuby のチュートリアルです。まず、第1 章では、皆さんのコンピュータでRuby を動かすための基本情報を提供します。続く第2 章では、Ruby独特の用語や概念について簡単に説明します。この章では、他の章の内容を理解するために必要な基本的なシンタックスについても触れています。第3 章以降は、Ruby 言語をトップダウンで概観するチュートリアルです。クラスとオブジェクト・型・式・その他Ruby という言語を構成するあらゆるものについて説明します。最後に、ユニットテストとトラブルシューティングに関する2 つの章で第I 部を締めくくっています。
Ruby の素晴らしい点のひとつに、周囲の環境との高い統合性があります。「第II 部Ruby とその周辺」では、この点について解説します。ここでは、Ruby の使い方に関する実用的な情報を提供します。インタプリタのオプション・irb・ドキュメントの作成・Ruby のプログラムをgem としてパッケージ化し配布する方法などについて説明します。また、Web プログラミングやWindows 環境でのRuby の使い方(Windows ネイティブAPI の呼び出し・COM の統合・Windows オートメーション)など、Ruby が広く利用されているいくつかの分野についてのチュートリアルも含まれています。さらには、Ruby を使用してインターネットにアクセスする方法についても説明します。
「第III 部Ruby の文法と動作の仕組み」は、少し高度な内容になっています。詳細な文法解説から始まって、duck typing の概念・オブジェクトモデル・オブジェクトの汚染・リフレクション・マーシャリングといった内容にも触れます。この部分は最初は斜め読みでも構いませんが、Ruby を本格的に使い始めると読み返すことになると思います。『プログラミングRuby 1.9 ライブラリ編』はライブラリリファレンスです。かなりのボリュームがあります。『プログラミングRuby 1.9』では54 を超える組み込みクラス/モジュールの1,250 を超えるメソッドについて解説しています(第2 版ではクラス/モジュール数40、メソッド数800)。それに加えて、標準のRuby ディストリビューションに含まれているライブラリについても説明しています。
読者の皆さんは、ご自分のプログラミング経験、とりわけオブジェクト指向言語での経験に合わせて、まずは必要な箇所だけを読んでみるとよいでしょう。レベル別のお勧めの読み方をまとめておきます。
初心者: 『プログラミングRuby 1.9 言編』第I 部のチュートリアルから読み始めてください。プログラムを書くときは、ライブラリリファレンスを手元に置いて参照するようにします。Array、Hash、String などの基本的なクラスの使い方に慣れてください。少し慣れて楽に使えるようになってきたら、第III 部の少し高度な話題に進むとよいでしょう。
Perl などの経験者: Perl、Python、Java、Smalltalk といった言語に習熟されている方は、まず、Rubyのインストールおよび実行方法について説明した『プログラミングRuby 1.9 言語編』第1 章(p. 3)を、続いて入門者向けの第2 章(p. 13)を読んでください。その後は、引き続きチュートリアル部の第3 章以降をじっくり読むのも良いでしょうし、いきなり第III 部からの高度な説明に飛んでも構いません。その後、『プログラミングRuby 1.9 ライブラリ編』に目を通してください。
上級者: 「うざったいチュートリアルなどいらない」という専門家や指導者の方は、いきなり『プログラミングRuby 1.9 言語編』の第22 章(p. 289)から読み始め、『プログラミングRuby 1.9 ライブラリ編』を斜め読みしたら、本書をコースター代わりにでも使ってください(結構おしゃれかもしれません)。
もちろん、最初から最後まで順番に読んでいっても一向に構いません。
それから、解決できない問題にぶつかったら、いつでも助けてくれる人がいることをお忘れなく。詳しくは付録A(p. 397)を参照してください。
(前付より)
著者について
著者代表
Dave Thomas(デイブトーマス)
1999 年以来、プログラミング言語Ruby を愛し続けている。Programming Ruby の初版(Ruby 1.6を解説)は、日本国外のソフトウェア開発者をRuby に注目させるきっかけとなった。カンファレンスやユーザグループやトレーニングの場でRuby の福音を説くことを喜びとする。ドキュメンテーションツールrdoc およびri の原作者。Ruby リポジトリのコミッタとして、Ruby のソースコードのドキュメントの大半を貢献。Andy Hunt とともに、The Pragmatic Bookshelf の代表を務める。本書のほかに7 冊の著作がある。
監訳者
まつもとゆきひろ
株式会社ネットワーク応用通信研究所フェロー。Ruby の生みの親。三女一男の父であり、良き夫でもある。性格はふまじめだが、敬虔(?)なキリスト教徒である。温泉好き。鳥取県出身、島根県在住。牡牛座。O 型。
訳者
田和勝(たわまさる)
フリーランス翻訳者。IT 関連書籍、ドキュメントの翻訳を専門に行っている。主な訳書として、『Perlクックブック』、『詳説正規表現第2 版』(いずれもオライリージャパン刊)などがある。兵庫県神戸市出身。
著者略歴 (「BOOK著者紹介情報」より)
ドキュメンテーションツールrdocおよびriの原作者。Rubyリポジトリのコミッタとして、Rubyのソースコードのドキュメントの大半を貢献。Andy Huntとともに、The Progmatic Bookshelfの代表を務める。8冊の著作がある
まつもと/ゆきひろ
株式会社ネットワーク応用通信研究所フェロー。Rubyの生みの親。鳥取県出身、島根県在住
田和/勝
フリーランス翻訳者。IT関連書籍、ドキュメントの翻訳を専門に行っている。兵庫県神戸市出身(本データはこの書籍が刊行された当時に掲載されていたものです)
About this Title
Ruby.new
プログラミング言語に関する書籍はどれも大体似たような構成になっています。基本型(整数、文字列な
ど)に関する章から始まり、式について解説し、if 文やwhile 文の説明に移り、そして第7 章か第8 章
あたりで初めてクラスが出てきます。筆者らは、こうした構成にあきあきしていました。
そこで、筆者らは本書の構成を考えるとき壮大な計画を立てていました(当時は若かった)。トップダウ
ン方式でRuby という言語を解説しようと思ったのです。つまり、いきなりクラスとオブジェクトから入
り、構文の詳細は後回しにするやり方です。当時は、それが良い考えのように思えました。Ruby ではすべ
てがオブジェクトですから、まずはオブジェクトから入るというのは筋が通っていました。
少なくとも我々はそう思っていました。
しかし、残念ながら、そのような方法で1 つの言語を説明するのは難しいことが分かりました。文字列・
if 文・代入・その他の詳細についてまず説明しておかなければ、クラスの例を書くことは困難です。トッ
プダウン方式で進めても、サンプルコードにはどうしても低レベルの詳細な事項が出てくるので、それにつ
いてまず説明しなければなりませんでした。
そこで我々は別の壮大な計画を思いつきました(だてに実用主義者(pragmatic)と呼ばれているわけで
はないのですよ)。トップダウン方式で説明するという方針は変えませんでした。ただし、その前に、サン
プルコードによく登場する機能を、Ruby 独自の用語と併せて説明する短い章を追加することにしたので
す。それがこの章です。この章はいわば、読者が以降の章を自力で読み進めるようにするためのミニチュー
トリアルです。
2.1 Ruby はオブジェクト指向言語である
繰り返しますが、Ruby は純粋なオブジェクト指向言語です。操作の対象になるのはすべてオブジェクト
であり、操作の結果得られるものもまたオブジェクトです。多くの言語がこれと同じことを主張しているも
のの、「オブジェクト指向」の解釈は言語の使用者によって異なることが多く、使用する概念を説明する用
語も異なっています。
そこで、詳細な説明に入る前に、本書で使う用語と表記法について簡単に説明しておきましょう。
オブジェクト指向のプログラムを書くときは通常、実世界の概念をコード内にモデル化しようとします。
そしてこのモデル化の過程で、コードで表現する必要があるモノのカテゴリを発見します。例えばジューク
ボックスでは、このようなカテゴリのひとつとして「曲」という概念があります。Ruby では、これらのエ
ンティティ(モノ)を表現するためにクラスを定義します。クラスとは、状態(例えば曲名)とその状態を
使用する手続き(例えば曲を演奏する手続き)を合わせたものです。
クラスを定義したら、クラスごとに多数のインスタンスを作成します。ジュークボックスシステムには
Song というクラスが定義されているので、有名なヒット曲(例えば"Ruby Tuesday"、"Enveloped in
Python"、"String of Pearls"、"Small talk" など)のインスタンスを作成することになります。クラスの
インスタンスと同じ意味で、オブジェクトという用語も使います(オブジェクトという単語のほうが短くて
簡単なので、おそらくそちらを使うことが多くなると思いますが)。
Ruby では、コンストラクタを呼び出してオブジェクトを作成します。コンストラクタはクラスに関連付
けられた特殊なメソッド(手続き)です。標準のコンストラクタはnewです。
song1 = Song.new("Ruby Tuesday")
song2 = Song.new("Enveloped in Python")
# 以下同様
これらのインスタンスは同じクラスから生成されたものですが、それぞれ固有の特性を持っています。ま
ず、すべてのオブジェクトには一意なオブジェクト識別子(オブジェクトID)があります。第二に、イン
スタンス変数(インスタンスごとに固有の値を持つ変数)を定義できます。これらのインスタンス変数はオ
ブジェクトの状態を保持します。例えば、曲というオブジェクトにはおそらく、曲のタイトルを保持するイ
ンスタンス変数があるでしょう。
各クラス内には、インスタンスメソッドを定義できます。メソッドは、クラスのコンテキスト内および
(アクセス制限にもよりますが)クラス外から呼び出すことができる、クラスの機能のひとつです。これら
のインスタンスメソッドは、オブジェクトのインスタンス変数にアクセスすることができます。つまり、イ
ンスタンスメソッドはオブジェクトの状態を参照できます。例えば、Song クラスにplay というインスタ
ンスメソッドを定義します。このとき、変数my_way が特定のSong インスタンスを参照していれば、そ
のインスタンスのplay メソッドを呼び出して、その曲を演奏することができます。
メソッドは、オブジェクトにメッセージを送信すると呼び出されます。メッセージは、メソッド名とその
メソッドに必要なパラメータからなります*1。オブジェクトはメッセージを受け取ると、自分のクラス内を
検索して対応するメソッドがないか調べます。対応するメソッドが見つかると、そのメソッドを実行しま
す。対応するメソッドが見つからない場合は......これについては後で説明しましょう。
このメソッドとメッセージの仕組みは複雑に思えるかもしれませんが、実際には極めて自然な考え方で
す。メソッド呼び出しの例をいくつか挙げてみます。次のコードでは、putsメソッドを呼び出しています。
putsはRuby の標準メソッドであり、引数をコンソールに出力し、最後に改行を追加します。
puts "gin joint".length
puts "Rick".index("c")
puts 42.even?
puts sam.play(song)
出力結果:
9
2
true
duh dum, da dum de dum ...
各行では、putsの引数としてメソッドが呼び出されています。ピリオドの前の部分がレシーバ、ピリオ
ドの後ろの部分が呼び出されるメソッドです。最初の例では、文字列の長さを尋ねています。2 番目の例で
は、別の文字列に含まれる文字c のインデックスを検索しています。3 番目の例では、42 が偶数かどうかを
尋ねています(疑問符はeven?というメソッド名の一部です)。最後に、Sam に対して曲を演奏するよう
要求しています(適切なオブジェクトを参照するsam という変数が存在しているものとします)。
ここで、Ruby と他の主要言語との主な違いについて触れておきましょう。Java では、数値の絶対値を得
るには、その数値を引数として別の関数を呼び出す必要があります。例えば次のような具合です。
num = Math.abs(num) // Java のコード
Ruby では、絶対値を計算する機能が数値自体に組み込まれています。詳細はすべて数値自体が面倒を見
てくれるのです。ですから、数値オブジェクトにメッセージabs を送信すれば、あとはオブジェクトが処
理してくれます。
num = -1234 # => -1234
positive = num.abs # => 1234
同じことが、Ruby のすべてのオブジェクトに当てはまります。例えば、C ならstrlen(name) と書く
ところは、Ruby ではname.length で済みます。我々が「Ruby は純粋なオブジェクト指向言語である」
という言い方をする理由の一部はこういうところにあります。
2.2 Ruby の基本
新しいプログラム言語を習得するとき、膨大な量の退屈なシンタックス(構文)を読むのが好きという人
はあまりいないでしょう。そこで、ここでは少しズルをして、Ruby のプログラムを書くときに知っておか
なければならないいくつかの重要な部分だけを取り上げることにします。詳しいことは第22 章(p. 289)で説
明します。
手始めに簡単なRuby のプログラムから始めましょう。個人名の入った陽気な挨拶を返すメソッドを書
き、そのメソッドを何回か呼び出してみます。
def say_goodnight(name)
result = "Good night, " + name
return result
end
# おやすみの時間...
puts say_goodnight("John-Boy")
puts say_goodnight("Mary-Ellen")
この例を見れば分かるとおり、Ruby のシンタックスは簡潔です。1 行に1 文ずつ書く限り、文末にセミ
コロンは必要ありません。コメントは#で始まり、その行の最後まで続きます。コードのレイアウトは自由
です。インデントに意味はありません(ただし、コードを配布するつもりなら、2 文字のインデントを使用
するとコミュニティのメンバから好感を持たれます)。
メソッドは、def キーワードの後に、メソッド名(この例ではsay_goodnight)と括弧付きのメソッ
ド引数を指定して定義します(実は括弧は省略可能ですが、本書では付けることにします)。Ruby では、
複合文の本体部と定義部を括弧で区切りません。単純に、本体部をキーワードend で終了するだけです。
上のメソッドの本体部は極めてシンプルです。1 行目では、リテラルの文字列"Good night, "を引数
name と連結し、その結果をローカル変数result に代入しています。2 行目では、結果を呼び出し元に返
しています。変数result を宣言する必要はありません。変数に何かを代入すると、その変数が存在する
ようになります(割り当てられます)。
メソッドを定義した後、そのメソッドを2 回呼び出しています。どちらも、結果をputsメソッドに渡し
ています。putsメソッドは、単純に引数に改行を付けて出力します(出力の次行に移ります)。
Good night, John-Boy
Good night, Mary-Ellen
次の行に注目してください。
puts say_goodnight("John-Boy")
この行では、2 つのメソッドを呼び出しています。1 つはsay_goodnightメソッド、もう1 つはputs
メソッドです。1 つ目のメソッド呼び出しでは引数に括弧が付いているのに、2 つ目のメソッド呼び出しに
は引数に括弧が付いていないのはなぜでしょうか。この例に関しては、これは全くの好みの問題です。次の
2 つの行は完全に等価です。
puts say_goodnight("John-Boy")
puts(say_goodnight("John-Boy"))
しかし、いつもこのようにシンプルにいくとは限りません。優先規則があるため、どの引数がどのメソッ
ド呼び出しに対応するのか分かりにくくなることがあります。ですから、非常に単純なケースを除いて、引
数は常に括弧で囲むことをお勧めします。
上の例は、Ruby の文字列オブジェクトについてもいくつか教えてくれます。文字列オブジェクトを作成
する方法はたくさんありますが、最もよく使われるのは文字列リテラルでしょう。文字列リテラルとは、シ
ングルクォートまたはダブルクォートで囲まれた文字の並びのことです。シングルクォート形式とダブル
クォート形式では、リテラルを生成するときRuby が文字列に対して行う処理が違ってきます。シングル
クォートを使った場合、Ruby はほとんど何もしません。わずかな例外を除き、文字列リテラルとして打ち
込んだ文字がそのまま文字列の値になります。
ダブルクォートを使った場合、Ruby はもう少し複雑な処理をします。まず、バックスラッシュで始まる
置換シーケンスを探し、それを特定の値で置き換えます。最も頻繁に使うのは、改行文字で置換される¥n
です。改行を含む文字列を出力するときは、¥n を挿入すればそこで改行されます。例えば次のような文が
あるとします。
puts "And good night,¥nGrandma"
出力結果:
And good night,
Grandma
ダブルクォート文字列に対してRuby が行う次の処理は、式の展開です。文字列中に#{expression}とい
うシーケンスを見つけると、Ruby はこれをその式の値で置換します。これを使って、上のメソッドを書き
換えると次のようになります。
def say_goodnight(name)
result = "Good night, #{name}"
return result
end
puts say_goodnight('Pa')
出力結果:
Good night, Pa
このように書くと、Ruby は文字列オブジェクトを生成するとき、name の現在値を参照して、その値を
文字列に埋め込みます。#{...}構文には、いくらでも複雑な式を指定できます。次の例では、すべての文
字列に定義されているcapitalizeメソッドを呼び出して、引数の先頭文字を大文字で出力しています。
def say_goodnight(name)
result = "Good night, #{name.capitalize}"
return result
end
puts say_goodnight('uncle')
出力結果:
Good night, Uncle
文字列およびその他のRuby の標準型について詳しくは、第6 章(p. 79)を参照してください。
上のメソッドはもう少し簡単に書くことができます。メソッドの戻り値は、そのメソッド内で最後に評価
された式の値になるため、一時変数とreturn 文は省略できるのです。
def say_goodnight(name)
"Good night, #{name.capitalize}"
end
puts say_goodnight('ma')
出力結果:
Good night, Ma
この節は簡単に済ますという約束でしたが、あと1 点だけ追加させてください。それは、Ruby で使う名
前についてです。話を簡単にするため、本章では(クラス変数など)まだ定義していない用語も使っていき
ます。しかし、ここで命名規則について説明しておけば、後でクラス変数などの説明が出てきたときに、話
が分かりやすいでしょう。
Ruby では、一見奇妙とも思える規則を使用します。まず、名前の先頭文字で、その名前が何に使われ
ているかを示します。ローカル変数・メソッドの引数・メソッド名はすべて小文字またはアンダースコア
(_)で始めなければなりません。グローバル変数にはドル記号($)を、インスタンス変数にはアットマー
ク(@)を先頭に付けます。クラス変数には、2 つのアットマーク(@@)を先頭に付けます*2。最後に、ク
ラス名、モジュール名、それに定数は、先頭文字を大文字にします。名前の具体例については表2.1 を参照
してください。
先頭文字の後には、文字・数字・アンダースコアを自由に組み合わせて指定できます(ただし@記号の直
後に数字を続けることはできません)。ただし、習慣上、複数の単語からなるインスタンス変数は、単語の
間にアンダースコアを挿入します。複数の単語からなるクラス名は大文字と小文字を混在させ、各単語の先
頭文字だけを大文字にします。メソッド名の末尾には、?、!、または=を付けることができます。
2.3 配列とハッシュ
Ruby の配列とハッシュは、添字付きコレクションです。どちらも、オブジェクトのコレクション*3を格
納し、キーで参照します。配列のキーは整数ですが、ハッシュでは任意のオブジェクトをキーとして使えま
す。配列とハッシュは、新しい要素を格納するために必要に応じて伸長します。要素のアクセスに関しては
配列のほうが効率的ですが、柔軟性という点ではハッシュのほうが上です。特定の配列またはハッシュに、
異なるタイプのオブジェクトを格納することもできます。例えば、この後すぐ見るように、1 つの配列に整
数・文字列・浮動小数点数を格納するといったことが可能です。
新しい配列を作成/初期化するには、配列リテラル------角括弧で囲まれた一連の要素------を使います。既
存の配列オブジェクトの各要素にアクセスするには、角括弧で囲んだ添字を使います。次に例を挙げます。
Ruby の配列の添字はゼロから始まる点に注意してください。
a = [ 1, 'cat', 3.14 ] # 3 つの要素を持つ配列
puts "The first element is #{a[0]}"
# 3番目の要素を設定する
a[2] = nil
puts "The array is now #{a.inspect}"
出力結果:
The first element is 1
The array is now [1, "cat", nil]
上の例で、特殊な値nil を使用していることに気付いた方もいるでしょう。大半の言語では、nil(また
はnull)は「オブジェクトがない」ことを意味します。しかし、Ruby では違います。Ruby では、nil も
他の値と同様にオブジェクトです。ただ、たまたま何も表さないというだけです。話を配列とハッシュに戻
しましょう。
単語の配列を作成する場合は、クォートやらカンマやらを使う必要があるので面倒になることがありま
す。幸いにも、Ruby には手っとり早い方法が用意されています。%w を使うと、単語の配列を簡単に作成
できます。
a = [ 'ant', 'bee', 'cat', 'dog', 'elk' ]
a[0] # => "ant"
a[3] # => "dog"
# 次のように書いても同じ:
a = %w{ ant bee cat dog elk }
a[0] # => "ant"
a[3] # => "dog"
Ruby のハッシュは配列に似ています。ハッシュリテラルには、角括弧の代わりに中括弧(ブレース)を
使います。ハッシュリテラルでは、エントリごとに2 つのオブジェクトを与える必要があります。1 つは
キー、もう1 つは値です。キーと値は通常、=>で区切って指定します。
例えば、楽器とオーケストラのセクションを対応付ける場合を考えてみます。これは次のようなハッシュ
で実現できます。
inst_section = {
'cello' => 'string',
'clarinet' => 'woodwind',
'drum' => 'percussion',
'oboe' => 'woodwind',
'trumpet' => 'brass',
'violin' => 'string'
}
=>の左側がキー、右側がキーに対応する値です。キーは一意でなければなりません。例えば、"drum" に
2 つの値を対応させることはできません。ハッシュ内のキーと値には任意のオブジェクトを指定できます。
値が配列のハッシュ、値がハッシュのハッシュなども許されます。
ハッシュの要素にアクセスするには、配列と同じように、角括弧で囲んだ添字を使います。次のコードで
は、pメソッドを用いてコンソールに値を出力しています。pメソッドはputsとほぼ同じですが、nil な
どの値も明示的に表示します。
p inst_section['oboe']
p inst_section['cello']
p inst_section['bassoon']
出力結果:
"woodwind"
"string"
nil
上の例を見れば分かるように、存在しないキーを添字にしてハッシュを参照すると、デフォルトではnil
が返されます。通常はこれで好都合です。というのは、nil は条件式で使うとfalse と同じ意味になるから
です。しかし、このデフォルトの動作を変更したい場合があります。例えば、ハッシュを使って、ファイル
内の各単語の出現回数をカウントする場合は、存在しないキーで参照したときゼロが返されたほうが好都合
です。デフォルト値をゼロに設定しておけば、単語をキーにして単純に対応するハッシュ値をインクリメン
トするだけで済みます。初めて出現する単語かどうかをいちいち気にする必要はありません。これを実現す
るには、空のハッシュを新しく作成するときにデフォルト値を指定します(単語の出現回数をカウントする
完全なプログラムは(p. 47)を参照してください)。
histogram = Hash.new(0) # デフォルト値をゼロに設定
histogram['ruby'] # => 0
histogram['ruby'] = histogram['ruby'] + 1
histogram['ruby'] # => 1
配列オブジェクトおよびハッシュオブジェクトには、便利なメソッドがたくさん定義されています。詳し
くは、p. 43 からの説明と、ライブラリ編のp. 8 とp. 91 を参照してください。
2.4 シンボル
プログラムを書いていると、何か重要なものの名前を作成しなければならない場合があります。例えば、
羅針盤の方位を名前で参照したい場合は、次のように書きます。
NORTH = 1
EAST = 2
SOUTH = 3
WEST = 4
そうすれば、以降のコードでは、次のように数値の代わりに定数を使用できます。
walk(NORTH)
look(EAST)
ほとんどの場合、こうした定数の実際の数値は(一意でさえあれば)何でも構いません。4 つの方位を識
別できればよいのです。
こうした場合に、Ruby では、もっと分かりやすい代替策を用意しています。それがシンボルです。シン
ボルとは、事前に宣言する必要がなく、なおかつ一意であることが保証される定数名のことです。シンボル
のリテラルは、コロンで始まり、その後に何らかの名前が続きます。
walk(:north)
look(:east)
シンボルに値を設定する必要はありません。Ruby が代わりに面倒を見てくれます。また、プログラムの
どこに出現しても、特定のシンボルはすべて同じ値を持ちます。したがって、次のようなコードを書くこと
ができます。
def walk(direction)
if direction == :north
# ...
end
end
シンボルはハッシュのキーとして頻繁に使用されます。前出の例は、次のように書くことができます。
inst_section = {
:cello => 'string',
:clarinet => 'woodwind',
:drum => 'percussion',
:oboe => 'woodwind',
:trumpet => 'brass',
:violin => 'string'
}
inst_section[:oboe] # => "woodwind"
inst_section[:cello] # => "string"
# 文字列とシンボルは異なることに注意...
inst_section['cello'] # => nil
シンボルをハッシュのキーとして使用することが非常に多いため、Ruby 1.9 より、新しい構文が導入さ
1.9 れました。キーがシンボルの場合、name: value のペアでハッシュを作成できます。
inst_section = {
cello: 'string',
clarinet: 'woodwind',
drum: 'percussion',
oboe: 'woodwind',
trumpet: 'brass',
violin: 'string'
}
puts "An oboe is a #{inst_section[:oboe]}"
出力結果:
An oboe is a woodwind
2.5 制御構造
Ruby は、if 文やwhile ループといった通常の制御構造をすべて備えています。Java、C、Perl などの
プログラマは、これらの文には本体部分を囲むブレースが存在しないので、驚くかもしれません。その代わ
り、Ruby では、キーワードend を使って本体部の終わりを示します。
if count > 10
puts "Try again"
elsif tries == 3
puts "You lose"
else
puts "Enter a number"
end
同様に、while 文もend で終わります。
while weight < 100 and num_pallets <= 30
pallet = next_pallet()
weight += pallet.weight
num_pallets += 1
end
Ruby の大半の文は値を返します。これは、文を条件に使えることを意味します。例えば、getsメソッド
は、標準入力ストリームから次行を読み込んで返します(EOF に到達した場合はnil を返します)。Ruby
は条件文でのnil をfalse とみなすため、ファイル内の行を処理する次のようなコードを書くことができ
ます。
while line = gets
puts line.downcase
end
この例では、代入文によって変数line に次行またはnil が設定されます。while 文は代入文の値を評
価し、結果がnil ならループを終了します。
if 文やwhile 文の本体部が式1 つだけの場合は、Ruby の文修飾子(statement modifier)として使う
と便利です。単に式の後にif またはwhile と条件を書けばよいだけです。例えば、次のような単純なif
文があるとします。
if radiation > 3000
puts "Danger, Will Robinson"
end
これを文修飾子を使って書き直すと次のようになります。
puts "Danger, Will Robinson" if radiation > 3000
同様に、次のようなwhile ループがあるとします。
square = 2
while square <1000
square = square*square
end
これを文修飾子を使って書き直すと、次のように簡単になります。
square = 2
square = square*square while square <1000
これらの文修飾子は、Perl プログラマにはお馴染みのはずです。
2.6 正規表現
Ruby のほとんどの組み込み型は、すべてのプログラマが既に知っています。ほとんどの言語は文字列・
整数・浮動小数点数・配列などの型を持っています。しかし、正規表現となると話は別です。正規表現は通
常、Ruby、Perl、awk といったスクリプト言語でしかサポートされていません。これは残念なことです。
正規表現は、少し暗号じみてはいますが、テキスト処理には極めて強力な道具です。この強力な道具が、最
初から組み込まれているのと、付け足しのようにライブラリインタフェースを介してサポートされているの
とでは、大きな差があります。
正規表現に関しては専門の参考書(例えばMastering Regular Expressions [Fri06] など)があるので、こ
の短い節ですべてを説明するつもりはありません。ここでは、正規表現のいくつかの使用例を挙げるにとど
めます。詳しくは第7 章(p. 89)からの説明を参照してください。
正規表現とは、文字列にマッチする文字のパターンを指定する方法のひとつです。Ruby では通常、ス
ラッシュで挟まれたパターン(/パターン/)を書くことで正規表現を作成します。そして、Ruby ではもち
ろん正規表現もオブジェクトですから、オブジェクトとして操作できます。
例えば、Perl またはPython というテキストを含む文字列にマッチするパターンを正規表現で書くと、次
のようになります。
/Perl|Python/
スラッシュがパターンを区切っています。このパターンは、マッチさせる2 つのものを縦棒(|)でつな
げています。この縦棒は「右側または左側のもの」という意味です。ですから、この例では、Perl または
Python という意味になります。パターン内では算術式と同じように括弧を使えます。上のパターンは次の
ように書いても同じです。
/P(erl|ython)/
パターン内には繰り返しも指定できます。/ab+c/は、1 つのa の後に1 回以上b が続き、さらにその後
に1 つのc が続く文字列にマッチします。+ を*に変えて/ab*c/とすると、1 つのa の後に0 回以上のb が
きて、さらに1 つのc がくる文字列にマッチする正規表現になります。
文字グループ中の1 文字にマッチするパターンもあります。よく使われるのは文字クラスです。例えば、
¥s は空白文字(スペース・タブ・改行など)にマッチし、¥d は数字にマッチし、¥w は英数字と_にマッチ
します。. (ピリオド)は任意の1 文字にマッチします。これらの文字クラスはp. 96 の表にまとめてあり
ます。
これらをすべて使えば、いくつか便利な正規表現を書くことができます。
/¥d¥d:¥d¥d:¥d¥d/ # 12:34:56 などの時刻
/Perl.*Python/ # Perl の後に0 個以上の任意の文字がきてPython がくる文字列
/Perl Python/ # Perl の後に1 つのスペースがきてPython がくる文字列
/Perl *Python/ # Perl の後に0 個以上のスペースがきてPython がくる文字列
/Perl +Python/ # Perl の後に1 つ以上のスペースがきてPython がくる文字列
/Perl¥s+Python/ # Perl の後に空白文字がきてPython がくる文字列
/Ruby (Perl|Python)/ # Ruby の後に1 つのスペースがきてPerl またはPython がくる
# 文字列
パターンを作成したら、それを使わない手はありません。文字列を正規表現にマッチさせるには、マッチ
演算子=‾を使用します。文字列内にパターンを見つけると、=‾はそのパターンの開始位置を返し、見つか
らなければnil を返します。したがって、正規表現は、if 文やwhile 文の条件に使えます。例えば、次
のコードはPerl またはPython というテキストが文字列に含まれていれば、メッセージを出力します。
if line =‾ /Perl|Python/
puts "Scripting language mentioned: #{line}"
end
Ruby の置換メソッドのひとつを使用すれば、正規表現にマッチした文字列の一部を他のテキストで置き
換えることができます。
line.sub(/Perl/, 'Ruby') # 最初のPerl をRuby で置き換える
line.gsub(/Python/, 'Ruby') # すべてのPython をRuby で置き換える
すべてのPerl またはPython をRuby で置き換えるには、次のように書きます。
line.gsub(/Perl|Python/, 'Ruby')
正規表現については、今後も随時取り上げて詳しく説明することにします。
2.7 ブロックとイテレータ
この節では、Ruby が備えている強力な機能のひとつであるコードブロックについて簡単に説明します。
コードブロックとは、あたかもパラメータのようにメソッド呼び出しに関連付けることができるコードのか
たまりのことです。これは信じられないくらい強力な機能です。本書のレビューアの一人が、この節を読ん
だ時点で次のようにコメントしています。「これは非常に面白く重要な機能だから、これまで注意を払って
こなかった読者は、これから注意を払うようにすべきです」。筆者らも同じ意見です。
コードブロックを使えば、コールバックを実装したり(Java の無名内部クラスよりも簡単)、コードのか
たまりを持ち歩いたり(C の関数ポインタよりも柔軟性が高い)、イテレータを実装したりできます。
コードブロックとは、ブレースまたはdo. . . end で囲まれた単なるコードのかたまりです。次に例を挙げ
ます。
{ puts "Hello" }
do. . . end で囲まれたブロックの例を挙げます。
do
club.enroll(person)
person.socialize
end
なぜ2 種類のデリミタが用意されているのでしょうか。ひとつには、場合によって、どちらか一方のデリ
ミタを使ったほうがより自然に感じられることがあるからです。また、この2 つのデリミタは優先順位が異
なります。ブレースのほうがdo/end よりも結合力が強いのです。本書では、Ruby で標準になりつつあ
る習慣に従って、1 行のブロックにはブレースを、複数行のブロックにはdo/end を使います。
ブロックはメソッド呼び出しに関連付けることによって使用します。ブロックをメソッド呼び出しに関連
付けるには、ブロックの開始位置を、メソッド呼び出しを含む行の終わりに持ってきます。
例えば、次のコードでは、puts "Hi"を含むブロックがgreetメソッドの呼び出しに関連付けられま
す(greetの中身はここでは表示していません)。
greet { puts "Hi" }
メソッドの引数がある場合は、ブロックの前に指定します。
verbose_greet("Dave", "loyal customer") { puts "Hi" }
これで、メソッドは、自分に関連付けられたブロックを、Ruby のyield 文を使って1 回または複数回
呼び出すことができます。yield 文は、yield 文を含むメソッドに関連付けられたブロックを呼び出すメ
ソッド呼び出しのようなものと考えることができます。
以下のコード例はyield が動作する様子を示しています。この例では、まず、yield を2 回呼び出すメ
ソッドを定義しています。次に、そのメソッドを呼び出していますが、その際、ブロックを同一行(メソッ
ドに引数がある場合はその後)に指定しています*4。
def call_block
puts "Start of method"
yield
yield
puts "End of method"
end
call_block { puts "In the block" }
出力結果:
Start of method
In the block
In the block
End of method
*4 ブロックをメソッドに関連付けることを一種のパラメータ渡しと考えたがる人がいます。これはある面では正しいのですが、そ
れがすべてではありません。それよりも、ブロックとメソッドを、互いに制御を渡したり受け取ったりするコルーチンと考えた
ほうがよいでしょう。
ブロック内のコード(puts "In the block")が、yield が呼び出されるたびに実行されているこ
とを確認してください。
yield にパラメータを指定すると、それがブロックに渡されます。ブロック内では、これらのパラメー
タを受け取るための仮引数名のリストを縦棒の間に指定します(| params... |)。次の例では、メソッ
ドが自分に与えられたブロックを2 回呼び出しており、その際、ブロックに2 つの引数を渡しています。
def who_says_what
yield("Dave", "hello")
yield("Andy", "goodbye")
end
who_says_what {|person, phrase| puts "#{person} says #{phrase}"}
出力結果:
Dave says hello
Andy says goodbye
コードブロックはRuby のライブラリのいたるところで、イテレータを実装するために使われています。
イテレータとは、配列などのコレクションから連続する要素を返すメソッドのことです。
animals = %w( ant bee cat dog elk ) # 配列を作成する
animals.each {|animal| puts animal } # 配列の要素を繰り返し処理する
出力結果:
ant
bee
cat
dog
elk
C やJava などの言語に組み込まれている多くのループ構造は、Ruby では単なるメソッド呼び出しとし
て実現されます。メソッドは自分に関連付けられたブロックを0 回以上呼び出します。
[ 'cat', 'dog', 'horse' ].each {|name| print name, " " }
5.times { print "*" }
3.upto(6) {|i| print i }
('a'..'e').each {|char| print char }
出力結果:
cat dog horse *****3456abcde
最初の例では、配列に対して、要素ごとにブロックを呼び出すよう要求しています。2 番目の例では、数
値オブジェクトである5 がブロックを5 回呼び出しています。3 番目の例では、for ループを使うことな
く、数値オブジェクト3 にブロックを呼び出すよう要求しています。その際、6 に到達するまでの連続する
数値をブロックに引数として渡しています。最後の例は、a からe までの文字範囲が、eachメソッドを使っ
てブロックを呼び出しています。
2.8 簡単な読み書き
Ruby では、総合I/O ライブラリが提供されています。しかし、本書のほとんどの例では、いくつかの単
純なメソッドだけを使用することにします。既に出力を実行する2 つのメソッドが出てきました。puts と
print がそれです。puts は各引数に改行を付けて出力します。print も引数を出力しますが、改行は付
けません。どちらも、任意のI/O オブジェクトに書き出すことができますが、デフォルトではコンソール
に書き出します。
もう1 つの頻繁に使う出力用メソッドとして、printfがあります。このメソッドは、引数をフォーマッ
ト文字列で指定されたとおりに出力します(C やPerl のprintf と同じです)。
printf("Number: %5.2f,¥nString: %s¥n", 1.23, "hello")
出力結果:
Number: 1.23,
String: hello
上の例では、フォーマット文字列"Number: %5.2f,¥nString: %s¥n"を使って、printfに、浮動
小数点数(最低5 文字で小数点以下2 桁)と文字列の出力形式を指定しています。文字列に改行文字(¥n)
が埋め込まれている点に注意してください。これにより、出力が次行に移ります。
プログラムに入力を読み込む方法はたくさんあります。おそらく最も一般的なのはgets ルーチンを使
う方法でしょう。gets はプログラムの標準入力ストリームから次の行を返します。
line = gets
print line
getsは、入力の終わりに到達するとnil を返すため、ループの条件に直接指定できます。次の例で、
while の終了条件が代入文になっている点に注意してください。つまり、getsの戻り値を変数line に格
納し、その戻り値がnil(すなわちfalse)であればループを終了しています。
while line = gets
print line
end
2.9 コマンドライン引数
Ruby のプログラムをコマンドラインから実行する場合には、引数を渡すことができます。コマンドライ
ン引数を参照するには2 つの方法があります。
1 つはARGV 配列です。ARGV 配列には、実行中のプログラムに渡される各引数が格納されます。例えば
cmd_line.rb というファイルを作成し、次のようなコードを入力します。
puts "You gave #{ARGV.size} arguments"
p ARGV
引数を指定してこのプログラムを実行すると、プログラムに渡された引数が表示されます。
$ ruby cmd_line.rb ant bee cat dog
出力結果:
You gave 4 arguments
["ant", "bee", "cat", "dog"]
多くの場合、プログラムに与える引数は、処理するファイルの名前です。その場合は、コマンドライン引
数を参照する2 つ目の方法としてARGF 変数が使えます。ARGF 変数は特殊なI/O オブジェクトで、コマ
ンドラインで渡された名前を持つすべてのファイル(コマンドライン引数を指定しない場合は標準入力)の
内容を表します。詳しくは22.5(p. 306)で解説します。
2.10 いざ、Ruby の世界へ
さて、Ruby の基本機能について駆け足で説明してきました。オブジェクト・メソッド・文字列・コンテ
ナ・正規表現について説明し、いくつかの簡単な制御構造と、かなり気の利いたイテレータについても見ま
した。本書を読み進めるにあたって、この章で紹介した予備知識が役立てば幸いです。
次の段階に進むときがやってきました。次は、クラスとオブジェクトについて見ていきます。どちらも、
Ruby で最高レベルの構文であると同時に、Ruby という言語全体に不可欠な基盤でもあります。
このタイトルのKindle化をご希望の場合、こちらをクリックしてください。
Kindle をお持ちでない場合、こちらから購入いただけます。 Kindle 無料アプリのダウンロードはこちら。
登録情報
- 出版社 : オーム社 (2010/5/26)
- 発売日 : 2010/5/26
- 単行本(ソフトカバー) : 450ページ
- ISBN-10 : 4274068099
- ISBN-13 : 978-4274068096
- Amazon 売れ筋ランキング: - 1,186,083位本 (の売れ筋ランキングを見る本)
- - 4,788位ソフトウェア開発・言語
- カスタマーレビュー:
著者について
著者の本をもっと発見したり、よく似た著者を見つけたり、著者のブログを読んだりしましょう
著者の本をもっと発見したり、よく似た著者を見つけたり、著者のブログを読んだりしましょう
カスタマーレビュー
上位レビュー、対象国: 日本
レビューのフィルタリング中に問題が発生しました。後でもう一度試してください。
いきなりコマンドプロンプトやターミナルでの操作が説明されている。
サンプルコードなどの使い方で説明していない部分が多く、何をしているかはなんとなくわかるが、自分で使うにはさらに詳しく調べてからでないと難しいといった場合が多い。
基本的に、すでにRubyを知っている人向けのような書き方である。
プログラミング経験が豊富でターミナルなどの操作に慣れていれば、有益な書籍ではないだろうか。
プログラミング初心者やRubyがまったく初めてといった場合は、他の書籍を読んだ後にこの本でさらに詳しく学ぶのがよい。