2008年9月29日月曜日

初めてのRuby(7)

第7章 メソッド
 
 メソッドとは、オブジェクトに対するメッセージ送信
 その他、関数的メソッドもある。

 メソッド呼び出し レシーバ.メソッド名(引数)
         a.some_method(1, "str")
a::some_method(1, "str") どっちも可。
 
 メソッド連鎖 メソッドの戻り値に対してメソッドを呼ぶ(適用する)
    escaped_str = str.gsub(/&/, '&').gsub(/</, '<').gsub(/>/, '>')

 レシーバの省略 → デフォルトのレシーバであるselfに対してメソッドを呼び出す。
  (p selfで確認)

 引数を持たないメソッドのレシーバを省略すると、ローカル変数の参照と見分けがつかないが、この場合はローカル変数が優先。

 関数的メソッド p Math.sin など
 組み込み関数 puts p

 メソッドの定義
  返値は最後の評価値 、return 式では、その値。returnだけだと、nilが返る。

 多値の返却
  def some_method(a)
return a, 1, 2, 3
end
a, b, *c = *some_method(0)

def some_method(a)
[a, 1, 2, 3]
end

C言語におけるvoidのように値を返さないメソッドはない。返値に使い道がないメソッドの実装では最後にnilを書く人もいる。

  
 デフォルト値
   def some_method(a, b, c = 1) # cは省略可能。デフォルト値は1
end

 デフォルト値の算出に式が用いられている場合、毎回その式を評価。
  def print_time(time = Time.now)
p time
end

 可変長引数
  def some_method(a, b, *c)
p [a, b, c]
end

some_method(1,2,3,4,5) #=> [1,2,[3,4,5]]

  クロージャーとしてのブロック
   ブロック中の自由変数はブロックの外部環境に従う。

 ブロックローカル変数
 last_odd = nil
(1..10).each do |i|
last_odd = i if i%2 != 0
end
p last_odd #=> 9

 ブロック付きのメソッドの定義
  yield式は、メソッド内から呼び出し側のブロックをコールバックする構文。式の値をブロック呼び出し時にブロック引数として渡す。

 def foo_bar_baz
yield "foo"
yield "bar"
yield "baz"
end
foo_bar_baz do |item|
puts item
end

 他のブロック付きメソッドを利用してブロック付きメソッドを実装することもよくある。
 def foo_bar_baz2
%w[ foo bar baz ].each do |item|
yield item
end
end

yield式はブロックの評価値を返すので、mapもどきを実装できる。
 def my_map
[yeild(1), yield(2), yeild(3)]
end
p my_map {|i| i+1} #=>[2,3,4]
  
 呼び出し側のブロックをオブジェクトして取得するには、仮引数リストの最後に&で修飾された引数を置く。この引数に、呼び出し側のブロックを表すProcオブジェクトが格納される。

 class SleepyPerson
def register_handler(&handler)
@event_handler = handler
end
def wake_up!
@event_handler.call Time.now, "woke up"
end
john = SleepyPerson.new
john.register_handler {|time, message| p [time, message]}
john.wake_up!
ブロックは環境を保存するので、ブロックをProc化してためておき、後で使う。

  Procオブジェクトをブロック付きメソッドに渡す。
  proc = Proc.new { puts "Proc was called" }
3.times(&proc)
#=> Proc was called
Proc was called
Proc was called


 

0 件のコメント: