Help us understand the problem. What is going on with this article?

AdventCalendar Day10 [超Ruby入門]

More than 1 year has passed since last update.

はじめに

本記事は、超Ruby入門10日目の記事です。

コメント頂ける方は、ガイドラインを読んで頂けると幸いです。

本題

%w[Ruby, Python, PHP].map { |str| str.length }

map { } というコードを見たことはないだろうか。

p Enumerator.method_defined?(:map)
> true

mapはEnumeratorオブジェクトのメソッドだ。

各要素に対してブロックを評価した結果を全て含む配列を返します。
ブロックを省略した場合、上で説明した繰り返しを実行し、その結果として 得られる配列を返すような Enumerator オブジェクトを返します。Enumerableモジュール

ブロックとは何なのだろうか?

ループを構成したり、家や塀を建てたり、人を殴ったりするもの。
Ruby用語集

block.jpg

ブロックは、Rubyで最も利用する構文だ。

さてここで問題だ。

以下コードのどこにブロックが隠れているだろうか。

%w[Ruby, Python, PHP].map { |str| str.length }

正解は、{ } の部分だ。

{ |str| str.length }

ブロックはブロック付きメソッド呼び出し(イテレータ)と共によく利用される。

イテレータの文法が複数存在することをご存知だろうか?

method(arg1, arg2, ...)  do [`|' 式 ... `|'] 式 ... end
method(arg1, arg2, ...) `{' [`|' 式 ... `|'] 式 ... `}'
method(arg1, arg2, ..., `&' proc_object)

上記のように3つの文法がある。今まで見たのは真ん中の文法だ。

ブロック構文{}の代わりにdo ~ endを使うと下記コードとなる。

%w["Ruby", "Python", "PHP"].map do |str|
    str.length
end

イテレータはループのようにみえる。

ループと言えば、for構文を思い浮かべるのではないだろうか?

では、for構文とイテレータの差異を調べてみよう。

# for
for i in [1, 2, 3, 4, 5]
    for_last = i
end
puts "for #{for_last}"

# iterator
[1, 2, 3, 4, 5].each do | num |
    last = num
end
puts "iterator #{last}"

上記コードを実行するとイテレータがエラーとなる。

そう!for構文とイテレータではスコープが違うのだ。

ブロックは新しいローカル変数を持つが、 for文はローカル変数のスコープに影響を及ぼさない。

もう、mapが何を行なっているのか理解できたのではないだろうか?

%w[Ruby, Python, PHP].map { |str| str.length }

mapメソッドをクリアして疲れた頃だろうか。

大丈夫、次が最後だ。yieldのついてみていこう。

ああ、読み方か。イールドだ。

yieldは、自分で定義したイテレータでブロックを呼び出す時に使う。

わけがわからないので、コードをみよう。

def check_yield
    yield
end

check_yield { puts "pass check_yield" }

check_yieldメソッドを呼び出すとyieldはブロックを呼び出している。

次に、yieldに引数を渡してみよう。

def check_yield_argvs
    yield(1)
end

puts check_yield_argvs { | x | x + 2 }

yield(1)の1はどこに代入されるのだろうか。

正解は、ブロックパラメータだ。

check_yield_argvs { | block_parameter | x + 2 }

ブロックの説明は以上!

時間があるできた時にやること

yield(self)

imaharu
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away