yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2017/11 の記事
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]

yamicha.com's Blog
 諸事情により、現在更新休止中。ご了承ください。もし今後ブログを再開することがあるとすれば、その際にはこのブログスクリプトではなく、新しく開発したものによるかもしれません。
 当ブログ管理者についてはこちらをご参照。
開発魔法(737)
社会問題(733)
お知らせ(11)
質問・バトン回答(15)
ゲスト出演(8)
経済・知的財産(150)
ゲーム開発(182)
[Ada] 勝手に補足
- Note
- 金配りの次の一手


- Endless Ultimate Diary
- 銃世界

漢字バトン
- うるる雑記帳
- 漢字接力棒

ツキアイゲノムバトン
- ブログ@うにうに画像倉庫
- あぶ内閣

縺イ縺セ縺、縺カ縺励ヰ繝医Φ
- 月夜のボヤキ
- 騎士サーラバトン
パスワードを使う
名無し (2012/02/27)


開発者解放裁判
yamicha.com (2010/03/14)
Winnyに関しては、私も「純白」とまでは考えておりませんし、使用し..

開発者解放裁判
通りすがり (2010/03/08)
winnyに関しては「ダウンロードソフト板」なんてところを拠点に開発..

新型インフルエンザの恐怖
いげ太 (2009/11/03)
> C#などの「int Some(int , int)」は、F#では「(int * int) ->..

時効に関する思考
yamicha.com (2009/08/31)
>いげ太さんコメントありがとうございます。手元にドキュメントが少..
Homepage
Blog Top
Normal View
List View
Search
Calendar
Comment List
Trackback List
Blog RSS
Send Trackback
Phone Mode
Administrator
yamicha.com
Blog
るううるる。
Source
法令データ提供システム
FindLaw
Development
Java2 Platform SE 6
Java EE 6 API
MySQL Developer Zone
PHP Reference
MSDN Library
Ada Reference Manual
Objective Caml
Python Documentation
Erlang
Prolog Documents
細字の技術
2007/11/17(Sat)15:05:13
 この前はソフトバンクが不当な広告(条件付き定額通話サービス「ホワイトプラン」の制限条項を判別不可能なほど小さく表記)で警告を受けていましたが、今度はドコモとKDDIが警告を受けるに至りました。まさに携帯電話各社の本質見たりといったところですが、実際にこのような不正が起こる土壌があるのであれば、直してもらわなければ困ります。
 警告を受けた原因もソフトバンクの場合とほぼ同様です。ドコモ、KDDIともに契約直後であっても通話料を半額程度にするサービスを最近導入しているのですが、これは2年間の継続契約が前提となっており、違反すると違約金として約1万円を支払わなければなりません。これまでの1年契約の違約金と比べても、かなりの高額となっています。しかし、このサービスを紹介した広告においては、半額であることが非常に大きな文字で強調されているにもかかわらず、違約金に関する規定は何と1ミリの文字で表記されていたというのです。問題があるどころか、卑怯と表現するしかありません。
 また、高額な利用料が携帯電話の値引きに使われているという批判や指導を受け、各社は携帯電話を値引きしない代わりに利用料を安くするプランを出し、従来のプランにも端末利用期間に制限を設けるなどしましたが、こちらでもどのような不当表示が行われるのか分かったものではありません。奇しくも、端末の料金が安くなるプランはおおむね2年契約であったり、期間内の解約や機種変更に制限がつく点など(例えばドコモの場合、端末が安くなるプランは2年契約であり、違約金は残り1月につき税別600円、契約1ヶ月で解約・機種変更すると13800円)、今回不正が発生したプランとの共通項もかなり存在し、全く同じ不正が通用してしまいます。今回の「警告」は、これに対する牽制の意味もあるものと考えられます。
 そして何より問題なのは、端末割引型のプランが「負債」であると認識しない人が増えることにほかなりません。この型のプランは見たところ従来と同じであり、同じ感覚で考えてしまいかねませんが、2年契約の義務化と違約金発生などかなり重い制限が存在するものとなっています。多くの人はこの点を認識しておらず、本来なら広告や契約時の説明などで周知を図らなければならないところですが、携帯電話会社としてはこの点は隠ぺいしたいはずであり、結果として無用なトラブルを招く恐れがあります。特に携帯電話割引型のプランを重視しているKDDIでは、同プランを契約する人が多くなる可能性が高く、問題が顕著に出る可能性があります。
 それで、このプランがなぜ「負債」なのかといいますと、このプランの考え方はまさにローンのそれであるためです。2年経過後も割高な料金が続くという違いはあるとはいえ、2年間で端末代金を回収する割賦販売と何ら変わりません。解約で残金を請求される点からしても、これが負債であることは疑う余地もありません。ソフトバンクの場合は一目で割賦販売と分かる形態ですからまだマシとしても、果たしてドコモやKDDIは新料金プランのトラブルを回避できるでしょうか。
 特にこじれることが予想されるのは、携帯電話が早々に壊れたり、紛失してしまったような場合です。端末割り引き型のサービスに加入した際には、ドコモでは保険に類似のサービスを3ヶ月間無料で提供し、もし端末が壊れても無償で新しい端末を受け取れるようですが、それ以降は月額300円のオプションサービスです。月額600円の違約金と比べても、サービス料としては微妙なところです。しかし、2年間全域を保険によってカバーしていては利用料の高騰は避けられず、現実的ではありません。問題を避けるには十分に説明責任を果たすしかありませんが、都合の悪いことを1ミリの文字で表記するような姿勢の各社に、それが期待できるでしょうか。
 それから、こちらは不正広告絡みではありませんが、KDDI及びソフトバンクの端末を割り引かない型の料金プランには大変疑問があります。これまでの携帯電話各社は端末代を割り引く代わりに利用料でそれを回収しており、そのビジネスモデルは問題であるから改正すべきと総務省が要請、新しい料金プランが導入されたというのがこれまでの流れなのですが、KDDIではミドルユーザー以上なら端末を割り引く型の料金プランの方が安く、端末を割り引かないプランでは多くの割引サービスに加入できないなど、新プラン契約希望者イジメともいえる内容になっています。本来なら端末代の条件だけで勝負すべきところであり、非常に不公平です。総務省に注意されたから、しぶしぶ誰も加入しないような割高なプランを新設した、と表現すべきでしょうか。
 不正な広告には今後とも注意が必要ですが、アリバイ作りともいえる新プランを形だけ導入する行為もそれに負けず劣らず姑息な手段ですので、改善が望まれます。

 「いじめ」の定義を変更したところ、何と報告されたいじめ数が6倍。これまでいかに「定義」を隠れ蓑にしていじめが隠ぺいされていたかが分かります。そして、実際にはいじめはもっと隠ぺいされているはずであり、この6倍となった数値でもいじめ全体の1割にも満たないというのが事実でしょう。
 しかし、そもそもこのような調査には全く意味がありませんし、県ごとに調査方法が全く違うということからして何の信頼もできないデータではあるのですが、いじめの定義を「被害者がいじめと感じたケース」と改めたことは評価できます。この定義を用いれば、教師が「被害者本人はいじめと主張していたが、客観的に見ていじめではなかった」などという言い訳や事実のわい曲をすることを防止できるのです。関係者からいじめの事実についてただされた際にこのような言い訳をするのならともかく、被害者の遺影の前でこのようなことを語られた日には、遺族の怒りは察するに余りあります。いじめ対処の際にはこの方針を原則とすべきでしょう。
 では、それでいじめがなくなるかといいますと、残念ながら完全になくすことはできません。いじめを認めたがらない教師が多いことの他に、時に教師自身がいじめに積極的に加担するためです。例えば福岡のいじめ自殺問題では、不適格としか言いようのない教師が被害者を殺したようなものでした。このようなクラスでは、自殺につながるようないじめがあったとしても、いじめが報告されたり改善されたりする望みは全くありません。
 しかし、いじめを完全に根絶する方法は存在しませんが、いじめを減らす方法ならあります。まずはいじめを「事件」とみなすことです。つまり、悪質ないじめにはしっかり刑事罰を適用し、いじめに加担あるいは訴えを無視した教師には懲戒免職を含む厳罰を下すようにします。ここまでの荒療治となると反対意見も多いでしょうが、「万引き」が「窃盗」であるのと同様、「いじめ」は暴力なら傷害あるいは暴行罪、被害者の精神を病ませれば傷害罪、誹謗中傷で被害者の名誉を傷つければ侮辱や名誉毀損罪、脅せば脅迫罪、金品を巻き上げれば恐喝罪、帰宅困難にすれば監禁罪など、立派な刑法違反の犯罪行為です。「クラスメイトをいきなり殴る」であったり「通行人に襲い掛かる」であれば問題にされたり告訴されたりするのに、これがいじめであれば「そこまでする必要はない」という弁護の声が出てくるのは不思議でなりません。
 教師についても、このような犯罪行為をとがめないのは重大な職責放棄です。自分が受け持つ児童・生徒が突然クラスメイトを攻撃したり、通行人を襲ったのであれば、何らかの対処をする場合がほとんどでしょうが、これがいじめとなるとなぜか放置される場合が多々あるのです。受け持つ児童・生徒の犯罪をとがめない以上、職務を全うする気がないと判断されても仕方ありません。
 ただし、当然のことながら、これは「ゼロトレランス」とは別物です。いじめという人道的にも刑法上も許されない行為には正当な罰が必要と述べているに過ぎません。ゼロトレランスでは「教師に逆らった」なる規定で減点されることもあり、それで停学処分となることもあります。このような権限をいじめ加担教師に持たせたら、一体何が起こるでしょうか。また、いじめの中には被害者を脅迫して問題行為を起こさせるというものもあり、このタイプのいじめでは被害者が処分される恐れもあります。
 無論、すべてのいじめを刑事罰に処することは相当ではなく、実務的にも困難ですから、手口が悪質または繰り返されているいじめのみが対象となるでしょう。しかし、いざとなれば刑事罰も適用可能というのは大きいですし、教師もいじめを無視しづらくなります。被害者が自殺し、教師が「いじめとは思わなかった」と言い出し、ようやく警察が動いて加害者を逮捕・少年院送致、という経緯ほど悲惨なものはありません。

 以前にDualKnightのサンプルを出したことがありましたが、あれも一応動くには動くものの、処理がかなり遅い点が問題でした。そもそも重くて当然のJavaですし、Direct3Dなどと違ってハードウェアの機能が使えないため、ある程度重いのはどうしようもありませんが、多少なりとも軽量化したいところです。
 こうした理由により、このところ行ったリファクタリング。パフォーマンスが従来比でおおむね125%〜150%の値を示しました。最初のDualKnightと比べれば、おそらく3倍程度は速くなっているでしょう。これでもまだ十分重いのですが、ワイヤーフレームの7割程度の性能には達しているため、プログラムの見直しで速度を向上させるのはこの辺りが限度でしょう。
 後は公開物を作るだけなのですが、果たして作れるのでしょうか。

 そして相変わらず苦戦しているRuby言語。言語自体がかなり難しく、難易度は軽量スクリプト言語というより重量言語に相当するほどなのですが、それでいてコンパイル言語ほどの厳しいチェックがなく、堅牢さは軽量スクリプト言語クラスというのはどうにもこうにも。VBより楽ですが、Javaよりは辛いです。
 私は決してRubyに恨みを持っているなどというわけではありませんし、日本人の作ったスクリプト言語ということで(私はおかしな民族主義者ではありませんので、日本語の資料が充実しているという意味で)悪くはないはずなのですが、どうにも満足できません。とはいえ、これは別にRubyに罪があるのではなく、同じスクリプト言語であり、比較対象となるPerlがあまりに強すぎるのが原因です。PHPもたびたび(主に$thisやGLOBALSを)酷評していますが、これもPerlが強力すぎるゆえです。実際、Perlを超えるスクリプト言語を作るのは至難の業でしょう。
 さて、言語自体はともかくとして、言語の難易度に彩を添えるのがドキュメントの存在です。言っては悪いのですが、このドキュメントはあまりに分かりづらい表現が多すぎます。例として、以下に「ブロック付きメソッド呼び出し(イテレータ)」の説明を引用します。
ブロック付きメソッドとは制御構造の抽象化のために用いられるメソッドです。最初はループの抽象化のために用いられていたため、特にイテレータと呼ばれることもあります。 do ... end または { ... } で囲まれたコードの断片 (ブロックと呼ばれる)を後ろに付けてメソッドを呼び出すと、そのメソッドの内部からブロックを評価できます。ブロック付きメソッドを自分で定義するには yield 式を使います。

{ ... } の方が do ... end ブロックよりも強く結合します。次に例を挙げますが、このような違いが影響するコードは読み辛いので避けましょう:

foobar a, b do .. end # foobarの引数はa, bの値とブロック
foobar a, b { .. } # ブロックはメソッドbの引数、aの値とbの返り値とがfoobarの引数
 非常に理解に苦しみました。これを読んで内容が理解できる人は一体どの程度存在するのでしょうか。日本語の読解力がないと言われればそれまでですが、これではせっかく日本語のドキュメントが存在している意味がありません。プログラム言語の基本は「書いて試す」ですが、何をすればそうなるのかがつかめないため、書いて試すことも難しいときています。
 何といっても、記述だけでなくサンプルソースが分かりづらいのはかなり致命的です。例えば上記の場合、「foobar a, b { .. }」の部分なのですが、コメントにそれらしいことが少しだけ書かれている通り、bは変数ではなくメソッドです(無論、bがメソッドなどという記述はそれ以外の部分には一切登場せず、何の脈略もなくメソッドとされています)。しかもbはyieldを呼び出し、その上値を返さなくてはなりません。当然のことながら、bがメソッドであることすら大変分かりづらい有様ですから、bはそのような特殊な動作をするメソッドなどということは、どこにも書いてありません
 その他、説明本文の「do ... end または { ... } で囲まれたコードの断片 (ブロックと呼ばれる)を後ろに付けてメソッドを呼び出すと、そのメソッドの内部からブロックを評価できます」なる部分も回りくどい割に何を言いたいのか良く分かりません。こればかりは実際に動かして検証してみるしかありません。
 私はRubyについて未だ良く分かっていないため、これの代わりに分かりやすい文章を書くことはできません。しかし、このような文章が連なっているドキュメントというのはあんまりでしょう。MSDNもJava APIもPHPもMySQLもドキュメントはこれより容易ですし、下手すると英語が読めない私ですらJava EE 5のドキュメント(英語)の方が分かりやすいというのはあんまりです。Rubyが難しい理由の1つがこれであるとするなら、これさえなくなれば難易度はかなり改善されるはずですから、本気でドキュメントの改善を検討して欲しいところです。
 それではRuby言語の続きと参りましょう。本来ならJRubyを用いるところなのですが、そのうちCGIも作ってみたくなりましたので、Rubyインタプリタをダウンロードして使用することにしました。あまり気は進まなかったのですが、これもCGIの検証環境を作るためです。しかし、例によってその行為を後悔することになるのでありました。
 まずはRubyのWindows版のダウンロードからですが、これは簡単です。インストーラ付きではない、通常の圧縮版を用いました。ダウンロードを終えたら、後はそれをどこに展開するかですが、もしrubyやirbコマンドを使うだけであればどこでも構いません。好きな場所に置いておけば使えます。しかし、もしApacheで使うのであれば、パスを指定しやすい場所に置いた方が良いでしょう。私の場合は「c:\usr\local」に展開しておきました。こうすると「#!/usr/local/bin/ruby」でパスを指定できます。
 しかし、問題はその展開です。私のPCの機嫌が悪かったのか、もともとそういうものなのかは知りませんが、何とかなり時間がかかりました。途中でキャンセルしようと考えては、キャンセルした方が恐ろしいことになりそうですので踏みとどまり、挙句は途中である程度開き直ってしまい、これもネタになるかとキャプチャしておきました。とはいえ、「RubyでCGIが使ってみたい」などといういい加減な理由で導入しようとしたことをかなり後悔したのは言うまでもありません。



 導入後は特に何もする必要はありません。httpd.confを修正する必要もありません。もし修正する点があるとすれば、必要なら*.rbをCGIとして動作させたり、index.rbをインデックスと認識させる程度でしょうが、スクリプトの拡張子を*.cgiとしてRubyを用いるならどちらも不要です。単にCGIの先頭で「#!/usr/local/bin/ruby」を指定し、後はRubyを書いていくだけです。
 それではまず1つ目、例外処理から。Rubyは例外処理機構を備えており、例外を投げたり受け取ったりすることができます。Javaでいうthrows節はなく、キャッチされなかった例外はさらにメソッドの呼び出し元へと順に投げられます。最後までキャッチされなければ、その時点でスクリプトの実行を停止します。したがって、例外をキャッチする記述がなくてもエラーにはなりませんが、務めてキャッチする必要があります。
 しかし、これまた例外処理の記述は覚えづらいです。C++やJavaでは「try〜catch〜finally」(finallyはJavaのみ)でしたが、Rubyでは「begin〜rescue〜else〜ensure」なのです。beginはtry、rescueはcatch、elseは例外が出なかった時に実行され、ensureはfinallyです。rescue節では受け取る例外の型を指定したり、例外を変数に格納することができます。受け取る例外の型が複数あるなら、rescueを複数書くこともできます。
 簡略化した書き方として「A rescue B」なるものもあります。これはAの処理で例外が発生した場合のみBが実行されるというもので、この場合は受け取る例外の型を指定することはできません。Perlの「A || B」のような書き方と同じ意味で使うと楽でしょうか。
 例外を発生する際には「raise」を使います。これは厳密には制御構文ではないそうですが、使い方はthrowとほとんど同じです。「raise "Message"」でメッセージ付き例外を生成でき、「raise ExceptionClassName」で例外クラスを生成して返せます。
 Rubyの最も上に位置する例外クラスはExceptionですが、JavaでThrowableよりExceptionを使うことが多いように、RubyではStandardErrorを例外の基底クラスとして使うことが多いようです。StandardErrorまたはそのサブクラスはクラス名を省略したrescueでキャッチすることができ、また簡略化版のrescueでキャッチできるのもこのクラスだそうです。
# 例外クラス(StandardError の派生)を作成
class TestException < StandardError
end

class SampleException < StandardError
end

# 例外を発生させるメソッド
def exception(type)
	if type == "Test" 
		raise TestException
	elsif type == "Sample"
		raise SampleException
	else
		raise
	end
end

# 例外を受け取る
begin
	exception("Test")
rescue TestException => e 
	print "TestException\n"
	# e は例外オブジェクトを格納する変数
	# 当然ながら名前は e である必要はない
rescue SampleException => e 
	print "SampleException\n"
rescue => e
	print "StandardError またはそのサブクラス\n"
else
	print "例外なし\n"
ensure
	print "例外があってもなくても実行\n"
end
 原理はJavaとさほど変わりません。
 なお、特定のメソッドなりの内部で発生した例外をすべてrescueすることもできるようです。その場合の構文はこうなります。
def method_name()
	...
rescue
	...
# else , ensure も使える
end
 beginとendがない以外はほぼ同じです。
 次は「モジュール」と参りましょう。モジュールは見たところクラスのようなものなのですが、クラスではありません。例によってドキュメントを読んでも一体何なのかはっきりしませんが、それではモジュールとは一体何者なのか。
 まず、モジュールはクラスと違ってインスタンスを作れません。ではモジュールはabstractクラスかといいますと、これも違います。メソッドにはしっかり実装を書きますし、実装を省略することはできません。さらに、どうやらクラスの継承元として用いるものでもないようです。
 それでは一体何に使うのか。モジュールはクラスからincludeして使うそうです。例えばこのような使い方をします。
# モジュール Test
module Test
	def test()
		print get_text()	# まだ見ぬ get_text()
	end
end

# それを include するクラス
class Include
	include Test
	def get_text()
		return "Message"
	end
end

i = Include.new()
i.test()	# 何の問題もなく呼び出せる
 IncludeクラスがモジュールTestをincludeすると、Includeクラスにはtest()メソッドが定義されます。ダック・タイピング言語だけに、モジュール内ではまだ見ぬメソッドや変数を使うことができます。上記の例ではTestのtest()内でget_text()メソッドを呼び出していますが、これはinclude先にget_text()メソッドが存在することが前提となっており、もしそのメソッドがないクラスにTestをincludeしてtest()を呼び出すとエラーになります。
 また、モジュールにはもう1つ役割があります。この方法によれば、関連性のあるクラスをモジュール内にまとめ、分かりやすく参照することができるようです。
module Outer
	class Inner
		def text()
			print "InnerClass"
		end
	end
end 

Outer::Inner.new().text()
 これはOuterがモジュールではなくクラスであっても同じことができるのですが、Outerがいわゆる「名前空間」の意味しか成していない以上、インスタンスを生成する必要は全くなく、生成できても無駄です。したがって、インスタンスを作れないモジュールとして定義するようです。
 また、クラスの場合と違って次のような省略型の構文も可能になります。
include Outer
Inner.new().text()
 さしずめC++の「namespace」と「use」です。
 上記と同じことをクラスで行えば入れ子クラスになりますが、Rubyにおいて外側のクラスと内側のクラスは特に関係ないようです。つまり、例えばこのようなことはできません。
class Outer
	def outer()
		return "inner"
	end
	class Inner
		def inner()
			print outer()
		end
	end
end
 ただし、Outerクラスは「Outer::」なしで自分のクラスの入れ子クラスにアクセスできます。
class Outer
	def call_inner()
		Inner.new().inner()
		# 外側からアクセスする場合はこれではダメで
		# Outer::Inner.new().inner()
		# としなければならない
	end
	class Inner
		def inner()
			print "This is the inner class"
		end
	end
end
 つまり、Javaのstatic内部クラスと似た性質を持っています。
 その他のクラス周りの特殊仕様としては、クラス宣言部でのインスタンス変数への代入はかなり類を見ない動作となっているようです。
class ClassName 
	@var = 100
end
 上記記述はJavaでも許容されており、最初からvarに100が入った状態になります。しかし、実はRubyでは毛色が違います。
 どこからどう見てもインスタンス変数への代入にもかかわらず、インスタンス変数への代入ではありません。正しくは、インスタンス変数への代入ではあるのですが、ClassName.new()で作られたインスタンスへの代入ではありません。
 これでは意味がさっぱり分かりませんが、それがRubyというものです。まずRubyではクラスもClass型のインスタンスです。ですから、上記であればClassNameという名前のClass型のインスタンスが定義されます。そして、ClassName内であってメソッドではない部分でインスタンス変数を使うと、その変数の値はそのインスタンスに格納されるのです。つまり、ClassName.varというインスタンス変数に100が代入されていることになります。
 したがって、特定のインスタンスに対してメソッドを定義する「特異メソッド」を定義してやると(余談ながら、JavaScriptのクラスのメソッドはすべてRubyでいう特異メソッドらしきものです)、
def ClassName.view_var()
	print @var
end

ClassName.view_var()	# 100
 インスタンスにデータが格納されていることが分かります。つくづく変な仕様ですが、RubyのクラスはClassクラスのインスタンスであり、メソッドもインスタンスに格納されたメソッドであると考えれば、分からなくもありません。しかしやはり変です。
 最後に、ドキュメントの例題で出したブロック付きメソッドと参りましょう。ブロック付きメソッドといいますのは、何らかのメソッドを指定し、そのメソッド内でyieldが呼ばれるたびにブロックの内部を実行するというものです。例えばこのように使います。
[1 , 2 , 3].each do |i| 
	print i
end
 eachは配列クラスのメソッドで、おそらく内部でリストの要素すべてに対してyieldを呼び出しているのでしょう。かくして無事に配列をイテレート処理できるのでありました。
 自分で処理メソッドを定義することもできます。処理メソッド内でyieldを呼び出すたび、ブロックの内部が実行されます。
def each(list)
	for i in list
		yield i
	end
end
 これは次のように使用できます。
each([1 , 2 , 3]) do |i|
	print i
end
 また、do〜endの代わりに中カッコを使うこともできます。
[1 , 2 , 3].each { |i| 
	print i
}
 中カッコを使う場合の動作はdo〜endとほぼ同じですが、ある一定の状況でのみ動作が変わります。これが最初に引用したRubyマニュアルの言わんとすることなのですが、これは後述。
 上記コードを見ての通り、ブロック付きメソッドに用いるメソッド(yieldを呼び出すメソッド)は事前に定義しますが、ブロック内部の処理も事前に定義することができます。
# 値を2乗して表示するコード
multiple = proc{ |i| 
	print (i * i)
	print "\n"
}

# メソッドの最後の引数として & をつけて渡す
[1 , 2 , 3].each(&multiple)
 方法は見ての通りです。proc{}によってブロック内部の実装を記述して変数に格納しておき、それをメソッドの最後の引数として渡します。その際、変数名の頭に&を付加します。したがって、自作eachメソッドを使う場合はこうなります。
# 自作 each メソッド
def each(list)
	for i in list
		yield i
	end
end

# ブロック内の実装を変数に格納
multiple = proc{ |i| 
	print (i * i)
	print "\n"
}

# メソッドの引数の最後に & を付加して記述
each([1 , 2 , 3] , &multiple)
 少々工夫すれば、このような処理をイテレータによって行うことができます。
# タブ区切りの適当なデータ
var = <<EOF
PI	3.14159
E	2.71828
SQRT_2	1.41421
EOF

# 切り分けたデータを yield するメソッド
def explode(word , data)
	datas = data.split(word)
	datas.each do |value| 
		yield value
	end
end

# テーブル化
print "<table border=\"1\">"
explode("\n" , var) do |row| 
	print "<tr>"

	explode("\t" , row) do |col|
		print "<td>"
		print col
		print "</td>"
	end

	print "</tr>"
end
print "</table>"
 結局のところ、Perlのforeach()と変わらないのではありますが。
 JavaならIterableを実装すればほとんど同じことが可能ですが、あえてRubyの流儀に似せて実装するならこのようになるでしょうか(JSPによる実装)。
<%!
// yield を呼び出すメソッドの実装
interface BlockMethodObject{
	void parseBlockMethod(BlockMethod method);
}
// ブロック内部の実装
interface BlockMethod{
	void yield(Object value);
}
%>

<%
final int values[] = {1 , 2 , 3 , 4};

// yield を呼び出すメソッドの実装
// 匿名クラスではなく通常のサブクラスにしてもよい
BlockMethodObject method = new BlockMethodObject(){
	final int data[] = values;
	public void parseBlockMethod(BlockMethod method){
		for(int v : data)
			method.yield(v);
	}
};

final JspWriter writer = out;

// yield により実行するブロックの中身
method.parseBlockMethod(new BlockMethod(){
	public void yield(Object value){
		try{
			int v = (Integer)value;
			v *= 2;
			writer.println(v);
		}catch(IOException e){
		}
	}
});
%>
 少々強引ですが、一応書けます。
 それでは肝心のdo〜endと{}の違いと参ります。ドキュメントでは次のコードが示されていました。
foobar a, b do .. end
foobar a, b { .. }
 ドキュメント中では何の脈略もなくfoobarだのaだのbだのという名前のものが出てきていますが、foobarの他にbもメソッドであると考えてください。
 上記ではどちらもfoobarがカッコ省略形式で呼び出されていますが、後者のfoobar呼び出しをこのように書き換えると、何と動作が変わってしまいます。
foobar(a, b) { .. }
 なぜか。do〜endの場合、及びカッコありのメソッド呼び出しの場合、おそらくパーサは次のように解釈することでしょう。まず、foobar(a , b)を実行します。foobar(a , b)でyieldが実行されたら、そのつどdo〜endあるいは{}のブロック内部を実行します。これをfoobar(a , b)から制御が返るまで繰り返します。
 しかし、これが「foobar a, b { .. }」である場合、パーサはまず「b { .. }」のブロックを実行しようとします。つまり、bの内部でyieldが呼び出されることでブロック内部の処理が実行されます。bから制御が返ったら、今度は「foobar(a , bの返り値)」を実行しようとします。したがって、この場合のbではyieldとreturnの両方の処理が意味を持ちます。
 以下に処理のサンプルを示します。
# yield を用いるメソッド
def get_list()
	# フィボナッチ数のリスト
	list = [1 , 2 , 3 , 5 , 8 , 13]

	# リストのデータを2倍にした値を順番に yield 呼び出し
	for i in list
		yield i * 2
	end

	# リストを返す
	return list
end

# リストのデータを3倍にした値を順番に表示するメソッド
def iteration(list)
	for i in list
		p i * 3
	end
end

# ブロック付きメソッド処理
iteration get_list { |i|
	p i
}
 この場合、get_listがyieldをコールするたびにブロック内部の処理が実行されるため、まず2,4,6,10...が表示されます。その後、get_listの返り値であるフィボナッチ数のリストがiterationに渡され、iteration内のループにより3,6,9,15...が表示されます。つまり、優先順位に差が生じるわけです。
 ちなみに、最初に引用したドキュメント内には、do〜endと{}の違いについて「このような違いが影響するコードは読み辛いので避けましょう」と書かれていますが、この点は全く同感です。それ以前に、せめてこのような場合、メソッドの引数はしっかりカッコで囲みましょう。こう書けば誰の目から見ても一目瞭然ではありませんか。これならb()がメソッドであることも最初から分かります。
# do〜end と同じ意味で { .. } を使うパターン
foobar(a , b()){ .. }

# { .. } と同じ意味を分かりやすくしたパターン
foobar(a , b(){ .. })
# または
foobar(a , (b(){ .. }))
# または
foobar(a , (b() do .. end))
 do〜endならカッコを省略しても{}ほど厄介でないとはいえ、これはあまりに分かりづらいのではないでしょうか。
# パッと見では do も引数の1つにしか見えない
foobar one two do |i|
	p i 
end
 ともかくRubyは肩がこる言語のようです。決して悪い言語というわけではないのですが。ひたすらRubyを書き続け、嫌になったころにすかさずJavaを書くと、Javaの素晴らしさを再実感できて感動に浸れるかもしれません。またはPerlを書いてラリー・ウォールの偉大さに感服するのも良いでしょう。
 しかし、未だにRubyでサンプル以外のコードを書けていませんので、そのうちRubyで適当なCGIでも書いてみたいものです。その程度までやれば、一応「Ruby使い」を名乗れるでしょうか。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 3]
<- 前の記事を参照 次の記事を参照 ->

Comments(3)
佐本 - 2007/11/18(Sun)23:45:35
私の勘違いでの指摘で、大変失礼致しました。お詫び申し上げます。
もしも、また書き込みさせて頂く機会があれば、その時には細心の注意を払います。どうもすみませんでした。
>あまりにもいじめのケースが多く、「○○(地名)いじめ」と表記するだけではどの事件なのか分からないという状況は極めて不健全
改めて今の状況が異常であると認識させられます。
この度は、私の見当違いにも関わらず、丁寧なご回答を有難うございました。

yamicha.com - 2007/11/18(Sun)07:45:55
>佐本さん
ご指摘ありがとうございます。「でっちあげ」、早速検索してみました。
しかし、私が本文中でしっかり明言しなかったのが原因なのですが、私が記事中で問題とした「いじめ教師」は福岡中2自殺のものでした。
参考:Wikipedia「福岡中2いじめ自殺事件」
http://ja.wikipedia.org/wiki/%E7%A6%8F%E5%B2%A1%E4%B8%AD2%E3%81%84%E3%81%98%E3%82%81%E8%87%AA%E6%AE%BA%E4%BA%8B%E4%BB%B6
こちらに関しては、生徒を「あまおう」「出荷できない」などと果実に例えた発言をしたり、偽善者などと暴言を吐いていじめを誘発したことについては、どうやら事実のようです。私が探した限りでは、否定する記事は見つかりませんでした。
私が本文に明記すれば済んでいたことではありますが、あまりにもいじめのケースが多く、「○○(地名)いじめ」と表記するだけではどの事件なのか分からないという状況は極めて不健全ですね。本当に何とかして欲しいものです。
マスコミの姿勢についても全く同感です。報じたことは取り返しがつかないとしても、名誉回復を行う義務はあるはずなのですが、「報道の自由」を主張しつつ「報道の責任」を果たさない姿勢にはあきれ返ります。
最近の例では、マスコミ連中がそろって「報道の自由や知る権利の侵害だから、職務上知りえた情報を漏らした人間を逮捕したり告訴するな」と言い出したことには失笑しました。
>小沢氏
民主党には、そしておそらく自民党にも、顔は売れていないものの、頭脳明晰で士気が高く、国民を第一に考えている優秀な人は存在するはずなのですが、顔だけでかい連中がそうした優秀な人々を覆い隠している現状は残念でなりません。
本来、小沢氏は安倍氏辞任と同時に代表の座を退き、代わりに目立たなくても優秀で確実な人(できれば菅氏といった代表経験者ではなく他の人)を立てるべきだった、というのが私の考えです。
>プログラム
こればかりは万人向けではないため、たまにデータなどにお遊びを入れてみてはいますが、プログラムを知らない人でももう少し面白く読めるよう努力してみます。
ご指摘感謝します。コメントありがとうございました。

佐本 - 2007/11/17(Sat)23:18:14
はじめまして。佐本と申します。
早速ですが、福岡のいじめ教師の事件は、虚言癖の両親と朝日などマスコミが作り上げた冤罪のようです。この裁判を傍聴し、取り上げたその名も「でっちあげ」という本が出ています。検索してみて下さい。
管理者様が何度もおっしゃられていますが、マスコミのいい加減さと、そのくせ誤報でも謝罪はおろか、訂正も無い、続報は目立たせず、というやり方は何とも恐ろしく困ったものです。またそれを見過ごす世間も。(この件では自分も騙されました。続報がないので変だなとは思ったのですが)世の中には問題教師が溢れ、苦しんでいる子供が多くいるのだから、そちらをちゃんと告発してほしいものです。
社会問題など多岐に渡るブログが読みごたえがあり、最近では小沢氏の批評に溜飲が下がりました。プログラムのことはわからず、申し訳ないのですが、時々拝見しております。初めてのコメントが指摘ですみません。

- Blog by yamicha.com -