rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/etc/oss/subject1-3_lesson.pdf ·...

136
Ruby プログラミング中級

Upload: vuongdat

Post on 29-Aug-2019

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Rubyプログラミング中級Rubyプログラミング中級

Page 2: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第1章 Rubyにおけるオブジェクト指向⑴ 11.1 メソッド 21.1.1 メソッドの呼び出し 21.1.2 レシーバの省略 31.1.3 関数的メソッド 41.1.4 メソッドの定義 51.1.5 メソッドの戻り値 71.1.6 ブロック付メソッド 8

第2章 Rubyにおけるオブジェクト指向⑵ 112.1 クラスの定義と利用 122.1.1 クラスの定義 122.1.2 インスタンスの初期化 132.1.3 クラスメソッドとクラス変数 142.1.4 アクセスメソッド 152.1.5 継承 172.1.6 クラス定義の追加 19

第3章 Rubyにおけるオブジェクト指向⑶ 213.1 変数と定数 223.1.1 ローカル変数 223.1.2 インスタンス変数とクラス変数 233.1.3 グローバル変数と組み込み変数 243.1.4 定数 25

3.2 アクセス権限と特異メソッド 263.2.1 アクセス権限 263.2.2 アクセス権限の設定 273.2.3 特異メソッド 28

第4章 Rubyにおけるオブジェクト指向⑷ 314.1 モジュール 324.1.1 モジュールとは 324.1.2 モジュールの利用 334.1.3 モジュールの定義 34

4.2 Mix-in 354.2.1 Mix-inとは 35

Page 3: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Version 0.00

目次

4.2.2 kernelモジュール 374.2.3 名前空間 38

第5章 正規表現 415.1 正規表現の基礎 425.1.1 正規表現とは 42

5.2 正規表現の利用 445.2.1 正規表現オブジェクトの作成 445.2.2 パターンマッチ 455.2.3 正規表現のオプション 465.2.4 後方参照 475.2.5 文字列パターンの置換 48

第6章 イテレータ 516.1 イテレータの利用 526.1.1 イテレータとは 526.1.2 eachメソッド 536.1.3 繰り返し処理 55

6.2 イテレータの作成 586.2.1 yieldキーワード 58

第7章 ファイル入出力 617.1 入出力の基本 627.1.1 標準入出力 627.1.2 コマンドライン引数 63

7.2 基本的な入出力操作 647.2.1 ファイルのopenとclose 647.2.2 入力操作 657.2.3 ファイルポインタ 687.2.4 出力操作 707.2.5 バイナリモード 71

Page 4: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第8章 ファイル/ディレクトリ操作 738.1 ディレクトリ操作 748.1.1 ディレクトリの場所 748.1.2 ディレクトリの読み込み 758.1.3 ファイル名のパターンマッチ 768.1.4 ディレクトリの作成と削除 77

8.2 ファイル操作 788.2.1 ファイル名の操作 788.2.2 ファイルの削除 798.2.3 ファイル名の操作 808.2.4 ファイルの属性 81

第9章 その他の組み込みライブラリ 839.1 Timeクラス 849.1.1 Timeクラスの概要 849.1.2 日時のフォーマット 859.1.3 時刻の操作 86

9.2 DateTimeクラスとDateクラス 879.2.1 DateTimeクラス 879.2.2 Dateクラス 89

第10章 RubyGems 9310.1 RubyGemsとは 9410.1.1 RubyGemsのインストール 94

10.2 RubyGemsの利用 9510.2.1 gemコマンド 9510.2.2 パッケージのインストール 9710.2.3 パッケージのアップデート 9810.2.4 パッケージのアンインストール 9910.2.5 パッケージ情報の検索 10010.2.6 gemのサブコマンド一覧 102

10.3 Rake 10310.3.1 Rakeファイル 10310.3.2 rakeコマンド 10410.3.3 ファイルの依存関係 105

Page 5: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Version 0.00

目次

第11章 実践的Rubyプログラミング 10711.1 Rubyならではのプログラミング 10811.1.1 可変引数 10811.1.2 シンボル 10911.1.3 変数の初期化 111制御式による代入 112

11.2 誤りやすいポイント 11311.2.1 識別子 11311.2.2 if式の評価 11411.2.3 elsif 115

11.3 その他の話題 11611.3.1 メソッドの探索手順 11611.3.2 eval 117

第12章 RubyによるGUIアプリケーション 11912.1 RubyによるGUIアプリケーション開発 12012.1.1 Ruby/TKの概要とインストール 12012.1.2 簡単なGUIアプリケーションの作成と実行 12112.1.3 ルートウィジェットとイベントループ 12212.1.4 ラベルウィジェット 12312.1.5 ウィジェットの作成 12412.1.6 ボタンウィジェット 12512.1.7 テキストエリア 126

Page 6: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第1章Rubyにおける

オブジェクト指向⑴

Page 7: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

2 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第1章

※この場合は、()を省略すると誤って解釈されることがあるので、()は省略すべきではありません。

1.1 メソッド

1.1.1 メソッドの呼び出しRubyプログラムで中心的となるのはメソッド呼び出しです。メソッドを呼び出す書式は次のとおりです。

引数の()は、曖昧でない限りは省略することができます。

Rubyでは、メソッドの戻り値に対してさらにメソッドを実行(メソッド連鎖)することができます。

オブジェクト.メソッド名(引数)

メソッド呼び出し1

line.chomp!.upcase

メソッド連鎖の例

Page 8: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

3Version 0.00

第1章 Rubyにおけるオブジェクト指向⑴

第1章1.1.2 レシーバの省略

メソッドの対象であるオブジェクトをレシーバといいます。レシーバを省略すると、デフォルトのレシーバであるselfのメソッドを呼び出すことになります。なお、レシーバを省略した場合、ローカル変数の参照なのか、メソッドの呼び出しなのか、見分けが付かなくなる場合があります。その場合は、ローカル変数の参照として扱われます。

class Adef foo"FOO"

end

def barfoo = "XXX"puts foo + self.foo

endend

a = A.newa.bar # => 'XXXFOO'

mymethod1.rb

メソッドの分類メソッドは、レシーバによって「インスタンスメソッド」「クラスメソッド」「関数的メソッド」に分類できます。インスタンスをレシーバとするものがインスタンスメソッド、クラスそのものをレシーバとするものがクラスメソッドです。関数的メソッドは次項で述べます。

Page 9: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

4 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第1章

※Rubyでは、レシーバのない「関数」は存在しません。

1.1.3 関数的メソッド関数的メソッドとは、C言語の関数のように、レシーバを使わないメソッドのことです。ただし、本当にレシーバがないわけではなく、レシーバの情報を使わないのです。今までに登場したものでは、オブジェクトの内容を出力するpメソッドや、文字列をコンソールに出力するputsメソッドなどが関数的メソッドです。これらの関数的メソッドはどこからでも呼び出せます。

以下は関数的メソッドの例です。

・p obj・puts "str"・print "str"・sleep(5)・Math.sin(5)

Page 10: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

5Version 0.00

第1章 Rubyにおけるオブジェクト指向⑴

第1章1.1.4 メソッドの定義

メソッドはdef式で定義します。

引数の()を省略することもできます。

メソッドの内容が簡潔なものなら、1行にまとめて記述してもかまいません。

次に、シンプルな例を示します。

def メソッド名(引数リスト) 処理end

メソッド定義1

def メソッド名 引数リスト 処理end

メソッド定義2

def メソッド名(引数リスト) 処理 end

メソッド定義3

def hello(name)puts "Hello, #{name}."

end

hello("World")hello Ruby

method1.rb

$ ruby method1.rbHello, World.Hello, Ruby.

Page 11: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

6 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第1章 メソッドの引数には、引数が何も指定されなかったときのデフォルト値を

指定することができます。

def hello(name="World")puts "Hello, #{name}."

end

hello()hello("Ruby")

method2.rb

$ ruby method2.rbHello, World.Hello, Ruby.

Page 12: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

7Version 0.00

第1章 Rubyにおけるオブジェクト指向⑴

第1章1.1.5 メソッドの戻り値

メソッドを実行すると、戻り値が得られます。戻り値となる値は、return式で指定した値か、メソッド内で最後に評価した値となります。

複数の戻り値を返すこともできます。この場合は「最後に評価した値」というわけにはいかないので、必ずreturnを使います。戻り値は配列です。

Rubyでは、C言語におけるvoid型のような、戻り値を返さないメソッドはありません。戻り値が不要なメソッドを定義する場合、nilを返すようにするとよいでしょう。

$ ruby method4.rb3 + 5 = 8

def sum(a, b)return a + b

end

c = sum(3, 5)puts "3 + 5 = #{c}"

method4.rb

$ ruby method5.rb[1, 2, 3]

def multivaluereturn 1, 2, 3

end

p multivalue

method5.rb

def hello(name)puts "Hello, #{name}."nil

end

method6.rb

Page 13: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

8 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第1章 1.1.6 ブロック付メソッド

メソッド呼び出しの時にブロックを指定することができます。eachメソッドの例を見てみましょう。

「{}」というブロックが引数として与えられていることが分かります。

ary = %w|Ruby PHP Python Perl Java C C++ C# D|count = 1ary.each {| lang |puts "#{count}: #{lang}"count += 1

}

method7.rb

$ ruby method7.rb1: Ruby2: PHP3: Python4: Perl5: Java6: C7: C++8: C#9: D

Page 14: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

9Version 0.00

第1章 Rubyにおけるオブジェクト指向⑴

第1章第1章 テスト

問 題 1メソッドの処理対象となるオブジェクトのことを何と呼びますか?

問 題 2関数的メソッドとはどのようなものですか?

問 題 3メソッドの戻り値となる値は、return文で指定しない場合、どのような値になりますか?

Page 15: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作
Page 16: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第2章Rubyにおける

オブジェクト指向⑵

Page 17: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

12 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第2章

2.1 クラスの定義と利用

2.1.1 クラスの定義クラスを定義するにはclass式を使います。

クラス名は必ず英大文字で始めます。なお、クラス名はファイル名と無関係ですし、1つのファイル内に複数のクラスを定義してもかまいません。クラス内の処理には通常、インスタンスメソッドの定義を記述します。

この例では、helloメソッドとbyeメソッドはHelloクラスのインスタンスメソッドです。最後の2行で、インスタンスに対してこれらのメソッドを呼び出しています。

class クラス名 処理end

クラスの定義

$ ruby classtest1.rbHello, Ruby.Good-bye.

class Hellodef helloputs "Hello, Ruby."

enddef byeputs "Good-bye."

endend

g = Hello.newg.hellog.bye

classtest1.rb

Page 18: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

13Version 0.00

第2章 Rubyにおけるオブジェクト指向⑵

第2章

2.1.2 インスタンスの初期化

※メンバ変数、プロパティ、属性とも呼ばれます。

クラス定義内でinitializeメソッドを定義すると、インスタンス生成時に自動的に実行されます。インスタンスの初期化処理を記述します。

@で始まる名前の変数はインスタンス変数です。newメソッドの引数として指定された値が@name変数に格納されます。

class Hellodef initialize(name)@name = name

enddef helloputs "Hello, #{@name}."

enddef byeputs "Good-bye, #{@name}"

endend

fred = Hello.new("Fred")fred.hellofred.bye

classtest2.rb

$ ruby classtest2.rbHello, Fred.Good-bye, Fred

Page 19: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

14 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第2章

2.1.3 クラスメソッドとクラス変数クラスに直接属しているクラスメソッドは、インスタンスを生成しなくても呼び出すことができます。クラスメソッドは次の書式で定義します。

もしくは、次のように記述してもかまいません。

次のようにしてもクラスメソッドを定義できます。

クラスメソッドは、「クラス名.メソッド名」として呼び出すことができます。

class クラス名def クラス名.メソッド名(引数)処理

endend

クラスメソッドの定義1

class クラス名def self.メソッド名(引数)処理

endend

クラスメソッドの定義2

class Hellodef Hello.helloputs "Hello!"

endend

Hello.hello #=> Hello!

classtest3.rb

class クラス名class << selfdef メソッド名(引数)処理

endend

end

クラスメソッドの定義3

Page 20: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

15Version 0.00

第2章 Rubyにおけるオブジェクト指向⑵

第2章

2.1.4 アクセスメソッドインスタンス変数は、外部からアクセスすることができませんが、インスタンス変数にアクセスするメソッドを定義すれば、参照や代入ができるようになります。そのようなメソッドをアクセスメソッド(アクセサ)といいます。次の例では、インスタンス変数を参照するためのメソッドと、変更をするためのメソッドをそれぞれ定義しています。

実際には、次のようにすればアクセスメソッドを定義できます。

$ ruby classtest4.rbCentOS 5.3Ubuntu 9.04

class Linuxdef distro=(d)@distro = d

enddef version=(v)@version = v

enddef distro@distro

enddef version@version

endend

c = Linux.newc.distro = "CentOS"c.version = "5.3"puts "#{c.distro} #{c.version}"

u = Linux.newu.distro = "Ubuntu"u.version = "9.04"puts "#{u.distro} #{u.version}"

classtest4.rb

attr_accessor :インスタンス変数名

アクセスメソッドの定義

Page 21: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

16 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第2章

attr_accessorメソッドを使ってclasstest4.rbを書き換えると、次のようにシンプルになります。

なお、インスタンス変数の読み取りだけを行うにはattr_readerを、書き込みだけを行うにはattr_writerをattr_accessorの代わりに使います。

「:名前」はシンボルといいます。シンボルとは、文字列や変数などの識別子に任意のIDを割り当てる仕組みです(11章を参照)。

class Linuxattr_accessor :distro, :version

end

c = Linux.newc.distro = "CentOS"c.version = "5.3"puts "#{c.distro} #{c.version}"

u = Linux.newu.distro = "Ubuntu"u.version = "9.04"puts "#{u.distro} #{u.version}"

classtest5.rb

Page 22: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

17Version 0.00

第2章 Rubyにおけるオブジェクト指向⑵

第2章

2.1.5 継承あるクラスの内容を引き継いで別のクラスを生成することを継承といいます。継承により、スーパークラスに共通する処理をまとめることができます。元のクラスをスーパークラス、継承して作られたクラスをサブクラスといいます。class式で「クラス名 < スーパークラス名」のように指定します。

次の例では、Animalクラスをスーパークラスとして、DogクラスとBirdクラスを作っています。

class クラス名 < スーパークラス名処理

end

継承

class Animaldef eatputs "えさを食べます。"

enddef sleepingputs "眠ります。"

endend

class Dog < Animaldef bowputs "ワンワン!"

endend

class Bird < Animaldef singputs "ピィピィ!"

endend

pochi = Dog.newpochi.eatpochi.bowpochi.sleeping

pchan = Bird.newpchan.eatpchan.singpchan.sleeping

inheritance.rb

Page 23: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

18 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第2章

superメソッドを使うと、スーパークラスにある同名のメソッドを呼び出すことができます。

$ ruby inheritance.rbえさを食べます。ワンワン!眠ります。えさを食べます。ピィピィ!眠ります。

class Adef x(str)puts str * 3

endend

class B < Adef x(str)super(str)puts "END"

endend

b = B.newb.x("hello")

super.rb

Page 24: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

19Version 0.00

第2章 Rubyにおけるオブジェクト指向⑵

第2章

2.1.6 クラス定義の追加Rubyでは、既存のクラスに後からメソッドを追加することもできます。この仕様をオープンクラスといいます。次の例では、Numericクラスに、KバイトやMバイトをバイト単位に変換するkbメソッド、mbメソッドを追加しています。

class Numericdef kbself * 1024

enddef mbself * 1024 * 1024

endend

puts "2KB = #{2.kb}bytes."puts "2MB = #{2.mb}bytes."

mkbytes.rb

$ ruby mkbytes.rb2KB = 2048bytes.2MB = 2097152bytes.

Page 25: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

20 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第2章

第2章 テスト

問 題 1クラスに関する記述として適切なものに○をつけてください。 (  )クラス名は必ず大文字で始める (  )スクリプトのファイル名はクラス名と同じにする (  )組み込みクラスにメソッドを追加することができる

問 題 2インスタンス生成時に自動的に実行される初期化処理を記述するには、クラス定義内で何というメソッドに定義すればよいですか?

問 題 3インスタンス変数に外部からアクセスできるようにするためのメソッドを何と呼びますか?

問 題 4クラス定義で、Aクラスの内容を引き継いでBクラスを生成したいとき、class式の下線部にはどのように記述すればよいですか?class ________________

Page 26: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第3章Rubyにおける

オブジェクト指向⑶

Page 27: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

22 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第3章

3.1 変数と定数

3.1.1 ローカル変数変数には、その適用範囲(スコープ)があります。最もスコープの狭い変数がローカル変数です。メソッド定義内、クラス定義内、ブロック内ごとにスコープが分かれます。変数名には任意の英小文字と「_」を使用できます。

ブロックの外側で初期化された変数は、ブロックの内側でも有効です。逆に、ブロックの内側で初期化された変数は、ブロックの外側では無効です。ブロックの内側のみで初期化された変数をブロック外で参照すると、エラーが発生します。

メソッド内で定義されたローカル変数は、メソッドの中が有効なスコープです。メソッド外で定義されたローカル変数は、メソッド内では無効です。

変数と定数は、いずれもオブジェクトへの参照です。Rubyの変数の特徴は、型を持っていないことです。同一の変数に、さまざまなクラスのオブジェクトを格納する(参照する)ことができます。

var = "var1"def method1var = "var2"puts var

end

puts varmethod1

3.times {|var|puts var

}puts var

local.rb

$ ruby local.rbvar1var20122

Page 28: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

23Version 0.00

第3章 Rubyにおけるオブジェクト指向⑶

第3章

3.1.2 インスタンス変数とクラス変数インスタンス変数とは、特定のオブジェクトに属している変数で、同じオブジェクトのメソッドからのみアクセスできます。オブジェクトの状態を表すための変数として利用されます。変数名は「@」で始まります。

外部からインスタンス変数を「object.@var」のように、外部からアクセスすることはできません。そのためには、アクセスするためのメソッド(アクセスメソッド、アクセサ)が必要です(第2章参照)。

一方、クラスが持つ変数をクラス変数といいます。クラス変数のスコープは、定義されたクラスから生成されたインスタンスすべてです。また、すべてのインスタンスで共有されます。変数名は「@@」で始まります。クラス変数とインスタンス変数を使った例を以下に示します。

クラス変数@@countは、helloメソッドが呼び出された回数を表します。

class Hello2@@count = 0

def Hello2.count@@count

enddef initialize(name)@name = name

enddef helloputs "Hello, #{@name}."@@count += 1

endend

fred = Hello2.new("Fred")puts "Hello count: #{Hello2.count}"fred.hellofred.helloputs "Hello count: #{Hello2.count}"

vartest.rb

$ ruby vartest.rbHello count: 0Hello, Fred.Hello, Fred.Hello count: 2

Page 29: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

24 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第3章

3.1.3 グローバル変数と組み込み変数プログラム全体をスコープとする変数がグローバル変数(大域変数)です。グローバル変数は、変数名の頭に「$」を付けます。グローバル変数は、大規模なプログラムではエラーの原因となるため、利用は推奨されません。自分だけが利用するような短いスクリプトであれば、使ってもよいでしょう。

また、あらかじめ予約されている変数のことを組み込み変数といいます。組み込み変数も変数名は「$」で始まります。

[表3-1]主な組み込み変数組み込み変数 説明

$_ 直前にgetsメソッドで読み込んだ文字列$& パターンマッチにマッチした文字列$` パターンマッチでマッチした部分以前の文字列$' パターンマッチでマッチした部分以降の文字列$1, $2 ... パターンマッチでそれぞれの()にマッチした文字列$? 終了した子プロセスの終了ステータス$! 最後に発生した例外$@ 最後に発生した例外の場所$\ 入力コードの区切り文字$1 出力コードの区切り文字$. 最後に読み込んだ入力ファイルの行番号$< ARGFと同じ$> putsやpメソッドの出力先(デフォルトは標準出力)$0 実行中のRubyスクリプト名$* ARGVと同じ$$ 実行中のRubyのPID$" requireが検索するディレクトリの配列$stdin 標準入力$stdout 標準出力$stderr 標準エラー出力$KCODE 処理をする文字コード

Page 30: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

25Version 0.00

第3章 Rubyにおけるオブジェクト指向⑶

第3章

3.1.4 定数※定数はクラスもしくはモジュールに属します。トップレベルで定義した定数はObjectクラスに属します。

定数は、特定のオブジェクトへの参照を持ち続けることを前提とする特殊な変数です。定数名はアルファベット大文字で開始します。

Rubyでは、定数にオブジェクトを再代入することができますが、その際には警告されます。

基本的にメソッド内では、定数を定義することはできません。また、定義されていない定数を参照すると、例外が発生します。

irb(main):001:0> Const = "Ruby"=> "Ruby"irb(main):002:0> puts ConstRuby=> nil

irb(main):003:0> Const = "Python"(irb):3: warning: already initialized constant Const=> "Python"irb(main):004:0> p Const"Python"=> nil

irb(main):005:0> p Const2NameError: uninitialized constant Const2

from (irb):5from :0

Page 31: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

26 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第3章

3.2 アクセス権限と特異メソッド

3.2.1 アクセス権限クラスに定義したメソッドをどこからでも呼び出せるのは、オブジェクト指向の「隠蔽」という点に反するため、好ましくない場合があります。たとえば、内部的な処理をするメソッドは、外部のオブジェクトに公開するのは望ましくないでしょう。メソッドにはアクセス権限を設定することができるので、適切なアクセス権限を選択するようにします。アクセス権限には以下の3種類があります。

◆public

どこからでも呼び出すことができる状態です。class内で定義されたメソッドは、デフォルトではpublicとなります。インスタンスメソッドとして利用することができます。

◆private

メソッドを定義したクラスとサブクラスのインスタンスからのみ呼び出すことができます。「クラス名.メソッド名」のような形ではなく、関数形式でしか呼び出すことができません。同じクラスに属するインスタンスどうしであっても、他のオブジェクトのメソッドは呼び出すことができません。トップレベルで定義されたメソッドは、デフォルトではprivateとなります。

◆protected

当該クラスもしくはサブクラスのインスタンスメソッドとしてのみ呼び出すことができます。レシーバを指定した形式でも呼び出すことができるため、同じクラスまたはサブクラスの他のインスタンスからも呼び出すことができます。

Page 32: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

27Version 0.00

第3章 Rubyにおけるオブジェクト指向⑶

第3章

3.2.2 アクセス権限の設定アクセス権限を設定するには、それぞれpublic、private、protectedメソッドを実行します。

public、private、protected各メソッドに「:メソッド名」を指定し、そのメソッドだけにアクセス権限を設定する方法もあります。

次の例では、publicを指定したメソッドとprivateを指定したメソッドを比較しています。

private# ここで定義したメソッドはprivateになる

protected# ここで定義したメソッドはprotectedになる

アクセス権限の設定1

public :メソッド名

private :メソッド名

protected :メソッド名

アクセス権限の設定2

class Accesstestdef public_methodputs "Public Method"

endprivatedef private_methodputs "Private Method"

endend

at = Accesstest.newat.public_methodat.private_method #=>エラーになる

accesstest.rb

$ ruby accesstest.rbPublic Methodaccesstest.rb:13: private method `private_method' called for#<Accesstest:0xb7f62a2c> (NoMethodError)

Page 33: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

28 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第3章

3.2.3 特異メソッド特異メソッドとは、特定のインスタンスにのみ属しているメソッドです。通常、メソッドはクラスに属していますが、個々のオブジェクトに固有のメソッドを定義することもできます。

次の例では、var1が参照している文字列オブジェクトにのみ属するhelloメソッドを定義しています。たとえ同じ文字列を参照しているように見えても、var1の参照先文字列オブジェクトとvar2の参照先文字列オブジェクトは別物です。

def オブジェクト名.メソッド名メソッド定義

end

特異メソッドの定義

$ ruby $_Hello, Rubyspecific.rb:9: undefined method `hello' for"Ruby":String (NoMethodError)

var1 = "Ruby"var2 = "Ruby"

def var1.helloputs "Hello, #{self}"

end

var1.hellovar2.hello #=>エラー

specific.rb

Page 34: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

29Version 0.00

第3章 Rubyにおけるオブジェクト指向⑶

第3章

第3章 テスト

問 題 1変数名が「@」で始まる変数を何と呼びますか?また、「@@」で始まる変数を何と呼びますか?

問 題 2グローバル変数は、変数名にどのような記号を付けて表しますか?

問 題 3定数名の最初の文字は何ですか?

問 題 4メソッドのアクセス権限は3種類あります。その名前を挙げてください。また、class式の中で定義されたメソッドは、デフォルトではどのアクセス権限が適用されますか?

Page 35: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作
Page 36: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第4章Rubyにおける

オブジェクト指向⑷

Page 37: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

32 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第4章

4.1 モジュール

4.1.1 モジュールとはモジュールは、機能を集めたプログラムの単位で、インスタンス化することのできないクラスのようなものです。モジュールのインスタンスは存在しませんし、モジュールを継承して別のモジュールを作ることもできません。

モジュールの代表的な使い方は、名前空間の提供とMix-inです。

◆名前空間の提供

ある程度大きなソフトウェアを開発していると、メソッド名や定数名などがぶつかってしまうことがあります。クラス名やメソッド名を「モジュール名.メソッド名」「モジュール名::定数名」のような書式でアクセスすることができます。

「モジュール名.メソッド名」「モジュール名::定数名」と記述するのは冗長ですが、includeを使うと、モジュール名を指定せず、現在の名前空間内でメソッドや定数を利用できます。

◆Mix-in

Mix-inについては次節で詳しく述べますが、簡単に言うと、多重継承の仕組みを実現するための仕組みです。Rubyでは多重継承をサポートしていませんが、Mix-inを使うと、モジュールに含まれるメソッドや定数をクラス内に取り込むことができます。各クラスに共通する部分をモジュールに記述しておき、includeを使ってモジュールを取り込むことにより、多重継承の欠点を回避しつつ、重複する処理を1カ所にまとめることができます。

puts Math::PI

Mathモジュールの定数PIを利用1

include Mathputs PI

Mathモジュールの定数PIを利用2

Page 38: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

33Version 0.00

第4章 Rubyにおけるオブジェクト指向⑷

第4章

4.1.2 モジュールの利用モジュール内のメソッドは、次の書式で呼び出します。このような形式のメソッドをモジュール関数といいます。

includeすると、モジュール名を指定しなくても利用できます。

次の例では、Mathモジュール内のsqrtメソッドを呼び出しています。

モジュール内に定義されている定数については、次の書式で利用できます。

モジュール名.メソッド名

モジュールのメソッド呼び出し

include モジュール名メソッド名

モジュールのinclude

puts Math.sqrt(9)

include Mathputs sqrt(16)

sqrttest.rb

モジュール名::定数名

モジュール定数の利用

Page 39: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

34 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第4章

4.1.3 モジュールの定義モジュールは以下の書式で定義できます。

モジュール内のメソッドは、includeすることで利用できるようになります。しかし、そのままでは「モジュール名.メソッド名」の形で呼び出すことができません。module_functionを使って宣言することで、モジュール内のメソッドを外部に公開することができます。

module モジュール名メソッドや定数の定義

end

モジュールの定義

module_function :メソッド名

モジュール関数の定義

module HelloModuledef helloputs "Hello, module."

enddef byeputs "Good-bye."

endmodule_function :hello

end

HelloModule.helloHelloModule.bye #=> エラー

moduletest1.rb

Page 40: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

35Version 0.00

第4章 Rubyにおけるオブジェクト指向⑷

第4章

4.2 Mix-in

4.2.1 Mix-inとはRubyでは、複数のスーパークラスから継承する、いわゆる多重継承をサポートしていません。多重継承は弊害が多いため、Rubyでは単純継承のみがサポートされています。もし、スーパークラスとは別のクラスの機能が使いたくなった場合は、モジュールをインクルードして使います。これがMix-inです。

Mix-inは制限された多重継承と考えればよいでしょう。ある機能を複数のクラスで共有したい場合は、共通する機能をモジュールとして作成し、それをインクルードすればよいのです。Mix-inを採用することで、多重継承の弊害を避けつつ、多重継承のメリットを享受することができるのです。

[図4-1]Mix-inスーパークラス モジュール スーパークラス

サブクラス サブクラス

継承 include 継承

Page 41: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

36 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第4章

module HelloModuledef helloputs "Hello, module."

endmodule_function :hello

end

class SuperClassdef byeputs "Good-bye."

endend

class SubClass < SuperClassdef chaoputs "Chao!"

endend

include HelloModules = SubClass.news.chaohellos.bye

moduletest2.rb

$ ruby moduletest2.rbChao!Hello, module.Good-bye.

Page 42: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

37Version 0.00

第4章 Rubyにおけるオブジェクト指向⑷

第4章

4.2.2 kernelモジュール組み込み関数や組み込み定数はKernelモジュールに含まれています。ObjectクラスはKernelモジュールをインクルードしていますので、結果としてすべてのクラスで組み込み関数や組み込み定数が使えるのです。

[表4-1]主な組み込み関数関数名 説明

exit プログラムを終了するgets 標準入力から1行読み込むloop ブロックを永久にループさせるopen ファイルを開くp 引数のオブジェクトを表示するprint 引数を出力するprintf 書式化して引数を表示するputs 引数のオブジェクトを表示するraise 例外を発生させるrand 乱数を発生させるrequire ライブラリを読み込むsleep 指定された秒数だけプログラムの実行を停止するsystem OSのコマンドを実行する

Page 43: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

38 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第4章

4.2.3 名前空間Rubyでは、名前空間の提供もモジュールの役割です。大規模なソフトウェアでは、あるクラスを作ろうとしたら、すでに同じ名前のクラスが使われていた、ということがあります。モジュールを利用することで、同名のクラスでも別々に扱うことができます。

この例の場合、同じHelloという名前のクラスがありますが、前者は「::Hello」、後者は「Modules::Hello」のように区別します。

class Helloend

module Modulesclass Helloend

end

名前空間

Page 44: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

39Version 0.00

第4章 Rubyにおけるオブジェクト指向⑷

第4章

第4章 テスト

問 題 1Mathモジュールのsqrt関数を呼び出すには、どのように記述すればよいですか?

問 題 2多重継承の代用として、モジュールをインクルードすることを何と呼びますか?

問 題 3組み込み関数や組み込み定数が含まれているモジュールで、Objectクラスがインクルードしているモジュールは何ですか?

Page 45: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作
Page 46: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第5章正規表現

Page 47: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

42 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第5章

※複数行モードでない場合、改行文字は除きます。

5.1 正規表現の基礎

5.1.1 正規表現とは文字列パターンを表現する記法の代表例が正規表現(Regular Expression)です。主なパターンの書き方を紹介します。

◆文字

正規表現では、メタキャラクタ(特殊文字)を使ってさまざまなパターンを表すことができます。それ以外の通常の文字は、文字そのものを表します。たとえば、「Ruby」は文字列「Ruby」をそのまま表しています。

◆任意の1文字

任意の1文字は「.」で表します。たとえば「a.c」は、「abc」や「a1c」などを表します。

文字列処理に正規表現は欠かすことができません。Rubyは正規表現クラスを使って手軽に正規表現を活用できます。

[表5-1]メタキャラクタ表記 説明

. 改行以外の任意の1文字^ 行頭$ 行末[ ] 括弧内の文字のいずれか1文字| 左右のパターンいずれか* 直前のパターンの0回以上の繰り返し? 直前のパターンの0回もしくは1回の繰り返し+ 直前のパターンの1回以上の繰り返し{m} 直前のパターンのm回の繰り返し{m,} 直前のパターンのm回以上の繰り返し{m,n} 直前のパターンのm回以上n回以下の繰り返し\w 英数字とアンダースコア\W \w以外の任意の1文字\s スペースやTabなどの空白文字\S \s以外の任意の1文字\d 数字\D \d以外の任意の1文字\A 文字列の先頭(改行直後にはマッチしない)\Z 文字列末尾の行末(改行ならその直前にもマッチ)\z \Zと同じだが改行文字には関知しない\b 語の境界(\wの部分とそうでない部分の間)\B \b以外の位置\1、\2... 後方参照

Page 48: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

43Version 0.00

第5章 正規表現

第5章

◆文字の集合

「[」と「]」の間に文字を並べると、それらの文字のいずれか1文字を表します。たとえば「[abc]」は「a」「b」「c」いずれかを表します。「c[au]t」は「cat」または「cut」を表します。「caut」にはマッチしません。

「-」を使って範囲指定もできます。「[2-4].txt」は、「2.txt」「3.txt」「4.txt」のいずれかを表します。「[0-9]」は数字を、「[a-z]」はアルファベットの小文字を、「[A-Z]」はアルファベットの大文字を表します。「[a-zA-Z]」は大文字小文字にかかわらずアルファベット1文字を意味します。

「^」が先頭にあれば「~以外」を意味します。たとえば「[^0-9].*」は、数字以外の文字で始まる文字列を表します。

◆行頭と行末

「^」は行頭を、「$」は行末を表します。行頭の文字や行末の文字ではありません。「^$」は空行を表します。

◆繰り返し

直前の文字の0回以上の繰り返しは「*」で表します。たとえば「ab*c」は、「ac」「abc」「abbc」などを表します。繰り返しが0回である「ac」もマッチする点に注意してください。

「?」は直前の文字の0回または1回の繰り返しを、「+」は直前の文字の1回以上の繰り返しを表します。

◆エスケープ

正規表現のメタキャラクタを、メタキャラクタではなく文字そのものとして表したい場合は、その文字の直前に「¥」を付けます。たとえば「¥*」は「*」という文字そのものを表します。

⑴ 次のような規則の会員番号にマッチする正規表現を書きなさい。 1. 1文字目はアルファベットの大文字 2. 続いて6桁または8桁の数字が続く⑵ IPアドレスにマッチする正規表現を書きなさい。

Page 49: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

44 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第5章

5.2 正規表現の利用

5.2.1 正規表現オブジェクトの作成正規表現パターンを表したオブジェクトを正規表現オブジェクトといいます。正規表現オブジェクトを作る方法はいくつかあります。もっとも簡単なものは、正規表現を「//」で囲む方法です。

文字列をもとに、Regexpクラスのnewメソッドを使って作成する方法もあります。

%を使った方法もあります。正規表現内で「/」を使いたい場合は、このやり方が便利です。配列や文字列オブジェクトの作成と同様、%rに続いて指定した文字を区切り文字として扱えます。

ここからはRubyにおける正規表現の利用について見ていきましょう。

/文字列パターン/

正規表現オブジェクトの作成1

変数 = Regexp.new("文字列")

正規表現オブジェクトの作成2

%r(文字列パターン)%r|文字列パターン|

正規表現オブジェクトの作成3

Page 50: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

45Version 0.00

第5章 正規表現

第5章

5.2.2 パターンマッチある文字列が、特定の文字列パターンに一致することをパターンマッチといいます。正規表現と文字列がマッチするかどうかは、=~メソッドを使って調べることができます。

文字列内でパターンがマッチすれば、マッチした部分の文字の位置を返します。たとえば、文字列の先頭でマッチすれば0、2文字目でマッチすれば2を返します。マッチしなかった場合はnilを返します。

次の書式を使えば、パターンマッチしたかどうかによって処理を分岐できます。

Stringクラスのmatchメソッドで調べることもできます。

irb(main):001:0> /cde/ =~ 'abcdefg'=> 2

/正規表現/ =~ 文字列

パターンマッチ

if /正規表現/ =~ 文字列マッチした場合の処理

elseマッチしなかった場合の処理

end

パターンマッチ

if /Ruby/ =~ 'Ruby is a dynamic, open sourceprogramming language'puts 'マッチしました'

elseputs 'マッチしませんでした'

end

regexp2.rb

str = 'Ruby is a dynamic, open source programming language'if str.match(/Ruby/)puts 'マッチしました'

elseputs 'マッチしませんでした'

end

regexp2.rb

Page 51: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

46 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第5章

5.2.3 正規表現のオプション正規表現は大文字と小文字が区別されます。

iオプションを付けると、大文字と小文字が区別されません。

よく使われるオプションには、次表のようなものがあります。

irb(main):001:0> /ruby/ =~ 'Programming Language Ruby'=> nilirb(main):002:0> /Ruby/ =~ 'Programming Language Ruby'=> 21

irb(main):004:0> /ruby/i =~ 'Programming Language Ruby'=> 21

[表5-2]正規表現のオプションオプション 説明i 大文字と小文字を区別しないm 複数行モード(「.」は改行文字にもマッチ)x 「#」以降をコメントと見なすn エンコーディングを無視して文字列をバイト列とみなすu 文字列をUTF-8であるとみなすe 文字列をEUC-JPであるとみなすs 文字列をShift-JISであるとみなす

Page 52: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

47Version 0.00

第5章 正規表現

第5章

5.2.4 後方参照正規表現でマッチした部分を取り出すことを後方参照といいます。具体的には、()で囲まれた部分にマッチした文字列が、$1、$2といった変数に格納されます。

プログラムに()は3カ所あります。それぞれマッチした部分が、変数$1、$2に格納されています。

変数「$`」には、マッチした部分より前の文字列、「$&」には、マッチした部分そのものの文字列、「$'」には、マッチした部分よりも後ろの文字列が格納されます。

/(^.).*(R...)/ =~ 'Programming Language Ruby'puts "$1 : #{$1}"puts "$2 : #{$2}"

regexp3.rb

$ ruby regexp3.rb$1 : P$2 : Ruby

/(c.e)/ =~ 'abcdefg'puts %Q|$` : #{$`}|puts %Q|$& : #{$&}|puts %Q|$' : #{$'}|

regext4.rb

$ ruby regexp4.rb$` : ab$& : cde$' : fg

Page 53: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

48 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第5章

5.2.5 文字列パターンの置換Stringクラスのsubメソッドやgsubメソッドを使うと、文字列パターンを置換できます。subメソッドは1カ所だけ置換するのに対し、gsubメソッドはマッチしたすべての箇所を置換します。次の例では、「Python」という文字列を「Ruby」に置換しています。

なお、subメソッド、gsubメソッドはいずれも非破壊的メソッドです。sub!メソッドおよびgsub!メソッドは対象となるオブジェクトを置換します。

str = 'Perl PHP Python Perl PHP Python'puts str.sub(/Python/, 'Ruby')puts str.gsub(/Python/, 'Ruby')puts str

regexp6.rb

$ ruby regexp6.rbPerl PHP Ruby Perl PHP PythonPerl PHP Ruby Perl PHP Ruby

str = 'Perl PHP Python Perl PHP Python'puts strputs str.gsub!(/PHP/, 'Ruby')puts str

regexp7.rb

$ ruby regexp7.rbPerl PHP Python Perl PHP PythonPerl Ruby Python Perl Ruby PythonPerl Ruby Python Perl Ruby Python

Page 54: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

49Version 0.00

第5章 正規表現

第5章

第5章 テスト

問 題 1正規表現オブジェクトの作成方法として適切なものを選択してください。 A. /文字列パターン/ B. ~/文字列パターン/ C. %r|文字列パターン| D. Regexp.new("文字列パターン") E. %w(文字列パターン)

問 題 2以下の要件を表す正規表現を記述してください。 ・行頭は「#」で始まる ・「#」に続いてアルファベットの大文字が1文字 ・続いて任意の英数字が0文字以上 ・行末の文字は「.」

問 題 3正規表現「:[0-3][0-9][0-9][a-zA-Z]+=[a-z]*¥.」が表す文字列の例を挙げてください。

Page 55: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作
Page 56: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第6章イテレータ

Page 57: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

52 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第6章

6.1 イテレータの利用

6.1.1 イテレータとは繰り返し機能を提供するメソッドをイテレータといいます。イテレータは、引数に「do~end」のようなブロックを取るブロック呼び出しの一種で、ブロック内の処理を繰り返し実行します。

引数やブロック変数は必須ではありません。ブロック変数は、ブロック内の処理を繰り返すたびにさまざまな値が代入される変数です。たとえば、オブジェクトが配列の場合、処理を繰り返すたびに配列の要素が一つずつブロック変数に格納されていきます。

オブジェクト.メソッド(引数) { |ブロック変数|繰り返す処理

}

イテレータの一般的な書式1

オブジェクト.メソッド(引数) do |ブロック変数|繰り返す処理

end

イテレータの一般的な書式1

Page 58: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

53Version 0.00

第6章 イテレータ

第6章

6.1.2 eachメソッド

※配列の場合とは異なり、順序は不定です。

eachメソッドは代表的なイテレータです。オブジェクトから要素を取り出し、それを使って処理を繰り返します。eachメソッドはさまざまなクラスで利用できます。

◆配列

配列内の要素を順に取り出します。

◆ハッシュ

配列の場合と同様、要素をすべて取り出します。

$ ruby aryeach.rbI love Ruby!I love Perl!I love Python!I love PHP!

ary = ["Ruby", "Perl", "Python", "PHP"]ary.each {|lang|puts "I love #{lang}!"

}

aryeach.rb

h a s h = { " M i c r o s o f t " = > " W i n d o w s " ,"Apple"=>"MacOS", "Sun"=>"Solaris"}hash.each {|vendor, os|printf("%10s : %s¥n", vendor, os)

}

hasheach1.rb

$ ruby hasheach1.rbSun : Solaris

Microsoft : WindowsApple : MacOS

Page 59: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

54 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第6章

ハッシュの場合はキーと値があるので、ブロック変数は2つ必要です。もしブロック変数を一つだけ指定すると、ブロック変数には配列が代入されます。

演習問題

aryeach.rbについて、langが"r"の文字を含んでいた場合だけ表示するように修正しなさい。

h a s h = { " M i c r o s o f t " = > " W i n d o w s " ,"Apple"=>"MacOS", "Sun"=>"Solaris"}hash.each {|os|printf("%10s : %s¥n", os[0], os[1])

}

hasheach2.rb

Page 60: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

55Version 0.00

第6章 イテレータ

第6章

6.1.3 繰り返し処理Integerクラスに用意されているイテレータを使って、繰り返し処理をすることができます。

◆timesメソッド

すでに紹介したtimesメソッドもIntegerクラスのメソッドです。

ブロック引数を利用することもできます。

$ ruby times1.rbRubyRubyRubyRubyRuby

5.times {puts "Ruby"

}

times1.rb

5.times {|i|puts i

}

times2.rb

$ ruby times2.rb01234

Page 61: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

56 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第6章

◆uptoメソッド

uptoメソッドを使うと、任意の数まで1ずつ加算してブロック変数に入れながら繰り返します。

◆downtoメソッド

uptoメソッドとは逆に、1ずつ減算しながら繰り返すのがdowntoメソッドです。

10.downto(5){|i|puts i

}

downto.rb

5.upto(10){|i|puts i

}

upto.rb

$ ruby upto.rb5678910

$ ruby downto.rb1098765

Page 62: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

57Version 0.00

第6章 イテレータ

第6章※loopメソッドはIntegerクラス

のメソッドではなく組み込み関数です。

◆stepメソッド

開始から終了までの間、ステップを加算もしくは減算しながら繰り返します。

◆loopメソッド

ブロック内を永久に繰り返すのがloopメソッドです。ループから脱出するにはbreakなどを使います。

開始.step(終了, ステップ){|i| ... }

stepメソッド

$ ruby step.rb3579

3.step(10,2) {|i|puts i

}

step.rb

$ ruby looptest.rb012345678910

i = 0loop {puts ii += 1break if i > 10

}

looptest.rb

Page 63: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

58 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第6章

6.2 イテレータの作成

6.2.1 yieldキーワードイテレータの特徴は、メソッド呼び出しの際に付属のブロックが繰り返し呼び出されるということです。メソッド定義の中でブロックを呼び出すには、yieldを使います。

$ ruby yieldtest1.rbStart of call_block method.Hello, Code-blockHello, Code-blockHello, Code-blockEnd of method.Start of call_block method.call yieldcall yieldcall yieldEnd of method.

def call_blockputs "Start of call_block method."yieldyieldyieldputs "End of method."

end

call_block { puts "Hello, Code-block" }call_block { puts "call yield" }

yieldtest1.rb

Page 64: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

59Version 0.00

第6章 イテレータ

第6章

yieldに引数があれば、ブロック変数に代入されます。次の例では、Stringクラスに、文字列を縦に表示するverticalというメソッドを追加しています。yieldの使い方を観察してください。

class Stringdef verticalfor i in 0...self.lengthyield self[i]

endend

end

"Ruby".vertical {|c|printf("%c¥n", c)

}

vertical.rb

$ ruby vertical.rbRuby

Page 65: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

60 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第6章

第6章 テスト

問 題 1以下のコードを実行したとき、出力されるメッセージを記述してください。

問 題 2以下のコードを実行したとき、出力されるメッセージを記述してください。

問 題 3以下のコードを実行したとき、出力されるメッセージを記述してください。

hash = {"A"=>"a", "B"=>"b", "C"=>"c"}hash.each {|alpha, beta|printf("%s,%s¥n", beta, alpha)

}

3.step(10,3) {|i|puts i

}

def call_blockputs "Start"yieldyieldyieldputs "End"

endcall_block { puts "Ruby" }

Page 66: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第7章ファイル入出力

Page 67: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

62 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第7章

7.1 入出力の基本

7.1.1 標準入出力UNIX系OSでは、プログラムには3つの入出力インターフェースである標準入力、標準出力、標準エラー出力が用意されます。Rubyでは、これらはIOオブジェクトとしてプログラムに割り当てられます。

●標準入力(Standart Input)キーボードからの入力を受け取ります。このIOオブジェクトは、組み込み定数STDIN、およびグローバル変数$stdinで参照できます。

●標準出力(Standard Output)プログラムの実行結果の出力先で、通常は端末画面上です。このIOオブジェクトは、組み込み定数STDOUT、およびグローバル変数$stdoutで参照できます。

●標準エラー出力(Standard Error)エラーや警告メッセージの出力先で、通常は端末画面上です。このIOオブジェクトは、組み込み定数STDERR、およびグローバル変数$stderrで参照できます。

次に、標準出力と標準エラー出力にメッセージを出力する例を紹介します。

まず、ファイルをはじめとする入出力の基本について説明します。

$stdout.puts "標準出力へのメッセージ。"$stderr.puts "標準エラー出力へのメッセージ。"

stdout.rb

$ ruby stdout.rb標準出力へのメッセージ。標準エラー出力へのメッセージ。

Page 68: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

63Version 0.00

第7章 ファイル入出力

第7章

7.1.2 コマンドライン引数

※ソースプログラム自体はARGVには含まれません。

コマンドラインで指定された引数は、組み込み定数ARGVに格納されます。

最初の引数はARGV[0]、次の引数はARGV[1]...に格納されます。引数は、スペースで区切って指定します。

puts "引数1 : #{ARGV[0]}"puts "引数2 : #{ARGV[1]}"puts "引数3 : #{ARGV[2]}"p ARGV

argtest1.rb

$ ruby argtest1.rb Ruby Python PHP引数1 : Ruby引数2 : Python引数3 : PHP["Ruby", "Python", "Perl"]

Page 69: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

64 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第7章

7.2 基本的な入出力操作

7.2.1 ファイルのopenとcloseファイル入出力は、IOクラスのサブクラスであるFileクラスを利用します。ファイルを開くには、openメソッドを使います。

モードには、表7-1のようなものがあります。省略すると、読み取り専用モード(r)になります。

開いたファイルは、処理が終わったら閉じる必要があります。同時に開くことのできるファイル数には上限がありますし、多数のファイルを開いているとシステムリソースも消費しますので、処理が終わったファイルは閉じるようにします。ファイルを閉じるにはcloseメソッドを使います。

ただし、次のようにブロックを使うと、ブロックが終了した時点でファイルは自動的に閉じられるので、closeメソッドを実行する必要はありません。

ここでは、ファイルの入出力をはじめとする基本的な入出力操作を取り上げます。

変数 = open(ファイル名[, モード])

ファイルを開く

[表7-1]モードモード 説明"r" 読み取りモード"w" 書き込みモード(既存のファイルは上書き)"a" 追記モード"r+" 読み書きモード(ファイルの先頭から)"w+" 読み書きモード(既存のファイルは上書き)"a+" 読み書きモード(ファイルの末尾から)

変数.close(ファイル名)

ファイルを閉じる

open(ファイル名) { |変数|while line = 変数.gets処理

end}

ブロックを使ったファイルオープン

Page 70: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

65Version 0.00

第7章 ファイル入出力

第7章

7.2.2 入力操作ファイルなどのIOオブジェクトから入力操作をするには、getsメソッドやreadlinesメソッド、readメソッドなどがあります。

次の例は、ファイルhello.rbを開いて内容を読み込み、標準出力に出力します。getsメソッドは、ファイルの内容を1行ずつ読み込みます。改行文字を削除するため、chomp!メソッドを使っています。

getsメソッドは、ファイルの末尾まで達してからさらに読み込むと、nilを返します。ファイル末尾に達したかどうかは、eof?メソッドを使って調べることができます。

open("hello.rb") { |f|while line = f.getsline.chomp!puts line

end}

iotest1.rb

open("fortest1.rb") { |f|while line = f.getsline.chomp!puts linep f.eof?

end}

iotest2.rb

$ ruby iotest2.rbfor lang in ["Ruby", "PHP", "Perl", "Python", "Java"] dofalseputs "Programming Language #{lang}"

falseendtrue

Page 71: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

66 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第7章

readlinesメソッドを使うと、ファイル内容を一気に読み込み、結果を配列に格納します。

f = open("whiletest.rb")puts "配列の内容:"ary = f.readlinesp ary

puts "¥nファイルの内容:"ary.each { |line|puts line

}f.close

iotest3.rb

$ ruby iotest3.rb配列の内容:["i = 0¥n", "while i < 10¥n", " puts i¥n", "i += 1¥n", "end¥n"]

ファイルの内容:i = 0while i < 10puts ii += 1

end

Page 72: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

67Version 0.00

第7章 ファイル入出力

第7章

getcメソッドを使うと、データを1バイト読み込みます。

なお、linenoメソッドを使うと、getsメソッドを使って何行読み込んだかのカウントが取得できます。次の例では、引数に指定したファイルに行番号を付けて出力します。

f = open("hello.rb")while c = f.getcp c

end

iotest4.rb

$ ruby iotest4.rb"p""u""t""s"" ""¥"""h""e""l""l""o"","" ""w""o""r""l""d"".""¥"""¥n"

open(ARGV[0]) { |f|while line = f.getsprintf("%4d : %s", f.lineno, line)

end}

linenotest.rb

$ ruby linenotest.rb fortest1.rb1 : for lang in ["Ruby", "PHP", "Perl",

"Python", "Java"] do2 : puts "Programming Language #{lang}"3 : end

Page 73: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

68 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第7章

7.2.3 ファイルポインタファイルからの入力には、readメソッドも使えます。readメソッドは、指定したサイズだけ読み込みます。サイズを指定しなければ全体を読み込みます。

実行結果から分かるように、readメソッドは「どこまで読み出したか」という情報を保持しています。これをファイルポインタ(ファイルオフセット)といいます。ファイルポインタの位置はposメソッドで取得したり変更したりすることができます。

f = open("hello.rb")p f.read(1)p f.read(4)p f.readf.close

iotest5.rb

$ cat hello.rbputs "hello, world."$ ruby iotest5.rb"p""uts ""¥"hello, world.¥"¥n"

f = open("hello.rb")p f.read(4)p f.posf.pos = 6p f.readf.close

iotest6.rb

$ cat hello.rbputs "hello, world."$ ruby iotest6.rb"puts"4"hello, world.¥"¥n"

Page 74: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

69Version 0.00

第7章 ファイル入出力

第7章

※その際、linenoメソッドが返す行番号もリセットされます。

rewindメソッドを使うと、ファイルポインタを先頭に戻すことができます。

f = open("hello.rb")p f.read(4)p f.posf.rewindp f.readf.close

iotest7.rb

$ ruby iotest7.rb"puts"4"puts ¥"hello, world.¥"¥n"

Page 75: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

70 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第7章

7.2.4 出力操作ファイルなどへの出力は、putsメソッド、printメソッド、putcメソッド、readメソッドなどが使えます。

putsメソッドは、文字列に改行を加えて出力します。文字列以外を指定するときは、to_sメソッドを使って文字列に変換してください。次の例では、端末上から入力した行をファイルnewfile.txtに出力します。

putcメソッドは、引数に指定した文字コードに対応する1文字を出力します。printメソッドはputsメソッドと同様ですが、改行を出力しない点と、引数が文字列でなければ文字列に変換する点が異なります。

writeメソッドを使うと、書き込んだバイト数を戻り値として返します。また、引数が文字列でなければ自動的に文字列に変換します。

f = open("newfile.txt", "a+")puts "何か入力してください(終了は[Ctrl]+[D])"line = read.chomp!f.puts linef.close

iotest8.rb

$ ruby iotest8.rb何か入力してください(終了は[Ctrl]+[D])Hello, Ruby.Hello, World. ← [Ctrl]+[D]$ cat newfile.txtHello, Ruby.Hello, World.

f = open("write.txt", "a")size = f.write("Hello, Ruby.")puts "#{size}バイト書き込みました。"f.close

iotest9.rb

$ ruby iotest9.rb12バイト書き込みました。

Page 76: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

71Version 0.00

第7章 ファイル入出力

第7章

7.2.5 バイナリモード改行文字は、OSごとに異なります。Rubyでは改行を「¥n」で表しますが、実際にはOSごとの改行文字に変換されてから出力されます。たとえば、Windowsの改行文字は「¥r¥n」ですので、Windowsのファイルでは改行が「¥r¥n」で記録されています。そのようなファイルからgetsを使って1行読み込むと、「¥r¥n」は自動的に「¥n」に変換されます。

たとえばgetsメソッドでは自動的に改行文字が変換されますが、改行文字を変更しないで、テキストファイルにある改行文字をそのまま使うには、ファイルをバイナリモードで扱います。バイナリモードにするには、binmodeメソッドを使います。

ファイルは通常、テキストモードとして扱われます。いったんバイナリモードにしてしまうと、テキストモードに戻すことはできません。

f = open(ファイル名)f.binmode

バイナリモードへの変更

Page 77: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

72 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第7章

第7章 テスト

問 題 1標準出力、標準エラー出力、標準入力を表すグローバル変数をそれぞれ記述してください。

問 題 2コマンドライン引数が格納される組み込み定数を記述してください。

問 題 3次のコードは、ファイルを開いて内容を出力します。下線部に当てはまるメソッド名を記述してください。

open("samplefile") do |f|while line = f.getsputs line.chomp!

end

Page 78: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第8章ファイル/ディレクトリ操作

Page 79: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

74 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第8章

8.1 ディレクトリ操作

8.1.1 ディレクトリの場所カレントディレクトリを知るには、Dir.pwdメソッドを使います。また、Dir.chdirメソッドを使ってディレクトリを移動できます。ディレクトリの指定には、絶対パスも相対パスも利用できます。

ディレクトリの操作にはDirクラスを利用します。

puts "Current Directory :"p Dir.pwd

puts "Change Directory to /tmp."Dir.chdir("/tmp")p Dir.pwd

dirtest1.rb

$ ruby dirtest1.rbCurrent Directory :"/home/student/Ruby"Change Directory to /tmp."/tmp"

Page 80: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

75Version 0.00

第8章 ファイル/ディレクトリ操作

第8章

8.1.2 ディレクトリの読み込みディレクトリに含まれるファイル一覧の情報を読み込むには、まずディレクトリをopenしてから内容を読み込み、その後closeします。ファイルの場合と同様の手順です。次のプログラムは、カレントディレクトリ内のファイル一覧を出力します。

実行すると、ファイル名が出力されます。カレントディレクトリを表す「.」、親ディレクトリを表す「..」も表示されます。それらが表示されないようにするには、次のようにするとよいでしょう。

ファイルの場合と同様、ブロックを使うと、ブロックが終了した時点でファイルは自動的に閉じられるので、closeメソッドを実行する必要はありません。

$ ruby dirtest2.rb"methodtest3.rb""untiltest.rb""var2.rb""exception1.rb""break.rb""fortest2.rb"(以下省略)

dir = Dir.open(".")while filename = dir.readp filename

enddir.close

dirtest2.rb

dir = Dir.open(".")while filename = dir.readnext if filename == "." or filename == ".."p filename

enddir.close

dirtest3.rb

dir = Dir.open(".")dir.each { |filename|p filename

}

dirtest4.rb

Page 81: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

76 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第8章

8.1.3 ファイル名のパターンマッチワイルドカードを使ってマッチしたファイル名だけを取り出したい場合は、Dir.globメソッドを使います。取得されたファイル名は配列として返されます。次の例では、カレントディレクトリ内で、ファイル名がaもしくはbもしくはcで始まり、末尾が「.rb」であるファイル一覧を取得しています。

複数のパターンを指定したいときは「\0」で区切ります。たとえば、ファイル名の末尾が「.htm」もしくは「.html」を表したいときは、次のようにします。

「**」を使うと、ディレクトリを再帰的に検索できます。次の例では、pubディレクトリ以下を再帰的に検索して「~.txt」ファイルを取得します。

dir = Dir.glob("[abc]*.rb")p dirdir.each { |filename|p filename

}

dirglob.rb

$ ruby dirglob.rb["break.rb", "buffertest.rb", "classtest.rb","array1.rb", "casetest.rb", "argtest1.rb"]"break.rb""buffertest.rb""classtest.rb""array1.rb""casetest.rb""argtest1.rb"

Dir.glob("*.htm\0*.html")

複数パターンの指定

Dir.glob("pub/**/*.txt")

ディレクトリの再帰検索

Page 82: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

77Version 0.00

第8章 ファイル/ディレクトリ操作

第8章

8.1.4 ディレクトリの作成と削除ディレクトリを作成するには、Dir.mkdirメソッドを使います。次の例では、入力された名前のディレクトリを作成します。

ディレクトリを削除するには、Dir.rmdirメソッドを利用します。削除するディレクトリは、中身が空である必要があります。

空でないディレクトリを指定すると、次のようになります。

puts "Directory Name?"newdir = readline.chomp!Dir.mkdir(newdir)

dirtest5.rb

$ ruby dirtest5.rbDirectory Name?sample$ ls -ld sampledrwxrwxr-x 2 student student 4096 May 22 19:57 sample

puts "Directory Name?"dirname = readline.chomp!Dir.rmdir(dirname)

dirtest6.rb

$ ruby dirtest6.rbDirectory Name?sampledirtest6.rb:4:in `rmdir': Directory not empty- sample (Errno::ENOTEMPTY)

from dirtest6.rb:3:in `<main>'

Page 83: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

78 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第8章

8.2 ファイル操作

8.2.1 ファイル名の操作ファイル名を変更するには、File.renameメソッドを使います。ファイルだけではなく、ディレクトリ名も同じように変更できます。

次の例では、oldname.txtファイルをnewname.txtに変更します。

新しいファイル名をパスで指定すると、指定されたディレクトリに移動させることになります。次の例では、ファイル名は変更せず、tmpディレクトリ内にファイルを移動しています。

ファイルの移動や削除は、Fileクラスを使って操作します。

File.rename("現在のファイル名", "新しいファイル名")

ファイル名の変更

irb(main):001:0> File.rename("oldname.txt", "newname.txt")=> 0

irb(main):001:0> File.rename("newname.txt", "tmp/newname.txt")=> 0

Page 84: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

79Version 0.00

第8章 ファイル/ディレクトリ操作

第8章

8.2.2 ファイルの削除ファイルを削除するには、File.deleteメソッドを使います。

ファイルを削除する権限がなかった場合は、次のようにエラーが発生します。

File.delete("ファイル名")

ファイルの削除

irb(main):001:0> File.delete("write.txt")Errno::EACCES: Permission denied - write.txt

from (irb):1:in `delete'from (irb):1from /usr/local/bin/irb:12:in `<main>'

Page 85: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

80 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第8章

※厳密には、もっとも右側の「/」までの部分を返します。

8.2.3 ファイル名の操作basenameメソッドを使うと、指定されたパスからファイル名だけを取り出します。また、拡張子を指定すると、拡張子の部分が取り除かれます。

dirnameメソッドはその反対に、ディレクトリ名を取り出します。パス名に「/」がない場合は、カレントディレクトリを表す「.」を返します。

ファイル名から拡張子だけを取り出すには、extnameメソッドを使います。拡張子が見あたらない場合は空文字列を返します。

splitメソッドを使うと、パス名をディレクトリ名とファイル名に分割し、それぞれを要素とする配列を返します。

splitメソッドとは逆に、ディレクトリ名とファイル名をつなぐにはjoinメソッドを使います。

basename(パス名[, 拡張子])

basenameメソッド

irb(main):001:0> File.basename("/usr/local/bin/ruby")=> "ruby"irb(main):002:0> File.basename("/home/student/Ruby/var1.rb",".rb")=> "var1"

irb(main):001:0> File.dirname("/usr/local/bin/ruby")=> "/usr/local/bin"irb(main):002:0> File.dirname("var1.rb")=> "."

irb(main):001:0> File.extname("write.txt")=> ".txt"irb(main):002:0> File.extname("/home/student/Ruby/hello.rb")=> ".rb"irb(main):002:0> File.extname("/home/student/Ruby/write.txt")=> ""

irb(main):002:0> File.split("/usr/local/bin/ruby")=> ["/usr/local/bin", "ruby"]あ

irb(main):003:0> File.join("/usr/local/bin", "ruby")=> "/usr/local/bin/ruby"

※厳密には、もっとも右側の「/」以降の部分を返します。

Page 86: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

81Version 0.00

第8章 ファイル/ディレクトリ操作

第8章

8.2.4 ファイルの属性ファイルやディレクトリには、所有者、パーミッション、最終更新日時などの属性情報があります。File.statメソッドを使うと、属性情報を取得できます。次の例では、指定したファイルのサイズを所有者ユーザーIDを表示します。

File.statメソッドは、File::Statクラスのインスタンスを返します。利用可能なメソッドは表8-1のとおりです。

ファイルのパーミッションは、File.chmodメソッドで変更できます。たとえば、samplefileのパーミッションを0644(所有者のみ読み取り書き込み可能、それ以外は読み取りのみ)に変更するには、次のようにします。

puts "ファイル名を入力してください:"filename = readline.chomp!

f = File.stat(filename)puts "Size : #{f.size}"puts "UserID : #{f.uid}"

filestat1.rb

$ ruby filestat1.rbPlease Enter Filename:filetest.rbSize : 161UserID : 500

[表8-1]File::Statクラスの主なインスタンスメソッドメソッド 説明

mode ファイル属性uid 所有者のUIDgid 所有グループのGIDsize ファイルサイズatime 最終アクセス日時mtime 最終更新日時ctime 属性の最終更新日時

File.chmod(0644, "samplefile")

chmodメソッドの例

Page 87: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

82 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第8章

第8章 テスト

問 題 1次のコードは、カレントディレクトリ内のファイル一覧を出力します。下線部に当てはまるクラス名.メソッド名を記述してください。

問 題 2次のコードは、カレントディレクトリ内にある、ファイル名の末尾が「.rb」であるファイル一覧を出力します。下線部に当てはまるクラス名.メソッド名を記述してください。

dir = ______(".")dir.each { |filename|p filename

}

dir = ______("*.rb")p dirdir.each { |filename|p filename

}

Page 88: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第9章その他の組み込みライブラリ

Page 89: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

84 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第9章

9.1 Timeクラス

9.1.1 Timeクラスの概要日付や時刻を表すためにTimeクラスが組込みクラスとして用意されています。現在の時刻は、Time.newメソッドで取得できます。

yearやmonthはTimeクラスのメソッドです。主なメソッドは次表のとおりです。

日時を指定してTimeオブジェクトを作成するには、Time.mktimeメソッドを使います。

t = Time.newp tp t.yearp t.monthp t.hour

time1.rb

Mon Jun 15 17:08:07 +0900 20092009617

t = Time.mktime(2009, 7, 10, 11, 22, 33)p t

time2.rb

$ ruby time2.rbFri Jul 10 11:22:33 +0900 2009

[表9-1]Timeクラスのメソッドメソッド 説明

year 西暦month 月day 日hour 時min 分sec 秒yday 今年の何日目か(1月1日が1)mday 今月の何日目か(dayメソッドと同じ)wday 今週の何日目か(日曜日が0)zone タイムゾーン

Page 90: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

85Version 0.00

第9章 その他の組み込みライブラリ

第9章

9.1.2 日時のフォーマット日時のフォーマットを変更したい場合は、strftimeメソッドを使います。利用できるフォーマット文字列は次表のとおりです。

t = Time.newp t.strftime("%Y年%m月%d日 %H時%M分%S秒")p t.strftime("%d, %B (%A)")

time3.rb

$ ruby time3.rb"2009年06月15日 17時15分25秒""15, June (Monday)"

[表9-2]フォーマット文字列書式 説明

%A 曜日(Sundayなど)%a 曜日(Sunなど)%B 月(Januaryなど)%b 月(Janなど)%c 日付と時刻%d 日(01~31)%H 時(00~23)%I 時(00~12)%j 年の何日目か(001~366)%M 分(00~59)%m 月(01~12)%p 午前・午後(AM/PM)%S 秒(00~60)%w 曜日(0~6、0が日曜日)%X 時刻%x 日付%Y 西暦%y 西暦の下2桁%Z タイムゾーン(JSTなど)%z タイムゾーン(+0900など)

Page 91: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

86 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第9章

9.1.3 時刻の操作Timeオブジェクトどうしの差を求めることができます。

また、秒数を足したり引いたりすることもできます。

puts "SLEEPします..."t1 = Time.nowsleep(5)t2 = Time.nowputs "#{t2 - t1}秒経過しました。"

time4.rb

$ ruby time4.rbSLEEPします...5.00371秒経過しました。

t = Time.nowputs "現在の日時: #{t}"puts "今から4時間後:#{t + (60 * 60 * 4)}"

time5.rb

$ ruby time5.rb現在の日時: Mon Jun 15 17:22:25 +0900 2009今から4時間後:Mon Jun 15 21:22:25 +0900 2009

Page 92: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

87Version 0.00

第9章 その他の組み込みライブラリ

第9章

9.2 DateTimeクラスとDateクラス

9.2.1 DateTimeクラスTimeクラスにあっては、表現できる日時の範囲はOS環境の制限を受けます。たとえば、UNIX系OSの多くは1970年~2038年までしか扱うことができないため、Timeクラスで表せる範囲もその間になります。そのような制限を受けないクラスがDatetimeクラスです。Datetimeクラスは組込みクラスではなく、dateライブラリにあります。

DateTimeクラスを利用するには、「require "date"」を使ってdateライブラリを読み込んでおく必要があります。基本的な使い方は、Timeクラスと同様です。

require "date"

t = DateTime.nowp tp t.yearp t.monthp t.hour

p t.strftime("%Y年%m月%d日 %H時%M分%S秒")p t.strftime("%d, %B (%A)")

datetime1.rb

#<DateTime: 212111814827654173/86400000000,3/8,2299161>2009617"2009年06月15日 17時33分47秒""15, June (Monday)"

Page 93: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

88 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第9章

Timeオブジェクトどうしを引くと秒数が出力されますが、DateTimeオブジェクトの場合は日単位になります。

DateTimeオブジェクトに数値を足すと、日数が加算されます。

require "date"

puts "SLEEPします..."t1 = DateTime.nowsleep(5)t2 = DateTime.nowputs "#{t2 - t1}日経過しました。"

datetime2.rb

$ ruby datetime2.rbSLEEPします...185199/3200000000日経過しました。

require "date"

t = DateTime.nowputs "現在の日時: #{t}"puts "今から4日後:#{t + 4}"

datetime3.rb

$ ruby datetime3.rb現在の日時: 2009-06-15T18:42:27+0900今から4日後:2009-06-19T18:42:27+0900

Page 94: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

89Version 0.00

第9章 その他の組み込みライブラリ

第9章

9.2.2 DateクラスDateクラスは時刻情報を持たず日付だけを扱うクラスで、DateTimeクラスのスーパークラスです。Dateクラスを利用する場合も「require "date"」が必要です。

現在の日付を取得するには、Date.todayメソッドを使います。

指定した日付のDateオブジェクトを作成するには、次のようにします。

require "date"

d = Date.todayp dp d.yearp d.monthp d.day

date1.rb

$ ruby date1.rb#<Date: 4909995/2,0,2299161>2009615

require "date"

d = Date.new(2009, 7, 10)puts d

date2.rb

$ ruby date2.rb2009-07-10

RubyライブラリのドキュメントRubyには数多くのライブラリが用意されています。Rubyリファレンスマニュアル(http://www.ruby-lang.org/ja/man/html/index.html)の「添付ライブラリ」からたどって、さまざまなクラスメソッドの使い方などを調べることができます。

また、riコマンドを使って、コマンドライン上で簡単なリファレンスを表示することができます。riコマンドは、ソースからのインストールでは標準で用意されますが、CentOSではruby-riパッケージをインストールします。

Page 95: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

90 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第9章

次の例では、Dateクラスのリファレンスを表示します。

次の例では、DateTime.nowメソッドのリファレンスを表示します。

⑴ 今週一週間の日付と曜日を表示するプログラムを作成しなさい。 たとえば、今日が2009年7月22日(水)とすれば、 07/19(Sun) 07/20(Mon) ... 07/25(Sat) のように、日曜日から土曜日まで表示されればよい。

⑵ 今日から来年の1月1日までの日数を計算するプログラムを作成しなさい。

# yum install ruby-ri

$ ri Date

$ ri DateTime.now

Page 96: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

91Version 0.00

第9章 その他の組み込みライブラリ

第9章

第9章 テスト

問 題 1次のコードは、現在の日時を出力します。下線部に当てはまるクラス名.メソッド名を記述してください。

問 題 2Timeクラスが扱える西暦の範囲はOS環境による制限を受けます。一方、______クラスは制限を受けません。このクラスは______ライブラリに格納されています。下線部に当てはまる名前を記述してください。

t = ______p t.strftime("%Y年%m月%d日 %H時%M分%S秒")

Page 97: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作
Page 98: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第10章RubyGems

Page 99: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

94 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第10章

10.1 RubyGemsとは

10.1.1 RubyGemsのインストールRubyGemsを使うと、インターネット経由を経由して、ライブラリなどのソフトウェアパッケージをインストールしたりアップデートしたりすることができます。Ruby用ライブラリの多くはRubyGemsを採用しており、RubyGemsを使ってインストールできるようになっています。

RubyGemsは、RubyForgeからダウンロードすることができます。Linuxにインストールする場合、次のような手順を実施してください。

RDocがインストールされていない場合は、次のようにしてあらかじめインストールしておいてください(CentOS)。

インストール済みのRubyGemsをアップデートする場合は、次のコマンドを実行します。

RubyGemsのバージョンは、-vオプションで確認できます。

RubyGemsは、Rubyの標準的なパッケージ管理システムです。

# wget http://rubyforge.org/frs/download.php/57643/rubygems-1.3.4.tgz# tar zxf rubygems-1.3.4.tgz# cd rubygems-1.3.4# ruby setup.rb

[図10-1]RubyForge

# yum install ruby-rdoc

# gem update --system

# gem -v1.3.4

Page 100: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

95Version 0.00

第10章 RubyGems

第10章

10.2 RubyGemsの利用

10.2.1 gemコマンドgemコマンドの基本的な書式は次のとおりです。

どのようなコマンドがあるかは、次のようにすれば確認できます。

RubyGemsでは、gemコマンドを使ってパッケージを管理します。

gem <コマンド> [オプション] [パラメータ]

gemコマンドの書式

gem help [サブコマンド]

gemコマンドのヘルプ

# gem help

RubyGems is a sophisticated package manager for Ruby. This is abasic help message containing pointers to more information.

Usage:gem -h/--helpgem -v/--versiongem command [arguments...] [options...]

(...)

Page 101: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

96 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第10章

サブコマンドを指定すると、詳しい使い方が表示されます。

# gem help installUsage: gem install GEMNAME [GEMNAME ...] [options] -- --build-flags [options]

Options:--platform PLATFORM Specify the platform of gem to install

-v, --version VERSION Specify version of gem to install

Install/Update Options:-i, --install-dir DIR Gem repository directory to get installed

gems-n, --bindir DIR Directory where binary files are

located

(...)

Page 102: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

97Version 0.00

第10章 RubyGems

第10章

10.2.2 パッケージのインストール

※通常は、RubyForge(http://gems.rubyforge.org/)です。

パッケージをインストールするには、installサブコマンドを使います。

パッケージは、インターネット上にあるリポジトリからダウンロードされます。--remoteオプションを付けると、インターネット上のリモートリポジトリのみを対象とします。

RubyGemsでは、パッケージ間の依存関係がチェックされます。依存関係を無視して強制的にインストールしたい場合は、--forceオプションを利用します。また、あるパッケージに依存するパッケージがあれば自動的にインストールされますが、依存パッケージをインストールしたくない場合は、--ignore-dependsオプションを指定します。これらのオプションを指定した場合、パッケージが正常に動作しない可能性があります。

--versionオプションを指定すると、指定したバージョンをインストールできます。RubyGemsでは、複数のバージョンを同時に管理することができます。アプリケーションによって別バージョンのライブラリを利用する、といったことが可能です。

gem install [--remote] <パッケージ名>

パッケージのインストール

リポジトリリポジトリには、リモートリポジトリとローカルリポジトリがあります。リモートリポジトリは、ネットワーク上にあるパッケージ群で、デフォルトではRubyForgeが設定されています。リモートリポジトリは、「--source http://<サーバ名>:8808」とすれば変更することもできます。リモートリポジトリからパッケージをインストールすると、そのパッケージはローカルリポジトリにコピーされます。gemコマンドを実行するとき、--remoteオプションを指定するとリモートリポジトリのみが対象となります。また、--localオプションを指定するとローカルリポジトリのみが対象となります。両方を対象とする--bothオプションもあります。

Page 103: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

98 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第10章

10.2.3 パッケージのアップデートインストール済みのパッケージをアップデートするには、updateサブコマンドを使います。

次の例では、rakeパッケージをアップデートしています。

パッケージ名を省略すると、RubyGemsでインストールされているすべてのパッケージをバージョンアップします。どのようなパッケージがアップデートされるのかを事前に確認するには、次のコマンドを実行します。

この例では、rakeの最新バージョン0.8.7が存在することが分かります。

なお、新しいバージョンがインストールされても、古いバージョンは削除されません。旧パッケージを削除するには、cleanupサブコマンドを使います。

パッケージ名を省略すると、最新バージョン以外のすべてのパッケージを削除します。どのようなパッケージが削除されるのかを事前に確認するには、--dryrunオプションを指定して実行します。

gem update [パッケージ名]

パッケージのアップデート

# gem update rakeUpdating installed gemsUpdating rakeSuccessfully installed rake-0.8.7Gems updated: rakeInstalling ri documentation for rake-0.8.7...Installing RDoc documentation for rake-0.8.7...

# gem outdatedrake (0.8.6 < 0.8.7)

gem cleanup [パッケージ名]

旧パッケージの削除

# gem cleanup --dryrunCleaning up installed gems...Dry Run Mode: Would uninstall rake-0.8.6Clean Up Complete

Page 104: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

99Version 0.00

第10章 RubyGems

第10章

10.2.4 パッケージのアンインストール指定したパッケージをアンインストールするには、uninstallサブコマンドを使います。

アンインストール対象のパッケージが複数バージョンある場合、どのバージョンを削除するかを尋ねられます。バージョンを指定する場合は、--versionオプションで指定します。すべてのバージョンをアンインストールするには、--allオプションを指定します。次の例では、rakeのバージョン0.8.7をアンインストールしています。

gem uninstall <パッケージ名>

パッケージのアンインストール

# gem uninstall --version 0.8.7 rakeSuccessfully uninstalled rake-0.8.7

Page 105: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

100 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第10章

10.2.5 パッケージ情報の検索インストールされているパッケージを表示するには、searchサブコマンドを使います。

キーワードを省略すると、インストール済みのすべてのパッケージが表示されます。

キーワードを指定すると、パッケージを絞り込んで検索します。

gem search [キーワード]

パッケージ情報の検索

# gem search

*** LOCAL GEMS ***

actionmailer (2.3.2)actionpack (2.3.2)activerecord (2.3.2)activeresource (2.3.2)activesupport (2.3.2)rails (2.3.2)rake (0.8.7, 0.8.6)

# gem search active

*** LOCAL GEMS ***

activerecord (2.3.2)activeresource (2.3.2)activesupport (2.3.2)

Page 106: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

101Version 0.00

第10章 RubyGems

第10章

デフォルトでは、searchサブコマンドはローカルリポジトリを対象とします。リモートリポジトリを検索するには、--remoteオプションを指定します。

# gem search --remote active

*** REMOTE GEMS ***

active-fedora (1.0.2)active_acl (0.2.1)active_form (0.0.8)active_graph (0.1.0)active_lastfm (1.0.1)active_presenter (1.2.0)active_presenter_generator (1.0.1)active_presenters (1.1.7)active_record_voyeur (1.0.3)active_unimod_generator (0.1.0)active_youtube (1.0.0)activeaclplus (0.4.2)activecouch (0.1.0)activedirectory (1.0.1)

(...)

Page 107: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

102 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第10章

10.2.6 gemのサブコマンド一覧gemコマンドの代表的なサブコマンドを表にまとめておきます。

[表10-1]gemコマンドコマンド 説明

gem cleanup ローカルリポジトリ内にある古いパッケージを削除するgem contents インストールされたパッケージのコンテンツを表示するgem dependency インストールされたパッケージの依存関係を表示するgem fetch パッケージをダウンロードするgem help ヘルプを表示するgem install パッケージをインストールするgem list パッケージ一覧を表示するgem outdated アップデートが必要なパッケージを表示するgem search パッケージを検索するgem uninstall パッケージをアンインストールするgem update パッケージをアップデートする

Page 108: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

103Version 0.00

第10章 RubyGems

第10章

10.3 Rake

10.3.1 RakeファイルC言語で書かれたソースからビルドする際には、ファイルの依存関係を調べたり、指定した手順に従ってリンクやコンパイルを行うツールとしてMakeが使われます。Makeでは、Makefileファイルに手順を記述し、makeコマンドを実行することでMakefile内の処理が実行されます。以下は、簡単なMakefileの例です。

Makeツールと同等の機能を持ったRubyのビルドツールがRakeです。Rakeでは、Rubyコードを使って手順をrakeファイルに記述します。rakeファイルの書式は次のとおりです。

基本的な作業単位がタスクです。処理はタスク単位で実行できます。以下はrakeファイルの例です。

それぞれのタスク内で、shメソッドを使ってLinuxのコマンドを直接実行するようにしています。

RakeはMakeに相当するRubyのビルドツールです。

all: samplesample: sample.c

gcc -o sample sample.cclean:

rm -f sampleinstall: sample

cp sample /usr/local/bin

Makefileの例

task :タスク名 do任意の処理

end

rakeファイルの書式

task :install dosh 'cp *.rb /usr/local/bin'

end

task :clean dosh 'rm tmp/*'

end

task :default => [:install]

rakeファイルの例1

Page 109: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

104 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第10章

10.3.2 rakeコマンドrakeファイル内の処理を実行するには、rakeコマンドを使います。

先のrakeファイル(ファイル名はRakefileとします)の例で、installタスクを実行するには、次のようにします。

タスク名を省略した場合は、defaultタスクが実行されます。上記のrakeファイルには「task :default => [:install]」とあるので、installタスクが実行されます。

なお、rakeファイルのファイル名が「Rakefile」であれば、-fオプションによるファイルの指定は必要ありません。

rake [-f ファイル名] [タスク名]

rakeコマンドの書式

# rake -f Rakefile install

# rake -f Rakefile

# rake

Page 110: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

105Version 0.00

第10章 RubyGems

第10章

10.3.3 ファイルの依存関係rakeファイルでは、fileメソッドを使ってファイルの依存関係を指定できます。

この書式では、ファイルAはファイルBに依存しています。依存するファイルはハッシュで指定します。もしファイルAが存在しない場合、do~end内の処理が実行されます。また、ファイルBを更新したことでファイルAのタイムスタンプよりも新しくなった場合も、ブロック内の処理が実行されます。ファイルAの方が新しい場合は、何も処理が実行されません。

file "ファイルA" => ["ファイルB"... ] do処理

end

rakeファイルの書式2

Page 111: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

106 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第10章

第10章 テスト

問 題 1下線部に当てはまるサブコマンドを記述してください。 A. rakeパッケージをインストールする # gem ______ rake  B. rakeパッケージをアップデートする # gem ______ rake  C. gemでインストール済みのすべてのパッケージをアップデートする # gem ______  D. rakeパッケージをアンインストールする # gem ______ rake  E. リモートリポジトリにある、パッケージ名にmysqlが含まれるパッケージを検索する # gem ______ mysql --remote

問 題 2Rakeに関する記述として適切なものに○をつけてください。 (  )ソフトウェアのビルドやデータベースの作成に使われる (  )処理手順が記述されたファイルをrakeファイルという (  )Rakeの基本的な処理単位をタスクという (  )rakeファイルは基本的にRubyのコードを記述する

Page 112: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Ruby プログラミング

第11章実践的Rubyプログラミング

Page 113: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

108 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第11章

11.1 Rubyならではのプログラミング

11.1.1 可変引数引数の数が不定のメソッドを定義するには、変数名に「*」を付けます。

Rubyならではのプログラムの書き方をいくつか紹介します。

def println(*str)puts str

end

println "Hello, World."println "abc", 123

methodtest3.rb

$ ruby methodtest3.rbHello, World.abc123

Page 114: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

109Version 0.00

第11章 実践的Rubyプログラミング

第11章

11.1.2 シンボルRubyの内部では、メソッド名などの識別は、名前を表す文字列ではなく、シンボルが使われています。たとえ文字列が同一でも、Ruby内部では別々のID(オブジェクトID)で管理されています。

str1とstr2に格納されている文字列は同じですが、同一のオブジェクトではないことが分かります(別々のStringオブジェクト)。一方、シンボルは、同一の内容であればオブジェクトも同一です。シンボルは、1つの文字列を同じIDで表せるようにしたものと考えてもよいでしょう。

str1, str2 = 'Ruby', 'Ruby'p str1.object_idp str2.object_idp str1 == str2p str1.equal?(str2)

symbol1.rb

$ ruby symbol1.rb-604166538-604166548truefalse

sym1 = :Rubysym2 = :Rubyp sym1.object_idp sym2.object_idp sym1 == sym2p sym1.equal?(sym2)

symbol2.rb

$ ruby symbol2.rb104138104138truetrue

Page 115: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

110 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第11章

Rubyではシンボルがよく使われます。その理由としては、シンボルの方が文字列どうしの比較よりも高速に判定できることや、コードがすっきりして読みやすくなる点が挙げられます。シンボルはとりわけ、ハッシュのキーとしてよく用いられます。

なお、メソッドの(最後の)引数にハッシュを指定するときは、{}を省略することができます。次の例のような書き方はよく用いられます。

他に、第2章でも取り上げたように、アクセスメソッドを定義する際にも利用されます。

# 一般的なハッシュhash = {"Ruby" => 1, "Python" => 2, "Perl" => 3}

# シンボルをキーに使ったハッシュhash = {:Ruby => 1, :Python => 2, :Perl => 3}

symbol3.rb

def symtest(a)a.each {|b| p b }

end

symtest :Ruby => 1, :Python => 2, :Perl => 3

symbol4.rb

attr_accessor :distro, :version

アクセスメソッドの定義例

Page 116: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

111Version 0.00

第11章 実践的Rubyプログラミング

第11章

11.1.3 変数の初期化Rubyでは、論理和を評価するとき、たとえば「a || b」を評価するとき、最初にaを評価して真であれば、bを評価することなく、式の値としてaを返します。論理積も同様で、「a && b」を評価し、aが偽の場合はbを評価しません。これを代入式と組み合わせることで、「変数が真であれば代入する」もしくは「変数が偽であれば代入する」といったことができます。

この形式は、インスタンス変数を初期化するような場合に一般的な書き方です。

var = truevar ||= 1#=> varの値はtruevar &&= 1#=> varの値は1

var = falsevar &&= 1#=> varの値はfalsevar ||= 1#=> varの値は1

var = nilvar &&= 1#=> varの値はnilvar ||= 1#=> varの値は1

init.rb

Page 117: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

112 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第11章

制御式による代入Rubyでは「if文」「case文」ではなく「if式」「case式」のように、分岐やループを行う構文は「○○文」ではなく「○○式」です。なぜなら、制御式を評価すると値が得られるからです。したがって、制御式と変数の代入を組み合わせて利用することができます。

print "input [1-3] : "a = gets.to_ivar = if a == 1 then"Ruby"

elsif a == 2 then"Python"

else"Perl"

end

puts "var : #{var}"

varsub.rb

$ ruby varsub.rbinput [1-3] : 1var : Ruby$ ruby varsub.rbinput [1-3] : 2var : Python$ ruby varsub.rbinput [1-3] : 3var : Perl

Page 118: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

113Version 0.00

第11章 実践的Rubyプログラミング

第11章

11.2 誤りやすいポイント

11.2.1 識別子Rubyの変数名は、大文字小文字が区別されます。たとえば、varとvArは別の変数です。また、Rubyでは以下の語が予約語なので、変数名などに使用することができません。

BEGIN def for redo undefEND defined? if rescue unlessalias do in retry untiland else module return whenbegin elsif next self whilebreak end nil super yieldcase ensure not thenclass false or true

Rubyの予約語

Page 119: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

114 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第11章

11.2.2 if式の評価Rubyのif式では、真偽の評価で「偽」となるのは、falseもしくはnilの場合のみです。それ以外の値は「真」と評価されます。

「0」「1」といった値や空文字列はいずれも真となりますので注意してください。

def iftest(b)if b thenputs 'true'

elseputs 'not true'

endend

b = trueiftest(b)b = falseiftest(b)b = niliftest(b)b = 0iftest(b)b = 1iftest(b)b = ''iftest(b)

iftest.rb

$ ruby iftest.rbtruenot truenot truetruetruetrue

Page 120: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

115Version 0.00

第11章 実践的Rubyプログラミング

第11章

11.2.3 elsif次のプログラムを実行するとsyntax errorとなります。どこが誤りか判別できるでしょうか。

Rubyでは「elsif」ですが、ここは言語によってさまざまなため、混乱しがちです。正しくは次のとおりです。

str = 'Ruby'

if str == 'Ruby'puts 'I love Ruby.'

else if str == 'Perl'puts 'I love Perl'

end

error1.rb

str = 'Ruby'

if str == 'Ruby'puts 'I love Ruby.'

elsif str == 'Perl'puts 'I love Perl'

end

good1.rb

Page 121: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

116 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第11章

11.3 その他の話題

11.3.1 メソッドの探索手順Rubyでは、呼び出されるメソッドは次のような手順で決定されます。

①特異メソッド(定義されていれば)②オブジェクトが属するクラスのインスタンスメソッド③オブジェクトのクラスがインクルードしたモジュールのメソッド④オブジェクトの親クラスのインスタンスメソッド⑤オブジェクトの親クラスがインクルードしたモジュールのメソッド⑥以下、親クラスに向かって遡って探索⑦最後まで見つからなければNoMethodError例外が発生

この章では、Rubyプログラマとして知っておきたい話題や、誤りやすい点など、雑多なテーマを扱います。

オーバーロードは不可能Rubyでは、メソッド名によってのみメソッドが特定されます。したがって、引数の数や型によって別々のメソッドとして扱うオーバーロードは、Rubyでは不可能です。

Page 122: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

117Version 0.00

第11章 実践的Rubyプログラミング

第11章

11.3.2 evaleval関数は、引数をRubyプログラムとして実行します。

irbのようなプログラムを簡単に作れてしまいます。

終了するには[Ctrl]+[D]を押します。

他にも、いわゆる「eval族」と呼ばれるメソッドがあります。たとえばinstance_evalを使うと、既存のインスタンスを書き換えることができます。

$ ruby evaltest1.rbI love Ruby.

code = 'puts "I love Ruby."'

eval(code)

evaltest1.rb

$ ruby evaltest2.rbputs "Ruby"Rubynilp "Ruby".object_id-604508598nil

while code = getsp eval(code)

end

evaltest2.rb

$ ruby evaltest3.rbHello, Ruby.Good-bye.

class Hellodef helloputs "Hello, Ruby."

endend

e = Hello.newe.hello

e.instance_eval 'def bye; puts "Good-bye."; end'e.bye

evaltest3.rb

Page 123: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

118 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第11章

第11章 テスト

問 題 1Rubyにおけるシンボルとはどのようなものですか?

問 題 2シンボルを利用することのメリットを挙げてください。

問 題 3Rubyのif式で「偽」となるものを選択してください。 A. 正の整数 B. 負の整数 C. 0 D. 空文字列(NULL) E. false F. nil

問 題 4指定された引数の内容をRubyコードとして実行する関数は何ですか?

Page 124: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

第12章

Ruby プログラミング

第12章Rubyによる

GUIアプリケーション

Page 125: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

120 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第12章

Rubyをソースからコンパイルする場合は、事前にtcl-devel、tk-develパッケージをインストールしておいてください。

12.1 RubyによるGUIアプリケーション開発

12.1.1 Ruby/TKの概要とインストールRuby/TKは、Rubyに標準添付されているGUIアプリケーション開発ユーティリティです。TKは複数のOSに対応したGUIツールキットで、Tclと組み合わせてTcl/TKとして使われることが多いのですが、Tclの代わりにRubyをスクリプト言語として利用するのがRuby/TKです。

通常、Rubyをソースからインストールすると、必要なライブラリなども合わせてインストールされるのですが、パッケージからインストールした場合は、追加インストールが必要な場合があります。CentOSでは、次のコマンドでインストールします。

Ubuntuの場合は次のコマンドでインストールします。

RubyはGUIアプリケーションの開発にも利用できます。

# yum install ruby-tcltk

# apt-get install libtcltk-ruby

Page 126: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

121Version 0.00

第12章 RubyによるGUIアプリケーション

第12章

12.1.2 簡単なGUIアプリケーションの作成と実行まずは、もっともシンプルなGUIアプリケーションを作ってみます。

実行するには、GUI環境で、シェル上から次のコマンドを実行します。

図のようなウィンドウが表示されます。ただウィンドウ内に「Hello, Ruby/TK.」と表示されるだけなので、閉じるボタンでウィンドウを閉じます。

require 'tk'

label = TkLabel.newlabel.text("Hello, Ruby/TK.")label.pack

Tk.mainloop

hellotk1.rb

$ ruby hellotk1.rb

[図12-1:hellotk1.rb]

Page 127: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

122 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第12章

12.1.3 ルートウィジェットとイベントループRuby/TKプログラムで最低限必要なものは以下の2行です。

実行すると、何もないウィンドウが表示されます。これをルートウィジェットといいます。ウィジェットとは、個々のGUI部品のことです。ルートウィジェット上にさまざまなウィジェットを配置してGUIアプリケーションを作っていくことになります。

「require 'tk'」は、Ruby/TKプログラムに必要なライブラリのインクルートです。「Tk.mainloop」はイベントループです。「マウスを動かす」「マウスをクリックする」のような、GUI上で発生する出来事をイベントといいます。イベントループは、イベントを捉えてウィジェットに渡す役割を持っています。

require 'tk'Tk.mainloop

rubytk.rb

[図12-2:rubytk.rb]

Page 128: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

123Version 0.00

第12章 RubyによるGUIアプリケーション

第12章

12.1.4 ラベルウィジェットRuby/TKでは、すべてのウィジェットはクラスとして定義されています。インスタンスを作成すると、ルートウィジェット上にGUI部品が作成されることになります。たとえば、文字列を表示するラベルウィジェットは、TkLabelクラスのインスタンスです。

もう一度、最初の例を取り上げます。

「label = TkLabel.new」で新しいラベルウィジェットが作成されます。ウィジェットはさまざまな属性を持っています。たとえばラベルウィジェットの場合、アクセスメソッドを使ってtext属性に文字列を設定すると、ラベルウィジェット上に文字列が表示されます。これが「label.text("Hello, Ruby/TK.")」の部分です。

ただし、それだけではまだラベルウィジェットは表示されません。packメソッドを実行すると、その時点でルートウィジェット上にウィジェットが表示されます。packメソッドはウィジェットを配置する役割を持っており、ジオメトリマネージャと呼ばれます。

ジオメトリマネージャには、pack以外にもgridやplaceがあります。packは、ウィジェットを配置する座標やサイズの指定がなくても適切に処理をしてくれるので、本書ではpackメソッドのみを利用することとします。

require 'tk'

label = TkLabel.newlabel.text("Hello, Ruby/TK.")label.pack

Tk.mainloop

hellotk1.rb

Page 129: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

124 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第12章

12.1.5 ウィジェットの作成先の例では、ラベルウィジェットを表す変数labelを利用し、アクセスメソッドを使って属性の設定をしました。一方、次のような書式で、インスタンス作成時に属性も指定することができます。こちらの書式が一般的です。

最初の引数は、親となるウィジェットの指定です。ルートウィジェット上に配置するにはnilを指定します。2つめ以降の引数には「:属性名 => 値」の形式で属性を指定していきます。そのようにして作られたインスタンスにpackメソッドを実行すると、ウィジェットが作成されます。

次の例では、ラベルに色を付けています。読みやすいように、適宜改行を入れるとよいでしょう。

fgには文字色を、bgには背景色を指定します。

クラス名.new(nil, :属性名 => 値, :属性名 => 値, ...).pack

ウィジェットの作成

require 'tk'

TkLabel.new(nil,:text => 'Hello, Ruby/TK.',:fg => 'red',:bg => 'black').pack

Tk.mainloop

hellotk2.rb

[図12-3:hellotk2.rb]

Page 130: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

125Version 0.00

第12章 RubyによるGUIアプリケーション

第12章

12.1.6 ボタンウィジェットGUIアプリケーションの終了ができるよう、終了ボタンを追加しましょう。ボタンはTkButtonクラスのインスタンスです。

text属性には、ボタン上に表示する文字列を指定します。ボタンを押したときに実行されるRubyスクリプトは、command属性で「proc{}」内に記述します。プログラムを終了させるには「exit」を実行します。

require 'tk'

TkLabel.new(nil,:text => 'Hello, Ruby/TK.',:fg => 'red',:bg => 'black').pack

TkButton.new(nil,:text => 'Exit',:command => proc{exit}).pack

Tk.mainloop

hellotk3.rb

[図12-4:hellotk3.rb]

Page 131: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

126 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

第12章

12.1.7 テキストエリアTkEntryクラスを使うと、文字を入力するためのテキストエリアを作成することができます。Entryウィジェットに入力された文字列を取り出すには、valueメソッドを使います。

次の例では、入力された文字列を使って挨拶を返すプログラムです。メッセージを出力するウィジェットには、ラベルウィジェットを使っています。

演習問題

Todayボタンを配置し、クリックするとメッセージ表示部に今日の日付を表示するよう、hellotk4.rbを修正しなさい。

require 'tk'

TkLabel.new(nil,:text => 'Please input your name:').pack

entry = TkEntry.new.packmessage = TkLabel.new.pack

TkButton.new(nil,:text => 'Hello',:command => proc{message.text("Hello,

#{entry.value}")}).pack

TkButton.new(nil,:text => 'Exit',:command => proc{exit}).pack

Tk.mainloop

hellotk4.rb

[図12-5:hellotk4.rb] [図12-6:メッセージの出力]

Page 132: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

127Version 0.00

第12章 RubyによるGUIアプリケーション

第12章

第12章 テスト

問 題 1Ruby/TKで、ウィジェットとは何を表しますか?

問 題 2すべてのGUI部品のベースとなるウィジェットは何ですか?

問 題 3イベントループとは何ですか?

Page 133: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

128 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

記  号

$0 ………………………………………… 24$1 ………………………………………… 24$ …………………………………………… 42$\ ………………………………………… 24$! …………………………………………… 24$"…………………………………………… 24$$ ………………………………………… 24$& ………………………………………… 24$' …………………………………………… 24$* …………………………………………… 24$. …………………………………………… 24$< ………………………………………… 24$> ………………………………………… 24$? ………………………………………… 24$@ ………………………………………… 24$_ ………………………………………… 24$` ………………………………………… 24$1, $2 ... ………………………………… 24$KCODE ………………………………… 24$stderr ……………………………… 24・62$stdin ……………………………… 24・62$stdout ……………………………… 24・62* …………………………………………… 42+ …………………………………………… 42. …………………………………………… 42=~メソッド ……………………………… 45? …………………………………………… 42[ ] ………………………………………… 42^ …………………………………………… 42{m,} ………………………………………… 42{m,n} ……………………………………… 42{m} ………………………………………… 42| …………………………………………… 42\1 ………………………………………… 42\2 ………………………………………… 42\A ………………………………………… 42\b ………………………………………… 42\B ………………………………………… 42\d ………………………………………… 42\D ………………………………………… 42\s ………………………………………… 42\S ………………………………………… 42

\w ………………………………………… 42\W ………………………………………… 42\z …………………………………………… 42\Z ………………………………………… 42

アルファベット

AARGV ……………………………………… 63

Bbasenameメソッド …………………… 80binmodeメソッド ……………………… 71

Cclass式 …………………………………… 12class式 …………………………………… 17closeメソッド …………………………… 64

DDate.todayメソッド …………………… 89DateTimeクラス ………………………… 87Dateクラス ……………………………… 89dateライブラリ ………………………… 87def式 ………………………………………… 5Dir.chdirメソッド ……………………… 74Dir.globメソッド ………………………… 76Dir.mkdirメソッド ……………………… 77Dir.pwdメソッド ………………………… 74Dir.rmdirメソッド ……………………… 77dirnameメソッド ……………………… 80Dirクラス ………………………………… 74downtoメソッド ………………………… 56

Eeachメソッド …………………………… 53elsif ………………………………………115eof?メソッド …………………………… 65eval関数 ……………………………………117extnameメソッド ……………………… 80

FFile.chmodメソッド …………………… 81File.deleteメソッド ……………………… 79File.renameメソッド …………………… 78File.statメソッド ………………………… 81

索 引

Page 134: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

129Version 0.00

索引

Fileクラス …………………………… 64・78

Ggemコマンド …………………………… 95getcメソッド …………………………… 67getsメソッド …………………………… 65gsub!メソッド …………………………… 48gsubメソッド …………………………… 48

Iif式 …………………………………………114include ……………………………… 32・33initializeメソッド ………………………… 13IOクラス ………………………………… 64

Jjoinメソッド ……………………………… 80

Kkernelモジュール ……………………… 37

Llinenoメソッド …………………………… 67loopメソッド …………………………… 57

Mmatchメソッド ………………………… 45Mix-in ……………………………………… 35module …………………………………… 34

Oopenメソッド …………………………… 64

Ppackメソッド ……………………………123posメソッド ……………………………… 68printメソッド …………………………… 70private …………………………………… 26protected ………………………………… 26public ……………………………………… 26putcメソッド …………………………… 70putsメソッド …………………………… 70

RRake ………………………………………103rakeコマンド ……………………………104rakeファイル ……………………………103readlinesメソッド ……………………… 66

readメソッド …………………………… 68Regexpクラス …………………………… 44return式 …………………………………… 7rewindメソッド ………………………… 69riコマンド ………………………………… 89Ruby/TK …………………………………120RubyForge ……………………………… 94RubyGems ……………………………… 94

Sself …………………………………………… 3splitメソッド …………………………… 80sqrtメソッド……………………………… 33STDERR ………………………………… 62STDIN …………………………………… 62STDOUT ………………………………… 62stepメソッド …………………………… 57strftimeメソッド ………………………… 85sub!メソッド …………………………… 48subメソッド ……………………………… 48

TTcl/TK ……………………………………120Time.mktimeメソッド ………………… 84Time.newメソッド ……………………… 84timesメソッド …………………………… 55Timeクラス ……………………………… 84TkButtonクラス …………………………125TkEntryクラス ……………………………126TkLabelクラス ……………………………123to_sメソッド …………………………… 70

Uuptoメソッド …………………………… 56

Wwriteメソッド …………………………… 70

Yyield ……………………………………… 58

カ  ナ

アアクセサ…………………………………… 15アクセスメソッド………………………… 15

Page 135: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

130 ⓒ 2009 Linux Academy

Ruby プログラミング 中級

イテレータ………………………………… 52イベントループ……………………………122インスタンスメソッド…………………… 12インスタンス変数…………………… 13・23ウィジェット………………………………122オープンクラス…………………………… 19オブジェクトID……………………………109

カ改行文字…………………………………… 71可変引数……………………………………108関数的メソッド……………………………… 4組み込み変数……………………………… 24クラス変数…………………………… 14・23クラス名…………………………………… 12クラスメソッド…………………………… 14グローバル変数…………………………… 24継承………………………………………… 17後方参照…………………………………… 47

ササブクラス………………………………… 17ジオメトリマネージャ……………………123識別子………………………………………113正規表現オブジェクト…………………… 44正規表現とは……………………………… 42シンボル……………………………………109スーパークラス…………………………… 17スコープ…………………………………… 22

タタスク………………………………………103定数………………………………………… 25テキストモード…………………………… 71特異メソッド……………………………… 28

ナ名前空間……………………………… 32・38

ハバイナリモード…………………………… 71パターンマッチ…………………………… 45標準エラー出力…………………………… 62標準出力…………………………………… 62標準入力…………………………………… 62ブロック付メソッド………………………… 8ブロック呼び出し………………………… 52変数名……………………………………… 22

ボタンウィジェット………………………125

マメソッド……………………………………… 2メソッド連鎖………………………………… 2モジュール………………………………… 32戻り値………………………………………… 7

ヤ予約語………………………………………113

ララベルウィジェット………………………123ルートウィジェット………………………122レシーバ……………………………………… 3ローカル変数……………………………… 22

Page 136: Rubyプログラミング中級 - cs.tohoku-gakuin.ac.jpotofuji/ETC/OSS/subject1-3_lesson.pdf · ⓒ 2009 Linux Academy Ruby プログラミング 中級 Ⅲ 第8章 ファイル/ディレクトリ操作

Rubyプログラミング中級

2009年7月1日   初 版 第1刷 発行

著 者 株式会社 リナックスアカデミー

監 修 株式会社 万葉

発 行 株式会社 リナックスアカデミー 〒160-0023 東京都新宿区西新宿7-4-3 升本ビル TEL:03-3365-2072 FAX:03-3365-2076 URL:http://www.linuxacademy.ne.jp/

090519JLB03

Ver 1.0.0

※本書は、「クリエイティブ・コモンズ・ライセンス 表示 2.1 日本」により、株式会社リナックスアカデミーから利用許諾されています。 詳しい利用許諾条項は、http://creativecommons.org/licenses/by/2.1/jp/legalcode をご覧ください。

http://www.linuxacademy.ne.jp/biz/