データ型
これからRubyで扱うデータの概要を説明します。Rubyの場合、基本的なデータ型には「数」と「文字列」があり、高水準なデータ型として「配列」と「ハッシュ」があります。詳細な定義についてはマニュアル・リファレンスを参照してください。
データはオブジェクト
Rubyでは、数値や文字列など全てのデータがオブジェクトとして扱われます。メソッドの呼び出しは「.(ドット)」を使います。メソッドに渡す引数を囲む「( )」は付けても付けなくてもかまいません。
またRubyはダックタイピングの特徴を持っています。すなわち、オブジェクトがメソッドを持っていれば、そのクラス型に関わらずそのメソッドを実行できるというものです。
irb(main):001:0> "12,34,56".split(",") #ドットに続いてメソッド
=> ["12", "34", "56"]
irb(main):002:0> "12,34,56".split "," #引数のカッコを省略
=> ["12", "34", "56"]
irb(main):003:0> 123.size #数字のsizeメソッド(バイト数)
=> 4
irb(main):004:0> "123".size #文字列のsizeメソッド(文字数)
=> 3
irb(main):005:0> [1,2,3].size #配列のsizeメソッド(要素数)
=> 3
irb(main):006:0> {1=>2, 3=>4}.size #ハッシュのsizeメソッド(要素数)
=> 2
変数と定数
Rubyも他の手続き型プログラミング言語と同様に変数を設定し、代入・参照することができます。Rubyには変数の型がなく、代入の前に宣言しておく必要はありません。変数名は1文字目が英小文字かアンダーバー(_)、2文字目以降は英数文字またはアンダーバーで指定します。
定数も設定することができます。定数の名前は1文字目が英大文字、2文字目以降は英数文字またはアンダーバーで指定します。定数は値を再設定すると警告が出ます。また定数の中には、あらかじめ組み込まれている定数もあります。
irb(main):001:0> a = 100 #変数に値を代入
=> 100
irb(main):002:0> b = 200
=> 200
irb(main):003:0> c = a + b
=> 300
irb(main):004:0> puts c #変数を参照
300
=> nil
irb(main):005:0> c = "Ruby" #変数cに型が異なる「文字列」を代入
=> "Ruby"
irb(main):006:0> puts c
Ruby
=> nil
irb(main):007:0> CONST = "Ruby" #定数に値を設定
=> "Ruby"
irb(main):008:0> CONST = "Java" #定数を再設定
(irb):8: warning: already initialized constant CONST
=> "Java"
irb(main):009:0> puts CONST #再設定した定数値を参照
Java
=> nil
irb(main):010:0> puts RUBY_VERSION #組み込み定数
1.9.3
=> nil
数値
四則演算は通常の書式で記述できます。「**」はべき乗の演算子です。
irb(main):001:0> 5 + 3 #足し算
=> 8
irb(main):002:0> 5 - 3 #引き算
=> 2
irb(main):003:0> 5 * 3 #掛け算
=> 15
irb(main):004:0> 5 / 3 #(整数型同士の)割り算
=> 1
irb(main):005:0> 5.0 / 3 #割り算
=> 1.6666666666666667
irb(main):006:0> 5 % 3 #剰余
=> 2
irb(main):007:0> 5 ** 3 #べき乗
=> 125
irb(main):008:0> 100 + 200 * 300 / (400 + 500)
=> 166
数値を調べるための便利なメソッドも用意されています。
irb(main):001:0> a = 0
=> 0
irb(main):002:0> a.zero? #数値はゼロか?
=> true
irb(main):003:0> a.integer? #数値は整数か?
=> true
irb(main):004:0> b = 1.0
=> 1.0
irb(main):005:0> b.integer? #値が浮動小数点数ならばfalseと返す
=> false
irb(main):006:0> c = 100
=> 100
irb(main):007:0> c.even? #数値は偶数か?
=> true
irb(main):008:0> c.odd? #数値は奇数か?
=> false
型変換をするメソッドや、浮動小数点数に対して四捨五入や切り上げ・切り捨てを行うメソッドもあります。
irb(main):001:0> 1234.to_f #浮動小数点数に変換
=> 1234.0
irb(main):002:0> 3.14.to_i #整数に変換
=> 3
irb(main):003:0> 3.14.to_s #文字列に変換
=> "3.14"
irb(main):004:0> 1.4.round #小数点以下を四捨五入
=> 1
irb(main):005:0> 1.5.round
=> 2
irb(main):006:0> 1.5.ceil #小数点以下切り上げ
=> 2
irb(main):007:0> -1.5.ceil
=> -1
irb(main):008:0> 1.5.floor #小数点以下切り捨て
=> 1
irb(main):009:0> -1.5.floor
=> -2
Mathモジュールを使うことで、定数や数学関数を使うことができます(モジュールについては後述)。
irb(main):001:0> Math::PI #円周率
=> 3.141592653589793
irb(main):002:0> Math::E #自然対数の底
=> 2.718281828459045
irb(main):003:0> Math::sqrt(3) #平方根
=> 1.7320508075688772
irb(main):004:0> Math.sin(Math::PI/2) #正弦関数
=> 1.0
文字列
文字列を「'」(シングルクオート)か「"」(ダブルクオート)で囲むことで文字列オブジェクトを生成します。ダブルクオートで囲んだ場合は、エスケープシーケンスを解釈することができます。また「#{ }」で囲むことで、式展開を行うことができます。
irb(main):001:0> puts "Hello\nRuby\tWorld" #エスケープシーケンスを解釈
Hello
Ruby World
=> nil
irb(main):002:0> puts 'Hello\nRuby\tWorld' #エスケープシーケンスのまま
Hello\nRuby\tWorld
=> nil
irb(main):003:0> "2 + 3 = #{2 + 3}" #式展開も可能
=> "2 + 3 = 5"
複数行に渡る長い文字列オブジェクトの生成には、ヒアドキュメントを使います。「<<識別子」を含む行の次の行から「識別子」だけの行の直前までを文字列とします。
irb(main):001:0> s = <<EOB #<<EOBの下からEOBの上までが一つの文字列
irb(main):002:0" Hello
irb(main):003:0" Ruby
irb(main):004:0" World
irb(main):005:0" EOB
=> "Hello\nRuby\nWorld\n"
irb(main):006:0> puts s
Hello
Ruby
World
=> nil
次に文字列を操作するメソッドや演算子(これもメソッド)について説明します。メソッドの中には、メソッドの後ろに「!」を付けて破壊的メソッドとなるものがあります(たとえばchomp!やsub!やupcase!など)。破壊的メソッドとは元のオブジェクトを書き換えるものです。詳しくはマニュアルを参照してください。
まずは文字列の分割と連結、繰り返しについて説明します。
irb(main):001:0> s1 = "Matsue, Shimane, Japan"
=> "Matsue, Shimane, Japan"
irb(main):002:0> s1.split(",") #文字列をカンマで分割して配列に変換
=> ["Matsue", " Shimane", " Japan"]
irb(main):003:0> s2 = "Hello"
=> "Hello"
irb(main):004:0> s3 = "Ruby"
=> "Ruby"
irb(main):005:0> s2 + s3 #文字列同士を結合
=> "HelloRuby"
irb(main):006:0> puts s2 #+での結合は元の文字列は変えない(非破壊的)
Hello
=> nil
irb(main):007:0> s2 << s3 #文字列同士の結合
=> "HelloRuby"
irb(main):008:0> puts s2 #<<での結合は元の文字列を変える(破壊的)
HelloRuby
=> nil
irb(main):009:0> s3 * 3 #文字列を繰り返し
=> "RubyRubyRuby"
部分文字列を取得する際は、[ ]に始点のインデックスと長さを指定します。インデックスは先頭が0です。負の数を指定すると末尾から先頭に向かって数えるインデックスとなります。[ ]に範囲オブジェクトを指定することもできます。
irb(main):001:0> s = "Hello Ruby World"
=> "Hello Ruby World"
irb(main):002:0> puts s[0,5] #0番目より5文字の部分配列
Hello
=> nil
irb(main):003:0> puts s[6,4]
Ruby
=> nil
irb(main):004:0> puts s[-5,5] #-5番目(=11番目)より5文字の部分配列
World
=> nil
irb(main):005:0> puts s[0..4] #「..」(ドット2つ)は両端を含む連続した範囲
Hello
=> nil
irb(main):006:0> puts s[0...4] #「...」(ドット3つ)は右端を含まない範囲
Hell
=> nil
irb(main):007:0> s[0,5] = "HELLO" #部分文字列に代入して文字列を置換
=> "HELLO"
irb(main):008:0> puts s
HELLO Ruby World
=> nil
文字列の検索や置換もできます。
irb(main):001:0> s = "abcabcabc"
=> "abcabcabc"
irb(main):002:0> s.index("cab") #引数の文字列が初めて現れる場所の先頭
=> 2
irb(main):003:0> s.rindex("cab") #引数の文字列が最後に現れる場所の先頭
=> 5
irb(main):004:0> s.sub("cab","z") #初めて見つかった文字列を置換
=> "abzcabc"
irb(main):005:0> s.gsub("cab","z") #見つかった文字列全てを置換
=> "abzzc"
文字の削除もできます。また、文末の文字の削除に特化したメソッドも用意されています。
irb(main):001:0> "abcabcabc".delete("bc") #引数の文字列を削除
=> "aaa"
irb(main):002:0> "abc123".delete("a-z") #範囲を指定して削除
=> "123"
irb(main):003:0> "abc".chop #chopは文末の1文字を削除
=> "ab"
irb(main):004:0> "abc\n".chop #改行も削除可能
=> "abc"
irb(main):005:0> "abc\r\n".chop #「\r\n」の改行も同様に削除
=> "abc"
irb(main):006:0> "abc\n".chomp #chompは文末の改行を削除
=> "abc"
irb(main):007:0> "abc".chomp #文末に改行がない場合は削除せず
=> "abc"
irb(main):008:0> "abc\n\n\n".chomp("") #引数が空文字なら改行を全て削除
=> "abc"
この他に頻繁に使うメソッドとして以下のようなものがあります。
irb(main):001:0> "abc".length #文字列の長さ
=> 3
irb(main):002:0> "abc".upcase #大文字に変換
=> "ABC"
irb(main):003:0> "ABC".downcase #小文字に変換
=> "abc"
irb(main):004:0> "abc".reverse #文字の順序を逆転
=> "cba"
irb(main):005:0> " abc ".strip #前後のスペースを削除
=> "abc"
irb(main):006:0> "123".to_i #整数に変換
=> 123
irb(main):007:0> "123".to_f #浮動小数点数に変換
=> 123.0
続いて、他のデータ型である配列、ハッシュ、時刻のデータ型について説明します。