RubyのRangeクラスと範囲オブジェクト、範囲演算子、イテレーターの使い方:若手エンジニア/初心者のためのRuby 2.1入門(4)(3/3 ページ)
オープンソースのオブジェクト指向プログラミング言語「Ruby」の文法を一から学ぶための入門連載。最新版の2.1に対応しています。今回は、範囲オブジェクトを扱うRangeや範囲演算子の基本操作、各メソッドの使い方、イテレーターの基礎的な使い方に加え、イテレーターを使う利点などを解説します
Rubyのイテレーターの基本的な使い方
ArrayやHashなどのコンテナーやRangeといった範囲オブジェクトを使っていると、含まれている要素1つ1つに対して、何らかの処理を行いたい場合があります。このようなコンテナーの各要素に対する繰り返しの処理を、概念的に「イテレーター」と呼びます。
少し込み入った話をすると、ArrayやHashは「Enumerable」というモジュールをミックスインすることによってイテレーターを実現する種々のメソッドを実装しています。ミックスインについては、以降の連載のクラスやモジュールを解説する回で説明します。
基本的な繰り返し(eachメソッド)
ArrayオブジェクトにおいてもHashオブジェクトにおいても、要素を1つずつ取り出しながら処理するためのメソッドである「each」を使えます。array01.rbに配列から要素を順に取り出して表示するサンプルコードを示します。
["alice", "in", "wonderland"].each do |term| puts term end
$ ruby array_01.rb alice in wonderland
「do |term| 〜 end」の一塊を「ブロック」と呼び、ブロックには一連の処理を含めることができます。ブロックはメソッドに与える引数の1つで、通常の引数のようにデータそのものを渡すのではなく、「一連の処理そのもの」を渡すと考えると理解しやすいと思います。
この例では、配列「["alice", "in", "wonderland"]」から1つずつ要素が取り出され、変数termに格納されます。この変数名は自由に付けることができるので、必ずtermである必要はありません。termに格納されたオブジェクトは自由に操作できます。
ここでは、単純にtermの内容をputsメソッドで画面に表示しています。
Hashオブジェクトにおいても、同様にeachメソッドが使えます。ただし、こちらはキーとキーに関連付けられたオブジェクトの2つの変数が必要になるので、ブロックの変数を指定する部分が「|key, value|」となっています。
{jack: 11, queen: 12, king: 13}.each do |key, value| puts "key: #{key}, value: #{value}" end
key: jack, value: 11 key: queen, value: 12 key: king, value: 13
インデックス付きの繰り返し(each_with_indexメソッド)
each_with_indexメソッドを使うと、繰り返しごとに1回ずつカウントアップされるインデックスを使えるようになります。
["alice", "in", "wonderland"].each_with_index do |term, index| puts "#{index}: #{term}" end
$ ruby array02.rb 0: alice 1: in 2: wonderland
逆順で繰り返す(reverse_eachメソッド)
reverse_eachメソッドを使うと、逆順に要素を1つずつ取り出しながら処理を行えます。array03.rbは、そのサンプルコードです。
["alice", "in", "wonderland"].reverse_each do |term| puts term end
$ ruby array03.rb wonderland in alice
ここまで最も基本的なイテレーターを紹介しましたが、実はまだまだ関数型言語由来の便利なメソッドが豊富にあります。eachは汎用性が高く使いやすいのですが、記述が冗長になりがちです。「map」「inject」「select」「reject」「all?」といったメソッドを使いこなすことで、eachをなるべく使わずに簡潔なコードを書くことができます。
これらのメソッドについては、以降の連載のブロックやクロージャの回で紹介する予定です。
補足「イテレーターを使うと何が便利なのか」
Rangeクラスの解説での補足で、多くのRubyプログラマーはイテレーターの概念を使うことを好むと書きました。ここでは、その理由について説明します。
例えば、イテレーターという概念のないC言語で、配列の内容1つずつを画面に出力するようなコードは以下のようになります。
#include <stdio.h> #define LENGTH 10 int main(void) { int array[LENGTH] = {0}; /* 配列のインデックスと等しい値を要素として代入 */ for (i = 0; i < LENGTH; i++) { array[i] = i; } /* 標準出力に出力 */ for (i = 0; i < LENGTH; i++) { printf("%d\n", array[i]); } return 0; }
このような場合、C言語ではfor文を用いてループを回すやり方が定石ですが、このfor文が「全ての要素に対して処理を行っている」という事実は、ループの中身を見ないことには分かりません。このように、画面に出力する、代入するといった単純な処理ならば問題となりませんが、ループの中身が大きくなったり、構造体を使う場合には大変読みづらくなってしまいます。
イテレーターとは、プログラミングでほぼ必ず遭遇する「全ての要素に対する処理」という動作そのものを抽象化し、人間が読みやすいプログラムにするための、一歩進んだループの概念なのです。このような優れた仕組みが存在するのだから、それを使わない手はありません。
次回は、日付と時刻、数値を扱うクラス
今回は、Rubyの組み込みライブラリの紹介の続きということで、範囲を表現するためのRangeクラスと、配列やハッシュ、範囲オブジェクトに深く関わるイテレーターという概念について説明しました。
次回は日付と時刻を表すTimeクラスと、数値を扱うための種々のクラスについて深く掘り下げていく予定です。お楽しみに!
- Rubyで逆ポーランド変換機を作りgem作成&コマンドの使い方
- 難しいが強力! Rubyのメタプログラミング、self、特異クラス/メソッド、オープンクラスとモンキーパッチ
- RubyのThread、Fiber、Kernel、forkで並列処理やプロセスの深淵へ
- RubyのFile/IOクラスで入力と出力、ファイルの読み取りと書き込み、フィルター作成
- Rubyの例外とその捕捉――基本のbegin〜rescue〜endからensure、else、retry、後置rescueまで
- Rubyの面白さを理解するためのメソッド、ブロック、Proc、lambda、クロージャの基本
- Rubyのオブジェクト指向におけるクラスとモジュール、継承、Mixin、アクセス制御の使い方
- RubyのNumericとTimeで数値と時間をさまざまな操作・演算・判定
- RubyのString/Regexpクラスによる強力な文字列操作/正規表現
- RubyのRangeクラスと範囲オブジェクト、範囲演算子、イテレーターの使い方
- Rubyの配列、ハッシュテーブルを表現するArray、Hashクラスの使い方
- Ruby 2.1の基本構文/基本文法まとめ&Pryの使い方
- Rubyプログラミングを始めるための基礎知識とインストール
著者プロフィール
麻田 優真(Rails技術者認定シルバー試験問題作成者)
イタリア、ローマ生まれ。中学生のころHSPに初めて触れ、プログラミングの楽しさを知る。オープンソースやハッカーカルチャーを好む。C#からRubyに転向したときに、動的型付け言語の柔軟性やメタプログラミングの魅力に感動し、Rubyとともにプログラマーとしての人生を歩む決意を固める。
現在は奈良先端科学技術大学院大学で学生として所属するかたわら、株式会社アジャイルウェアでプログラマーとして従事。Ruby on Railsによるコンシューマー向けのWebサービスの開発などに尽力している。
好きなメソッドは、define_method。
Twitter:@Mozamimy、ブログ:http://blog.quellencode.org/
監修者プロフィール
山根 剛司(Ruby業務開発歴7年)
兵庫県生まれ。1997年からベンチャー系のパッケージベンダーで10年間勤務。当時、使用していた言語はJavaとサーバーサイドJavaScript。
2007年よりITコンサル会社に転職し、Rubyと出会って衝撃を受ける。基幹システムをRuby on Railsで置き換えるプロジェクトに従事。それ以来Ruby一筋で、Ruby on Railsのプラグインやgemも開発。
2013年より、株式会社アジャイルウェアに所属。アジャイルな手法で、Ruby on Railsを使って企業向けシステムを構築する業務に従事。
Ruby関西所属。
Twitter:@spring_kuma、Facebook:山根 剛司
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- 3万5000円の参加費でも内外から580人の参加登録:公用語に英語、「再起動」したRubyKaigi 2013が東京で開催
いったん終了していたRubyコミュニティ主催の年次イベントが再開。技術色、国際色を強め、盛況のうちに幕を閉じた - IT業界 転職市場最前線(48):Web業界、今から行くならRubyエンジニアが狙い目?
不況で冷え込んでいたIT業界の転職市場に、回復の兆しが見え始めている。だが、業種や職種によって採用数や条件に大きな差異が生まれている。転職市場の動向を追い、自身のキャリア戦略立案に生かしてほしい。 - 安定版のメジャーバージョンアップ:Ruby 2.0.0がリリース、大規模化対応の機能などを搭載
生誕20年となる節目を迎えて、プログラミング言語「Ruby」の最新版がリリースされた - 新バージョンで何が変わるのか、Rubyはどこへ向かうのか:まつもと×笹田、Ruby 1.9を語る
- いよいよ始まるRuby 1.9への移行:開発コアメンバが語るRubyの今とこれから(前編)
- Rubyの今後の進化の方向性とは?:開発コアメンバが語るRubyの今とこれから(後編)
- 互換性や脆弱性の問題にどう対応していくのか:Rubyが抱える課題、NaClの前田氏が講演
- Rails Hub情報局:「なんでRubyなんか作った!? 迷惑だ!」に対するMatzの答え
- Rails Hub情報局:Rubyはイノベーション言語として選ばれている
- Rails Hub情報局:Rubyのまつもと氏は、一発屋で終わるのか?
- Rails Hub情報局:Rubyに魔法は要らない
- 数々の“スペル”で高度なプログラミング:Rubyの魔術
- 晴読雨読@エンジニアライフ:『たのしい開発 スタートアップRuby』――なぜRubyistたちはあれほど楽しそうなのか
- Ruby 1.9.3に対応:「JRuby 1.7.0」登場、1年半ぶりのメジャーアップデート
JavaVM上のRuby実装「JRuby」の最新版となる「JRuby 1.7.0」が、10月22日にリリースされた。