昨日のブログで「イテレータ」について書いたが、
最近のRubyの世界ではそれを「ブロック付きメソッド」と呼ぶほうが好まれているようだ。
まず、「ブロック付きメソッド」の定義。
Ruby リファレンスマニュアル
「
ブロック付きメソッド呼び出し」
によると、
「ブロック付きメソッドとは制御構造の抽象化のために用いられる メソッドです。」
とある。
「最初はループの抽象化のために用いられていたため、 特にイテレータと呼ばれることもあります。」
この説明からも判るとおり、
もともと ループの抽象化を目的としていたので「イテレータ」と呼ばれていたようだが、
繰り返し処理でなく1度きりの処理であっても
制御構造を抽象化したい場合に、同様の記述が可能であるということから、
最近ではもっと汎用的に「ブロック付きメソッド呼び出し」と呼ぶようになっているようである。
では自分で定義したブロック付きメソッドから
引き渡されたブロックを呼び出す方法。
そのためには「yield」をメソッド定義内で記述する必要があるようだ。
詳しくは Ruby リファレンスマニュアルの
「
yield」
に解説してある。
この「yield」を含めた「ブロック付きメソッド呼び出し」の
私なりの理解の方法の例を挙げてみる。
def foo # メッソド foo の定義
fooprint(5)
end
def fooprint( i ) # メッソド fooprint の定義
p i+10
end
foo # メッソド foo を呼ぶ
def fooprint( i ) # メッソド fooprint の再定義
p i+20
end
foo # メッソド foo を再び呼ぶ
この例では、まず foo というメッソドを定義している。
この fooの中から fooprint というメッソドを引数「5」で呼び出すことにする。
次に、fooprint というメッソドを定義しており、
その処理内容は 引数「i」に「10」を足してから表示する、というもの。
その直後に メッソド「foo」を呼び出している。
続いて再び、メッソド「fooprint」を定義しなおしている。
その処理内容は 引数「i」に「20」を足してから表示する、というもの。
その直後に再び メッソド「foo」を呼び出している。
上の例を 「yield」を使った「ブロック付きメソッド呼び出し」で記述してみると
def foo
yield(5) # fooprint(5) の代わり
end
foo do |i| # do |i| は def fooprint( i ) の代わり
p i+10
end
foo do |i| # do |i| は def fooprint( i ) の代わり
p i+20
end
となる。
こちらの例では
ブロックをメッソド「foo」に直接 引数として渡しており、
前の例であった「fooprint」というメソッド定義がなくなっている。
上記2つのスクリプト例を実行してみると
15
25
となる。
自分としては、この様なイメージで
「ブロック付きメソッド呼び出し」を理解している。
【参考リンク】
カテゴリー:
Ruby
22:44
| コメント (0)
| トラックバック (0)
Ruby の解説記事などで 言語の特徴について書かれている場合、
必ずと言ってよいほど「イテレータ」という言葉にお目にかかる。
実は私も、Rubyについて調査・研究を始めるまで聞いたことがなかった。
それでは、「イテレータ」とはいったい何なのだろうか?
まずは英語のお勉強から。「イテレータ」は「iterator」であり、
その原型の動詞「iterate」とは「 〜を 繰り返す」という意味。
また、ウィキペディアでの
「
イテレータ」ページ
での定義を引用させてもらうと、
イテレータ(Iterator)とは、プログラミング言語において配列やそれに類似するデータ構造の各要素に対する繰返し処理の抽象化である。
実際のプログラミング言語では、オブジェクトまたは文法などとして現れる。
反復するためのものの意味で反復子(はんぷくし)と訳される。
となっている。
また、Rubyリファレンスマニュアル の「イテレータとは何ですか」では
イテレータは制御構造(特にループ)の抽象化のために用いられるメソッド の一種です。
と定義付けされている。
Rubyでも繰り返しの記述方法は何通りもあるが、
繰り返したいブロックをメッソドの引数として与える記述が可能である。
そのメソッドのことを「イテレータ」と呼んでいる。
では Rubyとしての「イテレータ」の具体例を挙げてみよう。
3.times do
print "A"
end
これは 整数クラスの「3」というオブジェクトの
「times」というメッソドに
「do ... end 」のブロックを引数として与えていることになる。
処理としてはこの場合、「do ... end 」のブロックを3回繰り返すことになる。
これを実行してみると、結果は
AAA
となる。
「do ... end 」のブロックの中へ
何回目の繰り返しかを 変数で引き渡す方法。
3.times do |i|
print i, " "
end
前述のスクリプト例との違いは、
ブロックの開始 do の直後に「 |i| 」という
このブロックへの引数を受け取るローカル変数「i」の定義があり、
ブロック内では このローカル変数「i」が参照されていること。
この実行結果は
0 1 2
となる。
また、配列の場合であれば、
data = [5, 10, 15]
data.each do |i|
print i, " "
end
というような記述になり、結果が
5 10 15
となる。
【参考リンク】
カテゴリー:
Ruby
22:13
| コメント (0)
| トラックバック (0)
今年5月からオフィスを開いていた東北大学米国代表オフィスであるが、
内装なども整ったということで、
オープンハウスの式典が この日 15:30 より 同事務所で行われた。
この式典は まずマスコミ関係者を集めての記者会見から始まった。
その後、所長の庄子哲雄教授を始め関係者からご挨拶があった。
オフィスにはおそらく100人を超える人が集まっていた。
広いオフィスといえども、これだけの人数が集まると
オフィス内は鮨詰め状態となっていた。
このオープンハウスについては、
英語ではあるが 東北大学米国代表オフィスのウェブサイトに
「
オープンハウス・レポート」
として記載されている。
【参考リンク】
カテゴリー:
JUNBA
22:01
| コメント (0)
| トラックバック (0)
Ruby での ブロックとは
「 do ... end または { ... } で囲まれたコードの断片」のことを言う。
それでは do ... end と { ... } は 全く同じか、というとそうでもないようだ。
マニュアルによると
「 { ... } の方が do ... end ブロックよりも強く結合する」と記述されている。
このことを説明するための例をマニュアルから引用させてもらうと
foobar a, b do .. end # foobarの引数はa, bの値とブロック
foobar a, b { .. } # ブロックはメソッドbの引数、aの値とbの返り値とがfoobarの引数
となっている。
また、Rubyにおいて { ... } で囲むという表現は、ブロック以外にも存在している。
「
ハッシュ式」が
それにあたる。例えばハッシュの定義は
a = { 1=>2, 2=>4, 3=>8 }
のように { ... } で囲む形をしている。
もちろん、良く見れば 内容が違うので
これがブロックなのかハッシュ式であるかどうか判断できるが。
C言語等では言語の仕様上 { } が多用されていたが、
今まで Rubyのサンプルを読む限りでは
do ... end ブロックの方をよく見かけるようだ。
【参考リンク】
カテゴリー:
Ruby
22:53
| コメント (0)
| トラックバック (0)
ここしばらく、RDE (Ruby Development Environment) を試しているが、
どうも安定動作をしてくれない。
スクリプトを実行させると、「The parameter is incorrect.」というメッセージが
頻繁に表示されて止まってまうのである。
RDEは 使い方にも慣れてきて、便利さも感じている一方、
安定動作をしてくれないので
その点に関しては非常にストレスを感じてしまう。
上記のとおり、スクリプトを
メニュー「実行」の「実行」から、もしくは[F5]キーにより
実行させると、
「The parameter is incorrect.」という
メッセージボックスが表示されて
止まってしまうことがある。
また、この現象は必ず起こる訳でもなく、
同じスクリプトを実行させてみても、
起こる場合と起こらない場合がある。
確立で言うと50%くらいであろうか。
スクリプトの長さや、内容にも関係がないようである。
それからこのエラーが起こった場合でも、
メッセージボックス内の「OKボタン」をクリックすると、
一回で消える場合と、
同じメッセージボックスが連続的に表示される場合がある。
何度かメッセージボックス内の「OKボタン」をクリックして
スクリプトの実行が最後まで行った場合でも、
コンソールウィンドウに
正常にプログラムが終了した場合に表示される内容が
きちんと表示されている場合と、
コンソールウィンドウに何も表示されていない場合とがある。
ちなみに、プログラムが最後まで実行できたかどうかは
画面下のステータスの表示が「実行中」から
「完了(0)」に変わることによって判断がつく。
原因が判明すれば、対策の講じ様もありそうなのだが、
このメッセージだけからは、まったく判断がつかなかい。
グーグルで検索してみて、同様の問題については見つからない。
さて、どうするべきか、もう少し調査をしてみよう。
ちなみに、使っているRubyは 「mswin32」版。
Ruby本体やRDEの再インストールもやってみようかと思ってはいるが、
ただ 闇雲にやってみても仕方がないので、もう少し情報を集めてみよう。
【参考リンク】
カテゴリー:
Ruby
22:18
| コメント (0)
| トラックバック (0)
昨日のブログで Ruby のデバッグを CUIにより行ってみたが、
全く同じことを、RDE (Ruby Development Environment) 上でも
試してみようと思う。
- RDEから「var.rb」を開く
- エディタ部の行番号欄「2」と「4」のところの左端
(マウスカーソルが手の形に変わる)で、
それぞれマウスをクリックすると、赤い丸印がつく。
これがブレークポイントがついた印。
この用に RDEでは、実行する前にプレークポイントを設定することができる。
- メニュー「デバッグ」の「デバッグ開始・継続」を選択するか、
または[F9]キーを押すして、デバッグ・モードで実行を開始する。
すると、コンソールウィンドウに Ruby本体との通信の様子が表示される。
この時点で、既にプレークポイントが設定されたことが確認できる。
- 「変数ウィンドウ(Variable Window)」の中から「ローカル」タブを選択しておく。
この時点では、まだ何も表示されない。
- この段階で、エディタ部の行番号欄には、4行目に緑の丸印がついているが、
これは、この行まで実行してきた、ということではないようだ。
それは、コンソールウィンドウのログをみると判る。
ということで、メニュー「デバッグ」の「デバッグ開始・継続」を選択するか、
または[F9]キーを押すして、実行を継続する。
- すると実行が 2行のブレークポイントで止まったことがわかる。
この時、「変数ウィンドウ(Variable Window)」の中から「ローカル」タブには
「var => "Top Local Variable"」という記述が表示され、
変数の中身が確認できる。
- 続けて、メニュー「デバッグ」の「デバッグ開始・継続」を選択するか、
[F9]キーを押すして、実行を継続する。
- すると実行が 4行のブレークポイントで止まったことがわかる。
この時、「変数ウィンドウ(Variable Window)」の中から「ローカル」タブには
「var => "Top Local Variable2"」という記述が表示され、
変数の中身が変更されていることが確認できる。
文章で書くと長くなるが、
上記の処理が全てマウスのクリックだけで実現できたわけだ。
プログラミングに消費される時間の大半はデバッグ作業である。
このようなツールが使いこなせるようになると、
開発にかかる時間を短縮できるようになるであろう。
【参考リンク】
カテゴリー:
Ruby
22:31
| コメント (0)
| トラックバック (0)
Ruby には デバッガ機能がある。
実は RDE (Ruby Development Environment) も このデバッガ 機能を利用している。
そのため、 Ruby デバッガ について理解しておく方が
RDEのデバッグ機能を使いこなすためにも役に立つ。
Rubyマニュアルの「
コマンドラインオプション
」によると、
「-r」オプションは 「スクリプト実行前に指定されるライブラリを require する」となっている。
つまり、上記の例では
Ruby 起動時に 「debug.rb」というライブラリを読み込むことによって
デバッガを走らせていることになる。
具体的なデバッグの例を挙げてみる。
ソースとして
1: var="Top Local Variable"
2: p var
3: var="Top Local Variable2"
4: p var
という簡単な スクリプトを var.rb という名前のファイルにしておく。
実際のファイルには、もちろん行頭の番号はつけていなが、
デバッグする際には、行番号が必要となるのでここでは付けてある。
このスクリプトをデバッグ・モードで起動してみる。
> ruby -rdebug var.rb
Debug.rb
Emacs support available.
c:/ruby/lib/ruby/site_ruby/1.8/ubygems.rb:10:require 'rubygems'
(rdb:1)
ここでの「(rdb:1)」というのがデバッグ・モード用のプロンプトである。
それではスクリプトの2行目に「break」コマンド、省略形は「b」を使ってブレークポイントを設定してみる。
(rdb:1) b var.rb:2
Set breakpoint 1 at var.rb:2
(rdb:1)
この場合、「ファイル名:行番号」のフォーマットで設定する必要がある。
実行する前に、「var local」コマンド、短縮形は「v l」を使って現在のローカル変数を表示させてみる。
(rdb:1) v l
(rdb:1)
当たり前だが、まだスクリプトを実行する前なのでローカル変数はなにもない。
次に、「cont」コマンド、省略形は「c」でブレークポイントに到達するまで処理を続行してみる。
(rdb:1) c
Breakpoint 1, toplevel at var.rb:2
var.rb:2:p var
(rdb:1)
ここで再び、「var local」コマンドで現在のローカル変数を表示させてみる。
(rdb:1) v l
var => "Top Local Variable"
(rdb:1)
今度は、「var」という変数に文字列が入っているのが確認できる。
続いて 2行目にブレークポイントを設定、「cont」、そして、ローカル変数を表示をさせてみる。
(rdb:1) b var.rb:4
Set breakpoint 2 at var.rb:4
(rdb:1) c
"Top Local Variable"
Breakpoint 2, toplevel at var.rb:4
var.rb:4:p var
(rdb:1) v l
var => "Top Local Variable2"
(rdb:1)
今度は、「var」という変数の内容が、「Top Local Variable2」に変更されているのが確認できる。
この様に、Rubyでは
デバッグをすることができる。
ただし、CUIなので、入力がすこし面倒である。
【参考リンク】
カテゴリー:
Ruby
22:56
| コメント (0)
| トラックバック (0)