今日の教科書
メソッド
#メソッド
##メモ
###メソッドとは&メソッド呼び出し
def <メソッド名>
<オブジェクトの手続きにしたい処理>
end
オブジェクトを操作する手続きのことをメソッドと呼びます。キーワードのdefを使うことによって、そのオブジェクトに手続きを追加できます。
オブジェクトはデータとそのデータに対する手続きがひとつになったものでした。オブジェクトに手続きをおこなうように頼むことが、他の人に仕事を頼む様子に似ていることから「メッセージパッシング」と呼びます。
つまりメソッド呼出しをおこなう時は、オブジェクトへメッセージを送り、そのメッセージを受け取ったオブジェクトはメッセージに対応する処理をおこないます。メソッド名のメッセージを受け取ったオブジェクトは、そのメッセージに対応した処理を知っていればおこないますが、知らない時はエラーになります。このようなメッセージに対応する処理のことをメソッドと呼びます。
また、メッセージを受け取るオブジェクトのことをレシーバと呼びます。以下のような「レシーバ.メソッド名」や「レシーバ::メソッド名」の形でもメソッドを呼び出せます。
レシーバ.メソッド名
レシーバ::メソッド名
レシーバを書くことによって、メッセージを送るオブジェクトを指定しています。
###関数的メソッド
これまでの引数を端末へ表示するのに使ったメソッドなどは、レシーバがないので何かのオブジェクトへメッセージを送っているようには見えません。
print("foo") puts("bar") p "baz"
実は、これらのメソッドも同じようにオブジェクトがメッセージを受け取ってからメソッドを実行しています。これらのメソッドはレシーバを省略する形でしか呼び出せません。
ただし、省略されているだけで実際にはオブジェクトから呼び出されています。
なぜレシーバを省略する形でしか呼び出せないのでしょうか。それはレシーバにオブジェクトを指定しないでメソッドを呼び出すということは、どのオブジェクトでも呼び出せて、同じような動きをすることが期待されているからです。
###名前付き引数としてのハッシュ
メソッドを呼び出す時は正しい順番で引数を指定しないといけません。メソッドの引数が多くなってくると、引数の正しい順番を覚えておいてメソッドを呼び出すのは難しくなります。そのような時に他の言語では仮引数という機能を使うことで、メソッドの引数の順番を覚えておかなくてもよくなります。
Rubyでは仮引数名を指定してメソッド呼出しをする機能をサポートしていません。
ただし、メソッドの引数にハッシュオブジェクトを指定することによって、似たような機能をメソッドに持たせることができます。キーを名前のように使うことによって、キーに指定した引数へ値を渡すことができます。
def cubage(args)
# デフォルト値の設定
x = args[:x] || 10
y = args[:y] || 10
h = args[:h] || 10
return x * y * h
end
p cubage(:h => 100) #=> 10000
- ハッシュオブジェクトをメソッドの最後に指定するなら囲む{}はなくてもいい。
- キーと値だけでメソッドの引数に指定することができる。
###ブロック付きメソッド呼び出し
####yield
ブロック付きメソッド呼び出しの時にyield
が中にあるとブロックの中に処理を移し、
ブロックの処理を全て行ってから、メソッドに戻りyieldの下から処理を行う。
ブロックはdo~endや{}で囲まれた処理のこと。
def show
puts "Enjoy!"
end
show { puts "Programming!" } #=> Enjoy!
def show
puts "Enjoy!"
yield
end
show { puts "Programming!" } #=> Enjoy! Programming!
メソッドからブロックへの移動を2回行うこともできる。
def double
yield
yield
end
double { puts "Two" }
yieldの引数として式を指定することでブロックパラメータにもなる
def foo
yield "Hello!", "Enjoy", 42 + 23
end
foo {|x, y, z| puts x, y, z }
###メソッドの別名
メソッドは複数の名前を持つことができ、aliasを使って新しい名前をつける。
def hello
puts("Hello!")
end
alias new_hello hello
new_hello
別名を与えることでメソッドの拡張ができる。元の機能を別名で残しておき、新しい機能を新しい名前で定義する。
複数の名前をメソッドは持てる。複数の名前を持たせてから既存だけ拡張し、元のメソッドの機能を残すことができる。ただし、異なるメソッドが同じ名前を持つことはできない。
####演算子メソッド
[]
は文法ではなく実はメソッド。演算子はメソッド呼び出しの形でも使える。
p 10.+(20) #=> 30
配列オブジェクトに要素を加える際も[]=をメソッドとして使える。
()内の先頭の引数をインデックスの位置として後ろの引数を加える。
ary = []
# 第1引数がインデックスの指定で、第2引数が代入する値
p ary.[]=(1, 10) #=> [nil, 10]
p ary.[](1) #=> 10