プログラミング言語Ruby 1章 イントロダクション

イディオム

かっこは多くの場合省略可能で、特に呼びだそうとしているメソッドが引数を取らない場合には省略するのが普通

1.class
true.class
nil.class

ブロックとイテレータ

3.times { print "Ruby! " }
1.upto(9) {|x| print x }

timesやuptoはイテレータ(iterators)と呼ばれる特殊なメソッドの一種で、繰り返しのような動作をする。
中かっこ({})で囲まれたコードはブロックと呼ばれ、イテレータメソッド呼び出しに付属しており、繰り返しの本体となる。
Rubyは通常のwhileループもサポートしているが、繰り返しの実行には、実際にはメソッド呼び出しであるこれらの方法を使うことのほうが多い。

配列(ArrayおよびEnumerableオブジェクト)は、eachというイテレータを定義している。
これは配列内の個々の要素について一度ずつ付属ブロックを実行する。
ブロックの毎回の実行には、配列の1個の要素が渡される。

a = [1, 2, 3]
a.each do |elt|
  print elt + 1
end

ハッシュ(Hash)もeachメソッドを定義している。ブロックに引数としてキーと値の両方を渡す。

h = {:one => 1, :two => 2, :three => 3}
h.each do |key, value|
  print "#{value}:#{key}"
end

ハッシュのキーでもっともよく使われるのはSymbolオブジェクト。(:one とかのやつ)

その他のブロックを使った処理の例

File.open("data.txt") do |f|
  line = f.readline
end

式展開

print "#{value}:#{key}"

ダブルクォートで囲まれた文字列は、#{と}というセパレータで囲まれた任意のRuby式を組み込むことができ、
セパレータ中の式の値は文字列に変換される。

式と演算子

Rubyの構文は式を重視したものになっている。ifなどの制御構造は、他の言語なら文と呼ぶところだが、Rubyでは式である。
制御構造も、もっと単純な式と同じように値を持っているので、次のようなコードが書ける。

minimum = if x < y then x else y end

メソッド

  • メソッドの戻り値はメソッドの本体の中で最後に評価された式の値
  • メソッド名の前にプレフィックスとしてオブジェクト名を付けると、個々のオブジェクトのメソッドを定義できる
    • 特異メソッドという。Rubyではこの方法でクラスメソッドを定義する

代入

多重代入
x,y,z = [1,2,3]

>> x
=> 1
>> y
=> 2
>> z
=> 3

で、

def polar(x,y)
  theta = Math.atan2(y,x)
  r = Math.hypot(x,y)
  [r,theta]
end

# 呼び出し元
distance, angle = polar(2,2)

というような使い方が便利。

名前の最後がイコール(=)になっているメソッドは代入の構文で呼び出せる。
オブジェクトoがメソッドx=というメソッド名を持っているとき、

o.x=(1)
o.x = 1

は同じ。

プレフィックスとサフィックス

メソッド
  • 末に
    • ? がある。true、falseを返すメソッド(でいいか?)
    • ! がある。インスタンスの内容を変更するメソッド
変数

正規表現と範囲

リテラルで表現できる。

正規表現
/[Rr]uby/ # "Ruby" か "ruby" にマッチする
/\d{5}/   # 5個連続した数字にマッチする
範囲
1..3  # 1 <= x <= 3 を満たすすべてのx
1...3 # 1 <= x < 3 を満たすすべてのx
case等値演算子(===)
# 生年に基づいて米国での世代名を判定する
# case式は === で範囲をテストする
generation = case birthyear
             when 1946..1963; "Baby Boomer"
             when 1964..1976; "Generation X"
             when 1978..2000; "Generation Y"
             else nil
             end
# ユーザに何かを確かめるためのメソッド
def are_you_sure?
  while true
    print "よろしいですか? [y/n]:"
    response = gets
    case response
    when /^[yY]/
      return true
    when /^[nN]/, /^$/
      return false
    end
  end
end

気をつける点

Rubyの文字列はミュータブル

<<演算子で文字列に追加できたり。
freezeメソッドを使えばそのオブジェクトに新たな変更を加えることは出来なくなる。

nil は false その他は true

0 や "" もtrue扱い。

ri

Rubyのドキュメントを表示する。

ri クラス名
ri クラス名.メソッド名
ri クラス名#インスタンスメソッド名
ri クラス名::クラスメソッド名

ri Array

----------------------------------------------------------- Class: Array
     Arrays are ordered, integer-indexed collections of any object.
     Array indexing starts at 0, as in C or Java. A negative index is
     assumed to be relative to the end of the array---that is, an index
     of -1 indicates the last element of the array, -2 is the next to
     last element in the array, and so on.

------------------------------------------------------------------------


Includes:
---------
     Enumerable(all?, any?, collect, count, cycle, detect, drop,
     drop_while, each_cons, each_slice, each_with_index,
     each_with_object, entries, enum_cons, enum_slice, enum_with_index,
     find, find_all, find_index, first, grep, group_by, include?,
     index_by, inject, many?, map, max, max_by, member?, min, min_by,
     minmax, minmax_by, none?, one?, partition, reduce, reject,
     reverse_each, select, sort, sort_by, sum, take, take_while, to_a,
     to_set, zip)


Class methods:
--------------
     [], new


Instance methods:
-----------------
     &, *, +, -, <<, <=>, ==, [], []=, abbrev, assoc, at, choice, clear,
     collect, collect!, combination, compact, compact!, concat, count,
     cycle, dclone, delete, delete_at, delete_if, drop, drop_while,
     each, each_index, empty?, eql?, fetch, fill, find_index, first,
     flatten, flatten!, frozen?, hash, include?, index, indexes,
     indices, initialize_copy, insert, inspect, join, last, length, map,
     map!, nitems, pack, permutation, pop, pretty_print,
     pretty_print_cycle, product, push, rassoc, reject, reject!,
     replace, reverse, reverse!, reverse_each, rindex, select,
     shelljoin, shift, shuffle, shuffle!, size, slice, slice!, sort,
     sort!, take, take_while, to_a, to_ary, to_s, to_yaml, transpose,
     uniq, uniq!, unshift, values_at, yaml_initialize, zip, |
(END)

RubyGems

Rubyのパッケージ管理システム。RubyGemsを使って配布されるパッケージやモジュールは「gem」と呼ばれている。
Ruby1.9からは標準配布物でgemコマンドが使える。

gem
gem list             # インストールされているgemのリストを表示する
gem enviroment       # RubyGemsの設定情報を表示する
gem update rails     # 指定されたgemをアップデートする
gem update           # インストールされているすべてのgemをアップデートする
gem update --system  # RubyGems自体をアップデートする
gem uninstall rails  # インストールされているgemを削除する
注意点

Ruby1.8ではインストールしたgemを使うプログラムを書く場合、まずrubygemsモジュールをrequireする必要がある。
rubygemsをロードするとrequireメソッド自体が変わり、標準ライブラリを検索する前にインストールされているgemの検索をする。
requireでgemをロードすると、1,8、1.9どちらでも、インストールされたgemの最新バージョンがロードされる。
特定のバージョンをロードしたい場合にはrequireを呼び出す前にgemメソッドを呼び出す。

require 'rubygems'                # Ruby1.9では不要
gem 'RedCloth', '> 2.0', '< 4.0'  # RedCloth ver.2.x または ver.3.x をアクティベート
require 'RedCloth'                # アクティベートしたgemをロード

その他チュートリアルについて