0Pricing
Ruby Academy · レッスン

カスタム each の記述

反復処理を実装します。

「カスタム each の記述」はCoddyKit上の無料Ruby Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはRuby Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Ruby Academyコースには全4レッスンが含まれています。

反復処理を実装する

Rubyの反復処理の中心となるメソッドはeachです。独自のeachを書くことで、コレクションをどのように走査するかを決め、反復処理のエコシステム全体を利用できるようになります。

class Trio
  def each
    yield 1
    yield 2
    yield 3
  end
end
Trio.new.each { |n| puts n }

each で値を yield する

eachの内部で、要素ごとに1回yieldを呼び出します。呼び出し元が渡したブロックは、各値を順番に受け取ります。

class Days
  NAMES = ["Mon", "Tue", "Wed"]
  def each
    NAMES.each { |d| yield d }
  end
end
Days.new.each { |day| puts day }

内部データを保持する

通常、eachはインスタンス変数に保持されたデータを走査します。

class Stack
  def initialize
    @items = []
  end
  def push(x); @items << x; self; end
  def each
    @items.each { |i| yield i }
  end
end
s = Stack.new
s.push(10).push(20)
s.each { |x| puts x }

独自の走査順序

独自のeachでは、たとえば逆順など、好きな順序で反復処理できます。

class Reversed
  def initialize(arr); @arr = arr; end
  def each
    i = @arr.length - 1
    while i >= 0
      yield @arr[i]
      i -= 1
    end
  end
end
Reversed.new([1, 2, 3]).each { |x| puts x }

複数の値を yield する

yieldでは複数の値を渡すことができ、ブロックはそれらを複数のパラメーターとして受け取ります。ハッシュのキーと値がその一例です。

class Pairs
  def each
    yield :a, 1
    yield :b, 2
  end
end
Pairs.new.each { |key, value| puts "#{key}=#{value}" }

each は self を返す

慣例として、eachは呼び出しをチェーンできるよう、コレクション自体を返します。eachからselfを返すと、組み込みの動作に合わせられます。

class Box
  def initialize(*x); @x = x; end
  def each
    @x.each { |i| yield i }
    self
  end
end
result = Box.new(1, 2).each { |i| }
puts result.class

block_given? を使う

ブロックがない場合に、単独で呼び出したeachがクラッシュしないよう対処します。多くの場合は、後で説明する Enumerator を返します。

class List
  def initialize(*x); @x = x; end
  def each
    return @x.to_enum unless block_given?
    @x.each { |i| yield i }
  end
end
puts List.new(5, 6).each.class

他のメソッドを動かす

eachが存在すれば、同じクラス内で、それを基盤として他のメソッドを構築できます。

class Numbers
  def initialize(*n); @n = n; end
  def each; @n.each { |i| yield i }; end
  def total
    sum = 0
    each { |i| sum += i }
    sum
  end
end
puts Numbers.new(1, 2, 3, 4).total

計算で生成するシーケンス

eachは何も保持する必要がなく、値をその場で生成することもできます。

class Evens
  def initialize(limit); @limit = limit; end
  def each
    n = 0
    while n <= @limit
      yield n
      n += 2
    end
  end
end
Evens.new(8).each { |x| puts x }

Enumerable の基盤

独自のeachは、Enumerableが必要とする唯一の構成要素です。次のレッスンではこれをインクルードし、数十種類以上のメソッドを無料で利用できるようにします。

class Range3
  def each
    (1..3).each { |n| yield n }
  end
end
Range3.new.each { |n| print n }
puts

まとめ

独自のeachを使うと、反復処理を完全に制御できます。

  • 要素ごとに1回yieldします。
  • 任意の順序で走査したり、値を生成したり、ペアを yield したりできます。
  • 慣例としてselfを返します。
class Countdown
  def initialize(from); @from = from; end
  def each
    @from.downto(1) { |n| yield n }
  end
end
Countdown.new(3).each { |n| puts n }

確認

独自の each についての理解度を確認しましょう。

振り返り

独自のeachの書き方を学びました。

  • yieldは要素を呼び出し元のブロックに渡します。
  • 走査順序を制御でき、値を生成することもできます。
  • 慣例としてselfを返します。
  • eachは Enumerable の基盤です。
class Squares
  def initialize(n); @n = n; end
  def each
    (1..@n).each { |i| yield i * i }
  end
end
Squares.new(4).each { |sq| puts sq }

よくある質問

「カスタム each の記述」レッスンは無料ですか?

はい。「カスタム each の記述」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Ruby Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Ruby Academyコースには全4レッスンが含まれています。

「カスタム each の記述」で何を学びますか?

反復処理を実装します。 ブラウザで直接実行するハンズオンコードでRuby Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Ruby Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのRuby Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「カスタム each の記述」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このRuby Academyレッスンでコードを書いて実行できますか?

はい。すべてのRuby Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. カスタム each の記述
  2. Enumerable のインクルード
  3. 遅延 Enumerator
  4. Enumerator オブジェクト
← Ruby Academyに戻る