![]() |
|
「そう、私はこのテクニカルマニュアルに今出てることになってるんだけど、ピックアップを探していたら、変な動物の町で道に迷ってしまったんだ・・・」 |
![]() |
||
|
「ああ、おたくの町は変だと思うよ。そこら中動物だらけだ!」 |
「うがー!! ばかげている!!
今じゃ電話交換手まで私のトラックを盗むのを助けてるんだ!!」 |
「キツネの大統領のマルコス・レジナルドが一枚噛んでると思ってるの?」 |
オリジナルズの壮大な計画に巻き込まれていることも知らず、背の高いキツネと、ずっと背の低いキツネは、非常事態の地であるウィグズルの街へと迷い込んだ。できるなら私は彼らにそのことを知らせ たい。海岸にある孵化場へとさらっていき、彼らのとがった耳は押さえて魚の卵の山の中に隠し、豪華な隠れ家にかくまいたい。そして私は彼らの上に立って微動だにしない影を投げかけ、毅然とライフルを構える。
しかし私にはできない。打ち明けなければならないが、私は自分の面倒を見なければならないのだ。上の階の電球を交換しなきゃならない。無料のハロゲン電球がちょうど郵便で届いたところだ。誰かが私にそれを使わせようとしているらしい。だから私はその電球をねじ込む。そして 私はそこにただ立って、微動だにしない影を投げかけ、毅然とライフルを構える。
その影がきれいでくっきりしているなら、私はそれをそのまま保とう。
1. 私が車を探しているなら
![]() |
||
|
「座れて楽になったよ。まったくひどいことになった」 |
「君にそんな目で見られるのは嫌だな」 |
「私の鬱屈した感情を助長しようというの? 私の気楽な性格を押しつぶ
してしまおうと?」 |
私はこの2人が外にいるのを見るのが好きだ。彼らはスタジオの中ではすごく退屈していた。それで彼らは奇妙なスローガンなんかをでっち上げはじめた。とあるフレーズを繰り返し 、それに執着した。そんな不自然なキツネのナンセンスは我慢できない。
これだけは言っておこう。私は本当にものごとを大学みたいにやろうと努めている。大学には行ったことがないので、自分の書く文章が学問の世界が要求する厳格な基準に合っている かわからないが、大学には友達がたくさんいて、中には研究で世界をまわっている人もいるので、彼らのハイカルチャーのブレンドに私の調子を合わせるように努めよう。
ときどき私は学のある友達を越える仕事をした自分に拍手を送る——人気のない廊下でだけだ。人前で頭突きしたりしない——私は実際 、学派がまだ彼らの本の中にしかなく変り続けているうちから受け入れてきた。
私はプリイベンチュアリストだ。私がそれに関わるようになってずいぶん長くなるし、そうしてきたことを良かったと思っている。あなた方の中にはすでにこの本にマルクス主義の記号を探し始めている人もいる ことだろう。残念ながらそのような解釈は切り捨てざるを得ない。しかしあなたの引き出したニヒリスト的結論はどんなものであれ、研究する価値があるだろう。
何にしても、レトリックを使うのはやめることにしよう。私がプリイベンチュアリズムに触れたのは、それが我々が我慢してきたポストモダニズムに対する新鮮でやさしい代替であるということを別にすると、この 超カルトがウィグズルの住人に無料の落とし物サービスを提供しているからだ。
require 'open-uri'
open( "http://preeventualist.org/lost" ) do |lost|
puts lost.read
end私はキツネたちにこのサービスのことを知らせる手段がない。彼らのトラックはすぐにこのリストに載ることだろうと思う。依然、ここには善意があるのだ。
あなたがインターネットに接続されているなら、上のRubyコードがそのWebページをインターネットからダウンロードして画面に表示するはずだ†。メッセージは以下のような内容だ:
†このサービスは現在は機能していない。
プリイベンチュアリストの遺失物記録簿
(啓発された人のための無料のサービス)
---
毎日更新されます。定期的にチェックしてください!
---
このサービスの一部は
アシュレー・レイモンド・ユース・スタディ・クランに
委託され援助を受けています
...
すべての標章と権利は
ポリウェイフ明け渡し執行官、ペリー・W・L・フォン・フローリングの
卓越した著述のもとに登録されています。彼はまた
ベガーズ・コミュニティ・カップに7回連続で優勝しています。
...
この記録簿について
==============
はじめての方はこれをお読みください。以下にサービスについての簡単な説明があります。最初に、我々の
愛すべき執行官から重要なお知らせがあります。(子どもたちはみんな彼をアンクル・フォン・ガファンクル
と呼んでいます。笑)
重要なお知らせ
===========
/ 2005年4月15日 /
大ニュースです。ウィグズルとオーディッシュ地域の8チャンネルに私たちは出ました。コーリーが見ていま
す。私が出て、それからジェリー・マザーズも出ました。見てなかったらコーリーにメールしてください。
彼が一番良く説明してくれるでしょう。私に言えるのは、これが私の手ぶりじゃないということです!! (チ
ャンネル8を見ている人たちのためのジョークです。) ハリーとチャンネル8ニュースチームの皆さんに感謝!!
- ペリー
/ 2005年4月7日 /
私たちは本部でカーペットを調べましたが、ケイトリンのクリップボードを見張っていたなら、彼女がそれ
を投稿するにはあまりに控えめな女性だとわかるでしょう。それは彼女にとってとても重要なことです。彼
女は夫の受け口を撮ったとても高価なパノラマX線写真を持っていて、受け口が もっと目立っていた頃に
旦那さんがロボコップのコスチュームを着て撮った大切な写真にクリップで留めていました。彼女は(私に)
「彼らがそれを見れば私の言ったことの意味がわかるわ」と言いました。私にはそれが何を意味するのかわ
かりません。 :(
私がチェックしたのは: * フロントデスク * ホール * 待合室 * トイレ * キャンディー入れ * 大型テレビ
のあたり * ランチカウンター * 見習いの部屋 * 軽業師の古い部屋(桜の木の絵のあるやつ) * サーバルー
ム * 階段。部屋をもっと見つけたらこのリストを アップデートします。
- 愛を込めて、ペリー
/ 2005年2月25日 /
サーバが3時に落ちました。私は君たちに腹を立てています。軽業師は下の階に直るまでいることでしょう :O
-- 追記: 直った。復帰したぞ!!
- ペリー
/ 2005年2月23日 /
今日はいろいろ騒ぎがありました。スタンリー兄弟サーカスは12頭のラマとトレーラーとたくさんのマスタ
ーキーと5つのテントをなくしました。彼らはまだなくなったものを探しています。冷静に。私はみんなの助
けが必要です。このエンターテナーたちは何も持っていません。文字通りに。今日私は男の1人に紫色
のステッカーをやりました(これは私がやさしいそぶりとしてするのを好んでいることです)。そして彼は実
際その上で眠り、ピザソースの材料をその上で育てています。彼らはどん底にいるのです。
だから寄付をお願いします。私たちはpaypalも何もありません。だから寄付したいと思ったら、何でもいい
から見つけたものを送ってください(子供用自転車とか、腐りやすいものの缶詰ひと月分とか)。そしてサー
カスの人たちの名前を上に書いておいてください。
- ペリー
/ 2004年11月15日 /
プリイベンチュアリストの日の売り出しです。今日何かなくしたら、誰か何かを見つけた人の家から(40ドル
以下の価値の)景品を1つ持ってくることができます。私たちはこれをすごく楽しんでいます!! 私は去年これ
でローイングマシーンを手に入れました。すごく気に入っています!!
- ペリー
ユース・スタディ・クランはこのサービスの運営をとてもよくやっていると思う。これはちょっといんちきで陳腐だが、動物たちが所有権を本能的な仕方で主張しあうのを止め られるのであれば、私は敬意を払う。
しかしプリイベンチュアリストは若者のグループなのだろうか? そんなことがありうるだろうか? プリイベンチュアリストになる前に、少なくとも本物の冷笑主義の洗礼を受ける必要がある。そしてまず学校には通えない。だから私には分からない。
プリイベンチュアリストの遺失物記録簿の解説に戻ろう。
L&Fサーバの使い方
===============
L&Fは無料のサービスです。ものをなくしたり見つけたりするのは、プリイベンチュアリストのライフスタ
イルを形作る不可欠なものです。あなたの信条に合うといいのですが。
私たちはHTMLは使いません。作業を簡単にするためです。私たちのスタッフはすでに1日15時間働いています。
(ターク、ありがとう!! ホレス、ありがとう!!)
あなたは私たちのサービスでなくしたものを探すことができます。また、なくした(あるいは見つけた)ものを
記録簿に追加することができます。これはしかるべきアドレスをブラウザに入力することで行います。
検索
====
なくしたものを検索するには、以下のアドレスを使います:
http://preeventualist.org/lost/search?q={検索語}
{検索語}を検索語で置き換えてください。たとえば"cup"を探すには以下のようにします:
http://preeventualist.org/lost/search?q=cup
そうすると、なくしたり拾われたりしたcupの一覧が表示されます。
なくしたcupだけ探したい場合や、拾われたcupだけ探したいという場合には、`searchlost'や`searchfound'
のページを見てください:
http://preeventualist.org/lost/searchlost?q=cup
私はゲームをしているわけではない。私はトラックがどこにあるのか知っている。本当に、あなたのことをじらしているわけではない。すぐに教えてあげる。ただキツネたちを見てと言っているだけだ。
![]() |
||
|
|
「この公園はシマウマのにおいがする」 |
彼らはお手上げだ。しかしここにすばらしいツールがある。この混乱から脱出するための鍵になるかもしれない。何か手がかりがないか探ってみたい。
require 'open-uri'
# 語`truck'を含む落し物をすべて検索する。
open( "http://preeventualist.org/lost/searchfound?q=truck" ) do |truck|
puts truck.read
endこのリストに背の高いキツネのトラックの情報はないようだ。それはかまわない。どうせキツネたちはぼうっとしているので、私たちには少し時間がある。
あなたはインターネットからWebページを取得する簡単なテクニックをすでに学んでいる。OpenURI
ライブラリを使うやつだ。これは私の好きなルビイストの1人である田中哲が書いたものだ。彼はインターネットから読むのを自分のコンピュータのファイルを読むのと同じ
くらいに簡単にしてくれた。
前の章で、あなたの極悪非道なアイデアをテキストファイルとして保存した。そのファイルはRubyでopenを使って読むことができる。
require 'open-uri'
# 自分のコンピュータのフォルダからアイデアのファイルを開く
open( "フォルダ/アイデア-教会の椅子にレタスを隠す.txt" ) do |idea|
puts idea.read
endファイルは入出力オブジェクトだ。あなたはファイルの読み書きができる。Rubyでは、すべてのIO(input-output)オブジェクトはreadメソッドとwriteメソッドを持っている。openメソッドはIOオブジェクトを滑り台でブロックの中に落とし、それを使えるようにする。IOは外の世界へのチケットだ。刑務所の鉄格子から差し込む日の光だ。(もっともあなたはOpenURIでWebページに書き込むことはできない。Webサーバにコピーするためのツールを見つける必要がある。たとえばFTPプログラムのような。)
教会の椅子にレタスを隠すことに関するあなたの極悪なアイデアを読みたい人がいて、あなたがそれをWebページとしてポストしていたと仮定すると、
require 'open-uri'
# Webサイトで読めるようになっているアイデアファイルを開く。
open( "http://your.com/idea-about-hiding-lettuce-in-the-church-chairs.txt" ) do |idea|
puts idea.read
end OpenURIライブラリはまた、FTPアドレスも解釈できる。これはあなたがファイルを保存できる場所の選択肢を広げてくれる。あなたのコンピュータの中でも、インターネット上のどこかでもいい。
ファイルを1行1行読む
あなたがOpenURIを使い、openメソッドとreadメソッドでWebから情報を得るとき、ページ
は1つのStringとして取得される。何かを探している場合や、ページが大きくメモリを節約したい
という場合には、ページを1度に1行ずつ読んでいくこともできる。
require 'open-uri'
open( "http://preeventualist.org/lost/searchfound?q=truck" ) do |truck|
truck.each_line do |line|
puts line if line['pickup']
end
end上のコードはpreeventualistのサイトで見つかったトラック(truck)のリストを取得し、語‘pickup’を含んでいる行だけを表示する。そのようにして記述を削 って、肝心な行だけを対象として探すことができる。
上の例はインデックスの角カッコを文字列に対して使い、角カッコの中の語を文字列の中に探す。角カッコの中身は文字列'pickup'なので、文字列lineの中で語“pickup”を探すことになる。
![]() |
||
「公園にいると少なくとも可笑しくしなきゃいけないないというプレッシャーは感じなくて済むね」 |
「我々は可笑しいということになっていたの?」 |
「でも今はこの新しい役がすごく気に入ってるよ——この本の破壊者だ!」 |
Webページがreadでロードされると、ページ全体がメモリに読み込まれる。通常
それは数千バイトにしかならない。しかしページが大きい(数メガバイトある)場合には
、たぶんeach_lineを使い、1度に1行ずつ読んでメモリを使いすぎるのを避けたいと思うだろう。
子ブロックへの委譲
Rubyでは、しばしばイテレータを次のような仕方で使う。イテレータは、配列やハッシュといったコレクションのそれぞれの要素を順にたどるときに使われる。IOの対象を行のコレクションと見なしてみよう。イテレータはこの行のコレクションを這い進むことができる。
class IO
# each_lineメソッドの定義。引数リストを持たないことに注意。ブロックは引数として
# 書いてもらう必要がない。
def each_line
until eof? # ファイルの終わりまで・・・
yield readline # 行をブロックに渡す
end
end
end yield
キーワードはブロックを使う一番簡単な方法だ。一語で済む。カーテンに引き紐があり、スーツケースにハンドルがあるのと同じようなものだ。メソッドの中で点滅するyield
ボタンを押すと、そのメソッドにくっついているブロックが実行される。ブロック内のコードが終了するまでボタンが強い赤色に輝く。それから点滅状態に戻る。やりたければ
ボタンをまた押すことができる。
def yield_thrice
yield
yield
yield
end yield ボタンを3回素早く叩き、ブロックは3回その人生を生きる。
irb> a = ['最初に生まれる。', 'それから明滅するイメージの人生。', 'そして最後に終わりを迎える。']
irb> yield_thrice { puts a.shift }
# 以下のようにプリントされる:
# 最初に生まれる。
# それから明滅するイメージの人生。
# そして最後に終わりを迎える。 shift メソッドは配列の最初の要素を引っ張り出す。shift
の床屋は髪を刈ってそれを手渡す。それから頭皮。それをずっと続けて、哀れな男が何もなくなるまで削っていく。
メソッドにくっついたブロックを見たわけだが、Rubyのメソッドはどれでも、後ろにブロックを付けることができる。
# メソッドにブロックをくっつける簡潔なスタイル。
# ここではブロックは中括弧で囲まれている。
open( "idea.txt" ) { |f| f.read }
# メソッドにブロックをくっつける冗長なスタイル。
# ここではブロックはdoとendで囲まれている。
open( "idea.txt" ) do |f|
f.read
end yieldに引数を渡すと、その引数はブロックにも渡される。ブロックはメソッドのオートバイに
取り付けられた小さなサイドカーに乗っている。砂漠を疾走する彼らに吹き付ける風の中、メソッドは引数リストを大声でブロックに向かって叫ぶ。ブロックは自分のヘルメットを叩いて、「わかったよ、ちゃんと頭に入った」と伝える。
# メソッドは2つのファイルを開き、結果のIOオブジェクトを滑り台でくっついたブロックの中に落とす。
def double_open filename1, filename2
open( filename1 ) do |f1|
open( filename2 ) do |f2|
yield f1, f2
end
end
end
# それぞれのファイルの中身を並べてプリントする。
double_open( "idea1.txt", "idea2.txt" ) do |f1, f2|
puts f1.readline + " | " + f2.readline
endあなたはyield
キーワードが道路標識と何の関係があるのかと不思議に思うかもしれない。それはいい質問だ。そしてそれにはいい答えがある。あなたがメソッドを実行するとき、あなたはそのメソッドに
プログラムのコントロールを渡している。コントロールして自分の仕事を為し、そして答えを持って戻ってくるようにと言っているのだ。
yieldでは、メソッドは交差点で止まり、コントロールをあなたに、あなたのブロックに返す。メソッドは仕事を再開する前にあなたに仕事をさせてくれる。だからeach_line メソッドがファイルから行を実際に読み込む仕事をする間、each_line
メソッドにくっついているブロックはその行を渡され、サイドカーの中でその行に対してせっせと作業するチャンスが与えられる。
金張りの箱の中のプリイベンチュアリズム
OpenURIや、yield
を使って自分のイテレータを書く方法について、あなたはずいぶんと学んだ。遺失物サービスを使う方法も分かっている。本当に、あなたはウィグズルのガラクタの引き出しを私なしで探せるようになっている。
このサービス全体を1つのクラスの中に包み込んでしまおう。
require 'open-uri'
module PreEventualist
def self.open page, query
qs =
query.map do |k, v|
URI.escape "#{ k }=#{ v }"
end.join "&"
URI.parse( "http://preeventualist.org/lost/" + page + "?" + qs ).open do |lost|
lost.read.split( "--\n" )
end
end
def self.search word
open "search", "q" => word
end
def self.searchlost word
open "searchlost", "q" => word
end
def self.searchfound word
open "searchfound", "q" => word
end
def self.addfound your_name, item_lost, found_at, description
open "addfound", "name" => your_name, "item" => item_lost,
"at" => found_at, "desc" => description
end
def self.addlost your_name, item_found, last_seen, description
open "addlost", "name" => your_name, "item" => item_found,
"seen" => last_seen, "desc" => description
end
endコードというのはある時点で何かきちっとした形に整えてやる必要がある。上のモジュールをpreeventualist.rbという名前で保存しよう。
このモジュールはプリイベンチュアリストのサービスを使うためのとてもシンプルなライブラリだ。これはまさにライブラリの書かれる仕方だ。モジュールかクラスを手早く作り、ファイルに収め、それが気に入って世界の人 たちにもその恩恵を分け与えたいと思うなら、それをWebにのっける。
私が前にOpenURIを使ったみたいに、あなたのモジュールは使うことができる。
irb> require 'preeventualist'
irb> puts PreEventualist.search( 'truck' )
irb> puts PreEventualist.addfound( 'ホワイ', 'Rubyのスキル', 'ウィグズル公園',
"Rubyのスキルが身に付けられます!\npoignantguide.netへお越しください!" )
2. 一方、ヤマアラシは給油に立ち寄っている
![]() |
||
「9番ポンプ」 |
|
「凧は売ってる?」 |
3. スポンサー付きのドラゴン退治
![]() |
||
|
「ぼくはドラゴンを退治した!」 |
「ドラゴンの顔をウィザブラムで吹き飛ばした」 ドッカーン 「シーッ! 友達が休んでるんだ!」 |
「何が幸運かってわかる? |
「考えてみてよ」とキツネ小が言った。「僕たちの中には冒険する時間がない人もいる。大きな責任を負っていたり仕事があったりするんだ。生活の手段ってやつだよ。わかる?」
「ヘーイ、ぼくの仕事はドラゴンを殺すことだったんだ!!」ちっぽけなウサギが叫んだ。目を瞬かせ、木から木へ、沼から沼へと半狂乱に跳ね回りながら。「やつの鼻は大きな責任だった!! やつの煙たい息はぼくが考慮すべき問題だった!! ぼくはあそこに行くだけでタクシー代に50ドル払った。これは大きな大きな試練だった。君はぼくにかなわない。批難できない。ぼくの英雄性は絶対的に非の打ち所がない。ぼくの手段全体が、絶対的にアンズ不能だ。レスターに聞いてみて」
「レスターって、誰?」とキツネ小が聞いた。
「レスターはタクシーの運転手さ! 彼はドウェムジーズアレイの基地に駐車したんだ!!」 ウサギはスーパーコンピュータのスクリーンセーバーみたいに狂ったように飛び跳ねた。「ドウェムジーに聞いて!!」、
「ふうん」とキツネ小が言った。キツネ大の方を振り向いて見ると、彼はまっすぐ腰掛けて遠くを見つめていた。「えっ、ドウェムジーズアレーに駐車場があるの?」
「そうとも!! それにプレッツェルスタンドも!!」
「だけど隊列なんでしょ? それがチュロを売ってるわけ?」
「チョコラバだ!!」ウサギが言った。
「じゃあ暗闇で光る紐は売ってる? 髪に付けたり、手に持ったりするやつ——」
「ブレイドクエスト!!」
「セールスマンのコミッションの分け前をもらうべきだよ」キツネ小が言った。「みんな君がドラゴンを殺すのを見に来たわけでしょ?」
「しかーし!! チョコラバを引っ張り出すやっとこはぼくがやってるわけじゃない」
「言っただけだよ。殺すところは君がやってるわけだよね。だったら君は分け前をもらう権利がある」
「あっ、しまった!! お気に入りのレタスをドウェムジーズアレイに置いてきた!!」ウサギが金切り声を上げ、揺れるオークの木の間を儀式用サーベルみたいにくるくる回った。遠くから「それともレスターのトランクかも?」と言った。
「ちょっとじっとしてられないの??」キツネ小が言った。
「僕のラジオは」キツネ大が一瞬生気を取り戻して言った。「ピックアップの中だ」。彼の目は相変わらずぼんやりしていた。彼の視線は震えた後に止まり、別な時間の別な場所を思い出していた。メリーランドへのドライブ 。ライオネル・リッチーの声がはっきりと聞こえる。ワイパーは動くのが少し早すぎる。家に車をつける。母親が戸口に出迎える。彼女はすごくふわふわしたキツネだ。涙とメーキャップ。
背もたれにどすんと寄り掛かった。「あのヤマアラシは私のプリセットを変えたに違いない」
ウサギはベンチのひじかけに飛び乗って、近くで話した。「しかし!! すぐにぼくはドラゴンの頭とドラゴンの舌のジュースを楽しむだろう!!」ウサギは静かに座って優しく手を握り合わせた。
「(シナモンバーみたいな味だといいんだけど)」ウサギが心から囁いた。
「シナモンなら好きだ」とキツネ小が言った。「僕もいつか君と一緒に殺しに行きたい」
「そうすべきだね」とウサギは言い、目を輝かせた。
「よだれだ。よだれを出してるんじゃない?」
「もちろん!!」ウサギは興奮して目からスティッキーウィップが飛び出した。(スティッキーウィップについては後の補足に書く。私が忘れているようだったら教えてほしい。ジョリー・パトリック・ソブゴブリンの「純粋主義者 のための新しい網膜クリームの概要」も参照。動物の飾り付きのクリップを置いているとこならどこでも手に入る。)
「ああ、すっかり興味を引かれちゃった。全部聞きたいね」キツネ小がきっぱりと言った。「エントチュについて話してよ。ああ、それにドウェムジーのことも。誰なの? 彼を動かしているものは何? それから僕がまだついていっているようなら、ウサギを動かしているものが何なのか教えて。そして僕たちの手を取って、なくしたトラックの試練を導いてほしい。僕は他のなによりも慰めを必要としてる。今だったら宗教だって信じるよ。君の勇敢さと君からにじみ出る達成感を僕は求めている。パイプは持ってる? 僕たちが結ぶ儀式の道具になるよ」
それからウサギはドウェムジーと、ドウェムジーの伝説と、ドウェムジーのやり方について詳しく説明しはじめた。ドウェムジーの話の多くと同様、ウサギの話は装飾だらけだった。スモッチキス、私だけが語るべき微妙な話があるのだ。
ドウェムジーが誰なのか決して聞かないでほしい。彼は明らかに黒幕で、その居場所や本当の素性を決して明かさない。彼は王国を持っている。彼は火の鬼を生み出した。馬はどこ にいても彼の臭いを感じ取る。なにより、彼は官能的な快楽を知っている。そしてこれが・・・
これが彼のアレイだ。
ドウェムジーズアレイ
![]() |
||
|
「ドウェムジーズアレイは最高だ!! |
「こいつは血の付いたパズルだ」 |
「演奏しながら俺は、耳を聾するスタンディングオベーションと深い個人的な涙の間を漂っていた」 |
あなたはドウェムジーズアレイの入り口に立っている。あなたはアレイの奥深くにいて死にかけているウサギだ。
class Dragon < Creature
life 1340 # タフさの度合い
strength 451 # 逆巻く血脈
charisma 1020 # 歯を見せる笑顔
weapon 939 # 炎の息
end激しく渦巻く溶岩が不協和音を立てて坑道を通りドウェムジーの森の永遠の天蓋の中に深く入り込み・・・飢えた野生のストーキュパインの腹から 脆い夜の叫びが聞こえ・・・グラハムクラッカーを食べてお昼寝したすぐあとの湿ったガチョウの子を食べる・・・正式には孤児だが自動車販売代理店のコングロマリットの所有する傘に守られ た飢えているカバの中・・・どろどろした青いエリクサーの蓋をしていない小瓶の下に・・・とどまりつづける・・・これまで・・・乱されることのな かった・・・ドウェムジー!!!
![]() |
||
|
「自分の幸運をそんなに鼻にかけるものじゃないよ・・・そんなのいつでもなくなってしまう」 |
「実際はそうじゃない。幸運は魅力があって、人々をヒーローの目で見るときにやってくるんだ。そして木の精と母なる自然が幸運を与えてくれるんだ」 |
「僕がドラゴンなら、間違いなく木の精と母なる自然を最優先の仕事として殺すね」 |
ドウェムジーズアレイがわからないなら、それはドウェムジーの問題だ。彼は私たちの人生を複雑にするためにこのゲームをデザインしたのだ。単純なものだったら、私たちが腕に大切に抱 いて畏敬の念を感じる冒険とはならないだろう。
ドウェムジーズアレイにはとても深く曲がりくねった歴史がある。単純に「ドウェムジーズアレイ」と繰り返すだけでは信任状を得るのに十分ではない。私についてきて欲しい。何年かさかのぼ り、それがメタプログラミングとイルカで始まった60年代に連れて行ってあげよう。
あなたはメタプログラミングというのはファックス機の間で私用の電話をしたときにはじめて耳にしたハッカーの言葉だと思うかもしれない。ほんとのところ、真実 はそれよりもっと奇妙だということを話すために私はここにいる。メタプログラミングはイルカのいるところでドラッグをやっていたときに生まれたのだ。
60年代にジョン・C・リリーという多産な科学者が、体の仕組みを調べようと自分の感覚を材料に実験し始めた。私はこれに関係がある。道の真ん中にパイを持って立っているとき、あるいは聖堂の中に隠れているときに、私はこれを良くやる。私は自分自身を調べるために立ち止まる。これはほとんど不可能なことが証明された。私は罫線入りのノート3ページを代数式で埋めたが、そのどれも何も説明しはしなかった。ついでながら、パイというのは、数学的にとても容易に表現できる。
しかし科学者のリリーは実験を別の方向に進めた。彼はイルカと一緒にいるときにLSDを摂った。ときには暖かい海水で満たされた暗く悲痛な隔離タンクの中で。 すごく寒々としている。しかしそれは科学だったのだ! (彼が犯罪者だとは考えないことだ。1966年までは、Sandoz Laboratoriesが誰でも関心のある科学者にただでLSDを配っていたのだ。)
ドラッグ、イルカ、そして喪失。それがリリーの探索をメタなものに向けた。彼は、人とコンピュータを比較するメンタルプログラミングに関する本を書いた。あなたは次の引用を読む間に摂取するものを選んでいい——ほとんどの場合ひとつまみの塩に手を伸ばすだろう——しかし 芝生の上でグレートフルデッドのショーがあったり、熱狂的な人たちが地下室にあふれたりすることはないと請け合おう。
人が学ぶことを学ぶとき、人はモデルを作り、シンボルや、アナロジーを使い、メタファーを作り、つまり、言語や数学やアートや政治やビジネスなどを作り、利用する。脳(皮質)のサイズの上で大きな部分 を言語とそれにかかわる部分が占めている。学ぶことを学ぶこと、シンボル、メタファー、モデルといちいち繰り返すのを避けるため、これらの働きの基本になっているアイデア をメタプログラミングという記号で表すことにする。
ジョン・C・リリー、人間バイオコンピュータにおけるプログラミングとメタプログラミング、
ニューヨーク、1972年
私たちは学ぶ。しかし最初に学ぶことを学ぶ。私たちは心の中にプログラミングをセットアップし、それがプログラミングをさらに推し進めるための道となる。(リリーは 主として、彼がバイオコンピュータと呼ぶ脳と神経システムのプログラミングについて話している。)
リリーのメタプログラミングというのはむしろ、心象を与えるとか、自分自身を再構築するといったことだった。このような思考は、シャーマニズムに手を出し、タロットカードの上に手をかざし、空手の練習のために早起きする人々 に直接繋がるものだ。メタプログラミングはニューエージだと言 えるかもしれないが、それは最近では古き良きナード性とともに寝袋の中に収まっている。(あなたがGoogleで「C++ Metaprogramming」と検索してここに来たのなら、もう少し我慢してほしい。ただあなたにその検索をさせた神経経路は燃やしてしまってくれ。どうもありがとう。)
メタ自体は著者の時代でも違いなく語られている。
現実に対する感覚的反応というのはすべて、現実の解釈だ。甲虫もサルも彼らの世界を明らかに解釈している。そして彼らが理解したものに基づいて行動している。私たちの 身体的感覚はそれ自体解釈の器官なのだ。私たちを動物と区別しているのは、それらの解釈を解釈できるという私たちの能力だ。その意味で、人間の言語はすべてメタ言語なのだ。それは我々の体、我々の 感覚器官の「言語」の二次的な反映なのだ。
テリー・イーグルトン、理論のあと、ロンドン、2003年、第3章
その意味で、プログラミング自体メタ言語だと言うことができる。すべてのコードは、行動の言語を、まだ行われていないが間もなく行われるプランの言語を語る。マシンの中の役者 たちの舞台演出だ。私は以前これ をセンチメンタルに捉えていた。
しかし今では私たちの研究も進み、メタプログラミングの世界へと歩を進めているが、恐れることはない。それは依然としてあなたが見てきたRubyと違わない。それがドウェムジーがあなたにそれを押しつけることに呵責を感じない理由だ。すぐにそれは、足し算や引き算と同じくらい簡単にわかるようになる。最初それは、顔の方に飛んでくる蛍をはじめて見 たときのように、強烈に明るく見えるかもしれない。それから、それはオハイオでの暮らしをずっと良くしてくれる小さな揺れる光になる。
メタプログラミングとはコードを書くコードを書くということだ。しかしそれはM・C・エッシャーがスケッチするようにではない。プログラムは前に戻って自分自身を上書きすることはないし、画面から飛び出してあなたの手からキーボードをひったくることもない。それよりはずっと小さなことだ。
それはむしろあなたがサーカスで手に入れた小さなオレンジ色の錠剤に似ている。それを口に入れると、コーティングが溶けて、歯の裏側で大きな柔らかいスポンジのブロントサウルスが出てくる。それがあなたの舌を滑り降りて自由に飛び回り、草地をはしゃぎ回 って、「パパ!」と叫ぶのだ。そしてそれ以来、彼がイライラしてトラックを襲うときには、そのトラックはきれいな火花を散らすことだろう。
誰かが小さなオレンジ色の錠剤を水道の下に置いたとする。自分の舌の上にではなく、水道の下にだ。これは別な変化をもたらす。泣き叫ぶスポンジの八つ子を生む。へその緒や何やかや。それでもトラックを片づけるのには手頃だ。しかしまったく違った種類のシャモアだ。そしてある日、この8匹は、バイオリン演奏会 に出てパパに涙を流させる。
メタプログラミングはコードを錠剤の形に詰め込み、ほんのちょっと水を垂らすだけで広がりはじめる。さらに重要なのは、錠剤の反応をコントロールできるということで、鱗 のあるのっそりしたブロントサウルスが作られるようにできる。あるいはもちろん八つ子でもいい。あるいはお針子でも。あるいは猫の脳みそでも。あるいはドラゴンでも。
class Dragon < Creature
life 1340 # タフさの度合い
strength 451 # 逆巻く血脈
charisma 1020 # 歯を見せる笑顔
weapon 939 # 炎の息
endこれはまだメタプログラミングではない。ただの錠剤だ。メタプログラミングの結果だ。いったん立ち止まって怪物自体を見てみることにしよう。メスと顕微鏡を使って肉体の内部へと進む前に。
Dragon はクラスだ。もう何度も見ているだろう。Dragon
はCreature
クラスの子孫だ。
目を上げて、私を見て。Creature
クラスはメタプログラミングコードを含んでいる。あなたはRubyのどこででも使えるメタプログラミングコードを書くことができる。CreatureやDragonの中でも、Stringの中でも、Objectの中でも、どこででもだ。ここで挙げる例では、メタコードの最も一般的な形態である、自分のクラスの中でだけ使うメタプログラミングに焦点を当てる。
Dragonの特徴のそれぞれはただのクラスメソッドだ。
これは次のように書くこともできる:
class Dragon < Creature
life( 1340 ) # タフさの度合い
strength( 451 ) # 逆巻く血脈
charisma( 1020 ) # 歯を見せる笑顔
weapon( 939 ) # 炎の息
end括弧を取った方がすっきりするので、括弧は省略することにする。メソッドをいくつかまとめて使うのではっきりさせたいという時だけ括弧を使うようにしよう。
Creatureのコード
横隔膜のところでスライスしてCreatureの内部を見せよう。このコードをdwemthy.rbという名前で保存して。
# ドウェムジーズアレイの生命力の中心
class Creature
# このクラスのメタクラスを取得する
def self.metaclass; class << self; self; end; end
# 特徴(trait)を素敵できれいに表現するための先進的なメタプログラミングコード
def self.traits( *arr )
return @traits if arr.empty?
# 1. それぞれの変数にアクセサを用意する
attr_accessor *arr
# 2. それぞれのtraitにクラスメソッドを追加する
arr.each do |a|
metaclass.instance_eval do
define_method( a ) do |val|
@traits ||= {}
@traits[a] = val
end
end
end
# 3. それぞれのモンスターについて、initializeメソッドはそれぞれのtraitの
# デフォルトの値を使う
class_eval do
define_method( :initialize ) do
self.class.traits.each do |k,v|
instance_variable_set("@#{k}", v)
end
end
end
end
# Creatureの属性はリードオンリー
traits :life, :strength, :charisma, :weapon
end最後の行に注目してほしい。つまりtraits
をセットアップしている行だ。その前にあるコードはすべてtraits
クラスメソッドをセットアップしている。これは前の章のLotteryTicketを思い出させる。
class LotteryTicket
attr_reader :picks, :purchased
end traits とattr_reader のどちらも単なるクラスメソッドだ。attr_reader がLotteryTicketで使われたとき、裏ではメタプログラミングが動き出して、風船を膨らませ、インスタンス変数 @picks
と@purchased に対するリーダーメソッドを作り出していた。
traitsメソッドのコードは私がずっと仄めかしていたメタプログラミングだ。コードのコメントが、traitsを追加するときにたどる3つの段階を明らかにしている。
-
traitsのリストが
attr_accessorに渡され、それぞれのインスタンス変数に対するリーダーのコードとライターのコードを生成する。 - それぞれのtraitに対してクラスメソッドが追加される(たとえば
lifeクラスメソッドが:lifeに対して追加される)。これらのクラスメソッドはあなたがtraitsやattr_accessorを使うのと同じようにクラス定義で使われる。このようにしてそれぞれのcreatureとtraitの組に対してポイントを指定 できるようになる。 - 初期化メソッドを追加して新しいモンスターのプロパティをセットアップし、適切なポイントを与え、そして——パワーアップ! パワーアップ! モンスターが生きてるぞ!
この3ステップの素晴しいところは、あなたがRubyにモンスターのコードをどう書けばいいのか教えているということだ。Rubyがtraitsのところに来ると:
class Creature
traits :life, :strength, :charisma, :weapon
endRubyは裏でコードを埋め、トゲだらけの緑色の心臓を移植し、プルコードを引いて体をジャンプスタートさせる。RubyはCreature
クラスのメタプログラミングを使い、様々なメソッドを作り出し、traitsリストを次のような形に展開する:
class Creature
# 1. リーダ / ライタ メソッドを用意する
attr_accessor :life, :strength, :charisma, :weapon
# 2. creatureの中で使う新しいクラスメソッドを追加する
def self.life( val )
@traits ||= {}
@traits['life'] = val
end
def self.strength( val )
@traits ||= {}
@traits['strength'] = val
end
def self.charisma( val )
@traits ||= {}
@traits['charisma'] = val
end
def self.weapon( val )
@traits ||= {}
@traits['weapon'] = val
end
# 3. initializeはそれぞれのtraitにデフォルトのポイントを設定する
def initialize
self.class.traits.each do |k,v|
instance_variable_set("@#{k}", v)
end
end
endそうすると、トランプに印刷したらぴったりなくらい短いこの6行のDragon のコードを、Rubyは喜んで受け入れるようになる。
class Dragon < Creature
life 1340 # タフさの度合い
strength 451 # 逆巻く血脈
charisma 1020 # 歯を見せる笑顔
weapon 939 # 炎の息
end
Eval - 最小のメタプログラマ
メタプログラミングのコードは普通のRubyではあるが、追いかけるのは難しいかもしれない。この時点であなたの目が眼窩の中でぐるぐる回り、膝が動かなくなっていたとしても理解できる。上のコードで一番トリッキーなのは、instance_evalメソッド とclass_evalメソッドを呼んでいるところだ。私がevalについて説明している間、
関節にタイガーバームでも塗っておくといい。
私たちはメタプログラミングの話をしている。コードを書くコードを書くということだ。evalメソッドはこの横町に出入りしている。さすらいのevalはあなたが文字列の中に収めたコードを受け取ってそのコードを実行する。
drgn = Dragon.new
# これは次のように書くのと同じだ・・・
drgn = eval( "Dragon.new" )
# あるいは、こう書いてもいい・・・
eval( "drgn = Dragon.new" )穴の開いたプログラムを書いてみることにしよう。新しいDragonを作るプログラムを書くかわりに、Dragonが入る部分を穴にしておくのだ。
print "どのモンスタークラスと戦いますか? "
monster_class = gets
eval( "monster = " + monster_class + ".new" )
p monster(訳注: 変数monsterが前に使われていないとp monsterが未定義の変数エラーになる)
このプログラムはモンスターの名前を尋ねる。あなたがDragonとタイプすると、monster_class 変数に文字列"Dragon"が設定される。evalの中でいくつかの文字列がつなぎ合わされて、"monster =
Dragon.new"という文字列ができる。そしてevalが実行されると、monster変数にはDragon オブジェクトが設定され、戦いの準備ができる。
これはすごい! いまやプレーヤーがモンスターを選べるようになったのだ!
もちろんこれはプレーヤーが実在するモンスタークラスを指定してくれることを当てにしている。彼らがBotanicalWitch
(植物女)とタイプしてBotanicalWitchクラスがなかったなら、彼らは顔に例外をたたきつけられることになる。
簡単に言うと、evalは実行するその場でコードを作ることができるのだ。これは有用であり、かつ危険でもある。
Creatureクラスのメタプログラミングで使われていたinstance_evalメソッドとclass_evalメソッドは、ただのevalと若干異なっている。これらの2つの特別なメソッドはeval
と同じようにコードを実行させるが、しかしクラスやオブジェクトの中に入り込んで、そこでコードを実行するのだ。
# instance_evalメソッドはオブジェクトのインスタンスメソッドの中であるかのように
# コードを実行する
irb> drgn = Dragon.new
irb> drgn.instance_eval do
irb> @name = "Tobias"
irb> end
irb> drgn.instance_variable_get( "@name" )
=> "Tobias"
# class_evalメソッドはクラス定義の中であるかのようにコードを実行する
irb> Dragon.class_eval do
irb> def name; @name; end
irb> end
irb> drgn.name
=> "Tobias"上で見てわかるとおり、instance_evalメソッドとclass_evalメソッドは文字列のかわりにコードブロックを取ることもできる。それがドウェムジーズアレイでものごとがなされる仕方なのだ。
人を見くびった解説や意味ありげな併記はもう十分だ——ドウェムジーズアレイはどこにあるんだ??
注意して歩いて——ここにドウェムジーズアレイの残りの半分がある!!
このコードをdwemthy.rbに追加して。
class Creature
# このメソッドは戦いで受けたダメージを適用する
def hit( damage )
p_up = rand( charisma )
if p_up % 9 == 7
@life += p_up / 4
puts "[#{ self.class }は魔法で#{ p_up }パワーアップした!]"
end
@life -= damage
puts "[#{ self.class }は死んだ。]" if @life <= 0
end
# このメソッドは戦いの1ターンを行う
def fight( enemy, weapon )
if life <= 0
puts "[#{ self.class }は戦うには死にすぎている!]"
return
end
# 敵を攻撃
your_hit = rand( strength + weapon )
puts "[あなたの攻撃は#{ your_hit }ポイントのダメージを与えた!]"
enemy.hit( your_hit )
# 敵の反撃
p enemy
if enemy.life > 0
enemy_hit = rand( enemy.strength + enemy.weapon )
puts "[敵の攻撃で#{ enemy_hit }ポイントのダメージを受けた!]"
self.hit( enemy_hit )
end
end
end
class DwemthysArray < Array
alias _inspect inspect
def inspect; "#<#{ self.class }#{ _inspect }>"; end
def method_missing( meth, *args )
answer = first.send( meth, *args )
if first.life <= 0
shift
if empty?
puts "[ワオ。あなたはドウェムジーズアレイを全滅させた!]"
else
puts "[準備して。#{ first.class }が現れた。]"
end
end
answer || 0
end
endこのコードはCreatureに2つのメソッドを追加する。hit メソッドは他のCreatureからの攻撃に対応する。fightはそのCreatureに対してあなたの一撃を加える。
あなたのCreature が攻撃を受けると、防御が働いて、charisma
値を使ってパワーアップする。この現象の背後にある秘密については聞かないでほしい。乱数が選択されて単純な算術が行われる。あなたが幸運なら、何ポイントかライフポイントが手に入る。@life += p_up / 4。
それから敵の攻撃が来る。@life
-= damage。これがCreature#hitメソッドの働く仕組みだ。
fight メソッドはまず自分のCreature
が生きているか確認する。それから敵に対してランダムな攻撃を加える。敵は攻撃をしのぐと、反撃のチャンスを得る。これがCreature#fightメソッドの働く仕組みだ。
DwemthysArray
についてはすぐに説明する。ほんとにするって。そうするのが楽しいんだ。しばらくhitしたりfightしたりしていよう。
あなたを登場させる。
あなたはこのウサギの派生物をいじり回してもいい。しかしドウェムジーの公式な範例では、そのコードは——そしてキャラクタ
の全体が——明示的に以下のように記述されている。これをrabbit.rbという名前で保存しよう。
class Rabbit < Creature
traits :bombs
life 10
strength 2
charisma 44
weapon 4
bombs 3
# 小さなブーメラン
def ^( enemy )
fight( enemy, 13 )
end
# 英雄の剣は無制限だ!!
def /( enemy )
fight( enemy, rand( 4 + ( ( enemy.life % 10 ) ** 2 ) ) )
end
# レタスはあなたの体力を上げ、余った葉っぱは敵の顔に飛んでいく!!
def %( enemy )
lettuce = rand( charisma )
puts "[ヘルシーなレタスであなたの体力が#{ lettuce }ポイント回復した!!]"
@life += lettuce
fight( enemy, 0 )
end
# 爆弾。ただし3つしか持っていない!!
def *( enemy )
if @bombs.zero?
puts "[うわっ!! 爆弾が切れた!!]"
return
end
@bombs -= 1
fight( enemy, 86 )
end
endあなたには4つの武器がある。ブーメラン。英雄の剣。レタス。それに爆弾だ。
はじめるには、irb を起動して、ここまでで作ったライブラリをロードしよう。
irb> require 'dwemthy'
irb> require 'rabbit'それから、あなた自身を展開する。
irb> r = Rabbit.new
irb> r.life
=> 10
irb> r.strength
=> 2いいぞいいぞ。
ウサギはスキューバアルゼンチンと戦う!
あなたはシートベルトもせず、香水を付けただけでドウェムジーズアレイに突入するむわけにはいかない。悪魔のカドリールを慎重に進む必要がある。あるいは南の藪と石炭の迷宮を通り抜ける必要がある。
とりあえずは、こっそり水路の白い残留物に隠れよう。そしてScubaArgentineに忍び寄るのだ。
class ScubaArgentine < Creature
life 46
strength 35
charisma 91
weapon 2
end戦いを始めるには、あなたを1つと、ScubaArgentineを1つ作る。
irb> r = Rabbit.new
irb> s = ScubaArgentine.newよし、小さなブーメランで攻撃だ!
irb> r ^ s
[あなたの攻撃は2ポイントのダメージを与えた!]
#<ScubaArgentine:0x808c864 @charisma=91, @strength=35, @life=44, @weapon=2>
[敵の攻撃で28ポイントのダメージを受けた!]
[Rabbitは死んだ。]なんてことだ!! 私たちのウサギが死んでしまった!!
無慈悲な展開だ。だけどあなたにウサギの国に帰ってくれと言うわけにもいかない。あなたが死ななかったふりをして、新しいウサギを作ることにしよう。
irb> r = Rabbit.new
# ブーメランで攻撃!
irb> r ^ s
# 英雄の剣が切り裂く!
irb> r / s
# レタスを食べて体力が回復!
irb> r % s
# 爆弾が3つある!
irb> r * sこれはなかなかかっこいいと思わない? rabbit.rbのコードは算術記号を置き換えてRabbitだけの特別な使い方をしている。Rubyでは算術オペレータの振る舞いを変えることができる。なんにしても、算術オペレータはメソッドにすぎないのだ!
# ブーメランは通常はXORオペレータだ。 irb> 1.^( 1 )
=> 0
# 英雄の剣は通常は数を割る。
irb> 10./( 2 )
=> 5
# レタスは割り算の余り。
irb> 10.%( 3 )
=> 1
# 爆弾はかけ算だ。
irb> 10.*( 3 )
=> 30
そうするのが適切である場合には、自分のクラスで算術オペレータを使って構わない。Rubyは算術オペレータをいろいろなクラスで使っている。たとえば配列もいくつかの算術オペレータを持っている。ri Arrayでインスタンスメソッドの一覧を出せば見ることができる。
# プラスオペレータは2つの配列を組み合わせて1つの配列にする。
irb> ["D", "W", "E"] + ["M", "T", "H", "Y"]
=> ["D", "W", "E", "M", "T", "H", "Y"]
# マイナスは2番目の配列の要素をすべて最初の配列から取り除く
irb> ["D", "W", "E", "M", "T", "H", "Y"] - ["W", "T"]
=> ["D", "E", "M", "H", "Y"]
# かけ算は配列の要素を繰り返す
irb> ["D", "W"] * 3
=> ["D", "W", "D", "W", "D", "W"]あなたはこれが数学的にどういう意味があるのかと不思議に思っているかもしれない。配列に3を足したらどうなるのか? 文字列に数を足したら? Rubyはどう反応するのだろう?
これらのオペレータが単なるメソッドであることを思い出してほしい。これらのオペレータは読める言葉になっていないので、それが何をするのか言い当てるのは少し難しくなる。riを使おう。あなたは
これらのオペレータがしばしば他の読める名前を持ったメソッドと同じであることに気付くだろう。オペレータとメソッドで好きな方を選んで使えばいい。よりわかりやすいと思える方を。
# 割り算するのにオペレータメソッドを使うか・・・
irb> 10 / 3
=> 3
# ・・・あるいは読めるメソッドを使うか?
irb> 10.div 3
=> 3Rabbitの剣が割る仕方も同じことだ。
ドウェムジーズアレイの厳しい現実があなたを叩き潰そうと待ちかまえている!!
最後のやつを酸素チューブを使ってプレイチョークをかけて片づけたら、アレイに入る時だ。私はあなたにやれるか疑問に思っている。あなたは戦斧を家に置いてきてしまった。あなたが弱いやつ相手に爆弾を全部使っ たりしていないことを願っている。
あなたには6匹の敵がいる。
class IndustrialRaverMonkey < Creature # 工業的乱痴気モンキー
life 46
strength 35
charisma 91
weapon 2
end
class DwarvenAngel < Creature # ドワーベンエンジェル
life 540
strength 6
charisma 144
weapon 50
end
class AssistantViceTentacleAndOmbudsman < Creature # 副アシスタント触手オンブズマン
life 320
strength 6
charisma 144
weapon 50
end
class TeethDeer < Creature # 歯ジカ
life 655
strength 192
charisma 19
weapon 109
end
class IntrepidDecomposedCyclist < Creature # 恐れを知らぬ腐りかけのサイクリスト
life 901
strength 560
charisma 422
weapon 105
end
class Dragon < Creature # ドラゴン
life 1340 # tough scales
strength 451 # bristling veins
charisma 1020 # toothy smile
weapon 939 # fire breath
endこれがドウェムジーズアレイに生き、呼吸しているモンスターたちだ。彼らがどうやってここに来たのかは知らない。誰も知らないのだ。IntrepidDecomposedCyclist
はきっと10段変速に乗ってきたんだろうと思うが、他のやつについてはわからない。
どうしても知る必要があるというのなら、他のやつはここで生まれたのだということにしておこう。先に進んでもいい?
ドウェムジーズアレイに深く入っていくほど、挑戦はどんどん難しくなっていく。
dwary = DwemthysArray[IndustrialRaverMonkey.new,
DwarvenAngel.new,
AssistantViceTentacleAndOmbudsman.new,
TeethDeer.new,
IntrepidDecomposedCyclist.new,
Dragon.new]闘い進むにつれ、モンスターが次々と現れてくる。あなたが素早ければ、天使のかぎ爪に肩を貫かれることなく、恐ろしい話を持って逃げ帰ることができるかもしれない。
でははじめよう。
irb> r % dwaryああ、それから「私は死ぬには若すぎる」というのはなしだ。そんなくだらないことは聞きたくない。私はあなたに若き亡者たちを侮辱させるつもりはない。彼らは私たちの未来だ。我々の未来が終わったら、それが来るのだ。
![]() |
||
|
「行こう。あのウサギは何て?」 |
「ワオ。それはすごい偉業だな。彼はこの日を一生忘れることはないだろう」 |
「みんなぼくがいかに幸運か噂してる!」 |
ドウェムジーズアレイの作り方
風が止むところまで早送りしよう。ドラゴンは撃破された。卑しき輩たちはひれ伏している。私たちはあなたを好きだ。あなたに忠誠を尽くす。
しかしあなたの鼓膜を食い破っているムカデは何? 指でほじっても、そいつを追い出すことができない! なんてことだ! 地獄のドウェムジーズアレイがまた現れた。正体を現せ、ドウェムジー!
ここにアレイの正体を暴露しよう。
class DwemthysArray < Array
alias _inspect inspect
def inspect; "#<#{ self.class }#{ inspect }>"; end
def method_missing( meth, *args )
answer = first.send( meth, *args )
if first.life <= 0
shift
if empty?
puts "[ワオ。あなたはドウェムジーズアレイを全滅させた!]"
else
puts "[準備して。#{ first.class }が現れた。]"
end
end
answer || 0
end
end今では、あなたも継承に慣れ親しんでいると思う。DwemthysArray
クラスはArray を継承し、Array
のように振る舞う。あんなミステリーであるにしては、中身は驚くほど簡単だ。そうじゃない?
つまりはArrayということだ。モンスターでいっぱいの。しかしここで追加されているコードは何なのだろう?
Inspect
inspectメソッドはドウェムジーズアレイに本当に必要なものというわけではない。これはアレイのお客様へのサービスとしてドウェムジーが追加したものだ。(多くの人が彼をねじけていると言い、多くの人が彼を陰鬱だと言うが、彼が私たちのためにしつらえてくれた処置に敬意を感じないとしたら、私たちは無知のそしりを逃れないだろう。)
Rubyのオブジェクトはみなinspect メソッドを持っている。これは
![[o]](images/chapter.poignant.guide-6.jpg)









