名前はまだない。

プログラミングのことや趣味のことに関して綴ります。

Rubyの基本シンタックスまとめてみた~Part 3~

Rubyの基本シンタックスまとめてみた、最終パート(多分)です。 前回の記事はこちらを御覧ください。

ブロック、Proc、yield

ブロック
hoge do |n|
  p n
end
hoge { |n| p n }
Proc・lambda

ブロックのオブジェクト。

hoge1 = Proc.new { |n| p n }
hoge2 = proc { |n| p n }
hoge3 = lambda { |n| p n }
hoge4 = ->(n) { p n }
hoge5 = -> { p 'hogehoge' }

hoge1.call('hoge') #=> hoge
hoge2.call('hogehoge') #=> hogehoge
hoge3.call('piyo') #=> piyo
hoge4.call('piyopiyo') #=> piyopiyo
hoge5.call #=> hogehoge
def hoge
  procedure = Proc.new { return 'return from Proc.new' }
  procedure.call
  return 'return from hoge'
end

def piyo
  procedure = lambda { return 'return from lambda' }
  procedure.call
  return 'return from piyo'
end

p hoge #=> return from Proc.new
p piyo #=> return from piyo
yield(イールド)

ブロックを実行。
なんだかブロックがコールバックみたいに見える。

def hoge
  yield
end

hoge { p 'hoge' } #=> hoge
def hoge(num, msg, count)
  count.times do
    yield(num, msg)
    num += 1
  end
end

hoge(0, 'koba', 2) { |n, msg| p "#{n}_#{msg}" } #=> 0_koba 1_koba

クロージャ

コレに関しては少し説明を。 そもそも"クロージャ"って何ぞや?という点ですが、
クロージャとは、ある関数が作られた時にその状態(環境)が関数内で保持されるということです。

元々クロージャErlangHaskellといった関数型言語で扱われていた概念で、
ローカル変数の内容等を関数外に伝えるための機構です。
Rubyクロージャを実現するためには先程挙げたProcやlambdaを使用します。

例として下記を御覧ください。

def hoge
  n = 0
  closure = -> { n += 1 }
end
hogehoge = hoge
p hogehoge.call #=> 1 
p hogehoge.call #=> 2
p hogehoge.call #=> 3

メソッドhogeを一度hogehogeに格納している理由としては
hoge.callしてしまうとProcオブジェクトが再定義されて生成されてしまうため、
そのProcオブジェクトの状態を保つために別インスタンスにぶち込んで再定義されないようにしてるからなのです。

そしてこの挙動。
インスタンス変数の扱いに似ていると思いません?

class Foo
  def initialize
    @n = 0
  end

  def add
    @n += 1
  end
end

foo = Foo.new
p foo.add #=> 1
p foo.add #=> 2
p foo.add #=> 3

まさに、ローカル変数をインスタンス変数のように扱えちゃうというなかなかファンキーなやつ!
それがClosure(クロージャ)なのです!

正規表現

pattern = /こばけん/
p 'こばけんこばけん'.sub(pattern, 'コバケン') #=> コバケンこばけん
p 'こばけんこばけん'.gsub(pattern, 'コバケン') #=> コバケンコバケン
p 'こばけんkobakenコバケン'.match(pattern)[0] #=> こばけん
p 'こばけんkobakenコバケン'.match(/hoge/)[0] #=> nil
p '僕の名前はkobakenです。'.match(/僕の名前は(.+)です。/)[1] #=> kobaken

その他、こちらのサイトが良くまとまっています(他人任せ)↓

qiita.com

今回はここまで。
要望があったらまたまとめたいと思います。
ではノシ

参考サイト

www.atmarkit.co.jp

Rubyのブロック(クロージャ)はローカル変数をインスタンス変数に変えるマジックだ!