Ruby勉強会

第二回第三章の解説
  満永 裕之
前回のおさらい

 #コメント と=start埋め込みドキュメント=end
 構文構造
 ブロック構造
はじめに

 日本語の表示方法
  # -*- encoding: utf-8 -*-
 を先頭につける(マジックコメント)
リテラル

? 全ての数値オブジェクトはイミュータブルである
 整数、文字、文字列リテラルについて説明
 整数リテラル
    単純に数字の並び
0
123
1234567890 など
 アンダースコア(_)を挿入して数字を見やすくすること
 が出来る
1_000_000_000 #10億   =   1 billion = 1,000 million
整数リテラル

 10進数以外の基数で整数リテラルを表現できる
0377    #255の8進数表現 0~
0b1111_1111 #255の2進数表現 0b~
0xFF    #255の16進数表現 0x~
 負数を表現するには整数リテラルの先頭をマイナ
  ス符号にするとよい
 浮動小数点リテラル
0.0
-3.14
6.02e23 #6.02 * 10の23乗
1_000_000.1 #100万とほんの少し
 .1のように数字をなくして小数点を書くことは出
 来ない
整数リテラル(Rubyの算術演算)

 整数の算術演算でオーバーフローが起きない(クラ
  スの自動変換が行われる)
 浮動小数点数はオーバーフローすると正負の無限大
  を表す特別な値になる
[5/2,5.0/2,5/2.0] # =>[2,2.5,2.5]
[5.0.div(2),5.0.fdiv(2),5.quo(2)] # =>[2,2.5,Rational(5,2)]
?指数計算のために**演算子を使うことが出来る
x**4 #x*x*x*xと同じ
x**-1 #1/xと同じ
x**(1/3.0) #Xの平方根
x**(1/4) #整数の除算を行うとx**0と同じこととなり1になってしまう
x**(1.0/4.0) #xの4乗根
文字列

 もっとも単純な文字列リテラルはシングルクォート
 で囲まれたもの
'これは単純な文字列リテラルである„
 ダブルクォートで囲まれた文字列リテラルはシング
 ルクォートリテラルより柔軟性が高い
"この文字列リテラルは、
2行だが
三行に書かれている"
?エスケープシークエンス
   Unicodeエスケープ
   セパレータ
   ヒアドキュメント
文字リテラル

 文字の前に疑問符を入れると、Rubyプログラムに単
 一の文字をリテラルとして組み込むことが出来る
?a #ASCII文字Aを表す文字リテラル
?" #ダブルクォート文字を表す文字リテラル
?? #疑問符を表す文字リテラル
?あ #ひらがなの「あ」を表す文字リテラル
 文字リテラルの構文は全ての文字エスケープ(?)
 と併用できる
文字列演算子

 文字列の結合や繰り返しを行う
planet = "Earth"
"Hello" + " " + planet # Hello Earthと表示
"Hello planet #" + planet_number.to_s #to_s は文字列への返還を行う
"Hello planet ##{planet_number}"
greeting = "Hello"
greeting << " " << "world"
puts greeting #Hello worldと表示
 文字や部分文字列へのアクセス
s = 'Hello'
s[0] #ASCIIキャラクターコードで最初の文字である'h'を返す
配列

 配列とは値の列で、列の中の位置(添字)によって
    値にアクセスできるようになっているものである。
   Rubyでは配列の先頭の添字は0となっている。
   配列の最後の要素は-1という添字でもアクセスでき
    る。
   配列の外を読もうとすると、nilをかえす。
   +,-,*,<<演算子を使うことも可能である
配列(プログラム例)

[1,2,3] #3個のFixnumオブジェクトを保持する配列
[-10...0,0..10] #2個の範囲から構成される配列。末尾のカンマは許される
[[1,2],[3,4],[5]] #ネストされた配列の配列
[x+y,x-y,x*y] #配列要素としては任意の式が使える
[] #空配列の数字は0

a = []
a << 1
a << 2 << 3
a << [4,5,6]
a.count [7,8]
b = [0] * 8
a[0]
a[-1]
a[9]

['a','b','c','d','e']-['b','c','d'] #['a','e']
?ハッシュ

 ハッシュとはキーと呼ばれるオブジェクトの集合を
  保持し個々のキーに値を対応付けているデータ構造
  である。
 キーを値にマッピングするのでマップとも呼ばれる
#このハッシュは、数字の名前を数字自体にマッピングする
numbers = Hash.new #新しい空のオブジェクトを作成する
numbers["one"] = 1
numbers["two"] = 2
numbers["three"] = 3
sum = numbers["one"] + numbers["two"] #このようにして値を取得する
 先ほど作成したHashオブジェクトはハッシュリテラルでも
  作成できる
numbers = {"one" => 1,"two" => 2, "three" => 3 }
範囲

 範囲リテラルは先頭の値と末尾の値の間に二個または三
  個のドットを入れて記述する。ドットが二個なら範囲は
  包括的で末尾の値も範囲の一部になる。三個なら範囲は
  排他的で末尾の値は範囲に含まれない。
 値が範囲に含まれるかはinclude?メソッドかmember?メ
  ソッドでテストする
1..10 #1以上10以下の整数
1.0...10.0 #1.0以上10.0未満の数値(10.0は含まれない)

r = 0...100 #0から99までの範囲の整数
r.member? 50 # true:50は範囲のメンバ
r.include?(100) # false:100は範囲の外
r.include?(99.9) # true:99.9は100よりも小さい
?シンボル

 実装が把握している全てのクラス、メソッド、変数
 の名前を格納するシンボルテーブル(記号表)を管
 理している。シンボルテーブルがあるおかげでイン
 タープリタは文字列の比較をほとんどせずに済ませ
 られる。
?Symbolオブジェクトはシンボルを参照しているの
 である。シンボルリテラルはコロンをプレフィック
 スすると識別子や文字列という形で書ける
シンボル(プログラム例)

:symbol #Symbolのリテラル
:“symbol” #全く同じリテラル
:'another long symbol'
s = "string"
sym = :“#{s}” #:Stringというシンボル
%s["]
o.respond_to? :each

name = :size
if o.respond_to? name
 o.send(name)
end

str = “string” #文字列からスタート
sym = str.intern #シンボルに変換する
sym = str.to_sym #同じことを行う別の方法
str = sym.to_s #再び文字列に変換する
str = sym.id2name #同じことを行う別の方法
オブジェクト

 オブジェクト参照
 Rubyでオブジェクトを操作する時、実際に操作し
 ているのはオブジェクト参照である。
s = "Ruby" #Stringオブジェクトを作り、参照をsに格納する
t = s #参照のコピーを作ってtに格納する。sとtは同じオブジェクトを参照す
   る
t[-1] = "" #tに格納されていた参照を介してオブジェクトを書きかえる
print s #sを介して書き換えられたオブジェクトにアクセスする。"Rub"と表
   示
t = "Java" #tは別のオブジェクトを参照している
print s,t #"RubJava"と表示
オブジェクト

 オブジェクトの寿命
 リテラル構文を持っていないクラスはオブジェクト
 を名前を付けて作成しなければならない(newとい
 う名前を付けることが多い)
myObject = myClass.new
?Rubyはガベージコレクションと呼ばれるテクニッ
 クを持っており、オブジェクトは到達不能になると
 ガベージコレクションの候補になる
オブジェクト

 オブジェクト識別子
全てのオブジェクトはFixnumのオブジェクト識別
子を持っておりこの値はobject_idメソッドによって
取得できる。このメソッドが返す値はオブジェクト
の生涯にわたって一定であり、一意的である。
オブジェクト

?オブジェクトのクラスと型
  Rubyではオブジェクトのクラスが何かを取得するため
  に方法がいくつか存在する
 Ruby1.9では、オブジェクトはクラス階層のルートク
  ラスではなくなった
o = "test"
o.class #Stringクラスを表すオブジェクトを返す
#Ruby1.9から
Object.superclass #BasicObject:1.9ではオブジェクトにスーパークラスが
   ある
o.class == String #oがStringならtrue
o.instance_of? String #oがStringならtrue
オブジェクト

 オブジェクトの等値性
  Rubyにはオブジェクトが正しいかどうかを比較す
  る方法が4つある
 equal?メソッド,==演算子,eqlメソッド?===演算子,-
  ~演算子
 一般的にequal?メソッドは参照しているオブジェク
  トを比較し、==演算子は完全に同じオブジェクトか
  を調べるのに用いられる。
オブジェクト

 オブジェクトの等値性(プログラム例)
a = "Ruby" #一個のStringオブジェクトに対する一個の参照
b = C = "Ruby" #別のStringオブジェクトに対する二個の参照
a.equal?(b) #false: aとbは異なるオブジェクトを参照している
b.equal?(c) #true: bとcは同じオブジェクトを参照している

a = "Ruby" #一個のStringオブジェクト
b = "Ruby" #内容は同じだが別のStringオブジェクト
a.equal?(b) #false: aとbは同一のオブジェクトではない
a == b #true: しかし、二つの異なるオブジェクトは同じ値を持っている

1 == 1.0 #true:FixnumとFloatは==になることがある
1.eql?(1.0) #false: しかしこれらがeql?になることは決してない

(1..10) === 5 #true: 5 は1..10の範囲内
/d+/ === 123 #true: 文字列は正規表現にマッチしている
String === "s" #true: "s" はStringクラスのインスタンス
:s === "s" #Ruby1.9 ではture
オブジェクト

 オブジェクトの順序
  クラスは<=>演算子を実装して順序を定義する。こ
  の演算子は左辺の方が右辺より小さければ-1,両辺が
  等しければ0,左辺が右辺より大きければ1を返さねば
  ならない。
 Comparableミックスインは<,<=,==,>=,>の演算子
  も定義している。
オブジェクト

 オブジェクトの順序(プログラム例)
1 <=> 5 #-1
5 <=> 5 #0
9 <=> 5 #1
"1" <=> 5 #nil: 整数と文字列は比較されない

nan = 0.0/0.0 #0÷0は数値ではない
nan < 0 #false: 0より小さくない
nan > 0 #false:0より大きくない
nan == 0 #false:と等しくない
nan == nan #false:自分自身とも等しくない
nan.epual?(nan) #true
オブジェクト

?オブジェクトの変換
 #Ruby 1.8のみ
 e = Exception.new("not really an exception")
 msg = "Error " + e #String とExceptionの連結

   1.1.coerce(1) # [1.0,1.1]:Fixnum からFloatに強制変換
   require "rational" #Rationalを使う
   r = Rational(1,3) #Rational型の三分の一
   r.coerce(2) #[Rational(2,1),Rational(1,3)]:Fixnum からRatonal
    に

 if x != nil #"x != nil"という式はifに trueか falseを返す
 puts x #定義されている場合はxを出力する
 end
オブジェクト

?オブジェクトのコピー
 cloneとdupはともにコピーされるオブジェクトにほ
 かのオブジェクトを参照する内部構造が含まれてい
 る場合オブジェクト参照だけがコピーされ参照され
 ているオブジェクト自体はコピーされない
 cloneはオブジェクトのフリーズ、汚染状態をとも
 にコピーするがdupは汚染状態しかコピーしない。
オブジェクト

?オブジェクトの永続化
 オブジェクトの状態は、クラスメソッドの
 Marshal.dumpにオブジェクトを渡せば保存でき
 る。第二引数としてI/oストリームオブジェクトを渡
 せばMarshal.dimpはそのストリームにオブジェクト
 の状態を書き込む。
作成したデータをオブジェクトに復元するには、その
 データを含む文字列かI/OストリームをMarshal.load
 に渡す。
オブジェクト

 オブジェクトのフリーズ
 オブジェクトはどれもfreezeメソッドを呼び出せば
 フリーズすることが出来る。
フリーズされたオブジェクトは内部構造の変更が出来
 なくなり、ミュータブルなメソッドを呼び出しても
 失敗する。
オブジェクトがフリーズしているかはfrozen?メソッド
 で確認できる。
フリーズされたオブジェクトを「解凍」することはで
 きない。
オブジェクト

 オブジェクトのフリーズ(プログラム例)
s = "ice" #Stringはミュータブルなオブジェクト
s.freeze #この文字列をイミュータブルにする
s.frozen? #true: フリーズされている
s.upcase! #TypeError: フリーズされた文字列を書きかえることはできな
   い
s[0] = "ni" #TypeError: フリーズされた文字列を書きかえることはで
   きない
オブジェクト

 オブジェクトの汚染状態
taintメソッドを呼び出すと、オブジェクトに汚染され
  ているというマークを付けることが出来る。汚染さ
  れたオブジェクトから作られたオブジェクトも汚染
  状態になる。
オブジェクトが汚染されたかどうかはtainted?メソッ
  ドでテストできる。
オブジェクト

 オブジェクトの汚染状態(プログラム例)
s = "untrusted" #オブジェクトは通常汚染されていない
s.taint #個の信頼できないオブジェクトに汚染済みマークを付ける
s.tainted? #true: 汚染されている
s.upcase.tainted? #true: 汚染済みオブジェクトから作られたオブジェク
   トも汚染済み
s[3,4].tainted? #true: 部分文字列も汚染されている

Ruby講座第二回