Rubyのinstance_evalメソッドについて分かってきたような気もするが疑問も増えた

 Rubyのinstance_evalがブロック内のテキストを評価してレシーバーであるインスタンスの元で実行するメソッドであるということは、irbを叩いてなんとく理解できつつあるような気がします。しかし、逆に「何故そうなるのか?Why?」という疑問も増えてきました。
 

メソッド

 以下のように定義したメソッド”aaa”はStringクラスのインスタンス”str”の特異メソッドになるようです。

str = "hoge"
str.instance_eval{def aaa; puts "a";end}
str.aaa
⇒"a"

 しかし、このインスタンスメソッド”aaa”で返された”a”は文字列であるはずなので、Stringクラスかと思いきや、NilClassらしくて、この理由がよくわからないんですよね。 

str.class
⇒String
str.aaa.class
⇒NilClass</del>

 
  ちなみにFixnumクラスを返すはずのインスタンスメソッド”bbb”でも同じ結果です。 

str.instance_eval{def bbb;puts 1;end}
str.bbb
⇒1
str.bbb.class
⇒NilClass</del>


追記
「putsの戻り値がnilだからでは」というコメントをいただきました。試してみると確かにその通りでした。失礼しました。

str = "hoge"
str.instance_eval{def aaa;"a";end}
str.instance_eval{def bbb;1;end}
str.aaa.class
⇒String
str.bbb.class
⇒Fixnum

 

定数

  インスタンスの中で定数を定義してみます。正直、インスタンスの中で定数を定義することの意味がまだよくわかりませんが、一応可能なようです。これは特異定数というか、インスタンス定数という感じになるのでしょうか・・・?
 

str.instance_eval{AAA = "ccc"}

 
この定数”AAA”はどこで定義されてだろうか?
どうやって参照するのだろうか?
 疑問が次から次へと出てきて止まりません。 

クラス – class_evalとの違い –

 さらにこのインスタンス”str”の中でクラスを作ってみたいと思います。
 

str.instance_eval{class BBB;end}

BBBクラスのインスタンスはつくることができます。

b = BBB.new
b.class
⇒BBB

Objectクラスのすぐ下にクラスが作られるんですね。Stringクラスのインスタンス”str”の中で作られるので、Stringクラスのサブクラスとして生成されるかと思っていました。

BBB.ancestors
⇒[BBB,Object,Kernel]

 
 もう少し深く考えるとこの辺の挙動が理解できそうなのですが、今のところ???状態です。
 ちなみにクラスはClassクラスのインスタンスでもあるので、instance_evalを用いるとこんな感じになります。

CCC = Class.new
#これでCCCクラスの生成。
CCC.class ⇒Class
#CCCはClassクラスのインスタンス

 Classクラスのインスタンス、”CCC”にメソッドと定数を定義しています。

CCC.instance_eval{def ccc;puts "123456";end}
CCC.ccc
⇒"123456"
CCC.instance_eval{EEE = "789101112"}
CCC::EEE
⇒"789101112"

 
 それぞれクラスメソッドとクラス定数として定義されているようです。クラスメソッドに定義されるのはClassクラスのインスタンス”CCC”の特異メソッド(=クラスCCCのクラスメソッド)として定義されているからです。Classクラスのインスタンスをレシーバーにする限り、instance_evalとclass_evalと違いは無いような気がする。どうなのだろう?  
 
 

「書籍」と呼ぶには短い電子書籍というコンテンツと従来よりちょっと長くなったWebというコンテンツの相対的な関係

 10月にリリースされるというAppleのiOS5のアップデート、噂されるiBooksのEPUB3対応は当然すごく期待するところですが、それに加えてSafariのリーダー機能、結構面白いのではないかと思います。
Safariのアイコン

さらに快適なネットサーフィンを。
iOS 5は、iPhone、iPad、iPod touchでのネットサーフィンにさらなる新機能を加えます。例えば、Safariのリーダー。広告や不要なものが表示されないので、ウェブの記事だけに集中できます。リーディングリストは、あとでじっくり読むために記事を保存できる機能で、iCloudにはすべてのデバイスから集めた最新のリーディングリストが保存されます。iPadではタブを使うこともできるようになったので、複数のウェブページを開いて、思いのままに切り替えていけます。さらにiOS 5では、どのiOSデバイスでもSafariのパフォーマンスが向上しました。

 リーダーという機能はPC版のSafariですでに実装された機能ですし、iPad上でもすでにInstapaperが同じような機能を実現していますが、PCよりも「読む」という行為に適したインターフェイスであるタブレット端末の標準のブラウザで実装されることに意味があるのかと思うのです。
 Webコンテンツは、これまでこんな感じでこれまで垂直に立てられたモニター上で読むことを前提に作られてきたわけです。
垂直に立てられたモニター上でウェブを閲覧している人間を横から示した図
 目とコンテンツの距離姿勢(特に首の角度)に注目してほしいのですが、この上のようなインターフェイスは「読む」というよりも「作業をする」、もしくは「見る」という行為に適したインターフェイスではないかと。このインターフェイスはWebというコンテンツの有り様を大きく規定してきたのではないでしょうか。
 タブレットPCはこんな感じでコンテンツと目の距離といい、読むときの首の角度といい、書籍にインターフェイスが近いですから、Webというコンテンツの有り様を規定する前提が崩れてしまうかもしれません。
紙の書籍を読んでいる人間を横から示した図
タブレットPCでWebを閲覧する人間を横から示した図。本を読む状態に近いことを示している
 タブレットPCで標準で搭載されているブラウザに「リーダー」のような「読む」ことに集中できる機能を実装されるようになると
 
Webが、より「読む」コンテンツに
 
 となるかもしれません。つまり、少々長くなっても読むことが苦にならなくなるので、コンテンツが少し長くなるかもということです。 
 一方で・・ということで今度は電子書籍という器に話を移します。同じ端末で電子書籍を読むためのiBooksを利用できるわけですが、同じインターフェイス上で「読む」コンテンツである以上、Webと「書籍」はどういう関係になっていくのでしょうか。
 電子書籍という器はWebよりも長く、本より短いサイズのコンテンツに強みを発揮するような気がします。電子書籍のメリットとして上限がないことはよくいわれることです。量が増えても物理的サイズがふえるわけではないので、そういった制約はほとんどないと。
 しかし、逆に量の少ないコンテンツはどうでしょうか。紙の本でも数ページから数十ページという量の少ない冊子を作ることは可能です。無料冊子では普通にありますね。しかし、商業ベースにのせようと思った場合、流通コストを考えるとある程度のまとまったサイズにならないとコスト的に採算がとれないという制約があります。1つのコンテンツで流通コストを賄えない場合、複数のコンテンツをバンドルして単価を上げる必要が出てくる。このあたりは出版界にいる人間ではないので想像するだけになりますが。
 電子書籍は流通コストを低く抑えることができる(という前提でとりあえず今回は書く)。だから、単価を低く設定することができる。そして、だから、紙の書籍よりも遙かに少ないサイズでコンテンツを販売することができる。つまり、マイクロ化したコンテンツでも売れるということです。。
 ※が、実際はどうなんでしょう?もしかすると物理メディアと比較するのそもそもの間違いで、電子媒体はコストのかかり方、傾斜が全く違うもののような気がします。一線超えるとコストがゼロに等しくなるとか。
 誤解されそうなので、一応、書きますが、「紙の本よりも電子書籍は物流コスト等がかからないから紙と全く内容のコンテンツでも電子書籍のほうが安くできる」ということをここで言いたいわけではないのです。従来の紙の本という器では経済的に載せることができなかったコンテンツを商業ベースで販売できるかもしれないということです。
 課金コストをゼロにできるわけではないので、ほとんど情報が無料で公開されているWebよりコンテンツを細分化することはおそらくできないだろうと。それでも、紙の本より単価を遙かに安く設定することができる。だから、コンテンツも小さくすることができる。
 すでに100ページ前後の電子書籍が1000円を切る価格で販売されていますが、50ページ、30ページ程度の雑誌記事サイズのコンテンツが100〜300円程度の価格で販売される日は遠からずくるだろうなと思います。課金コストがさらに下がればさらにコンテンツのマイクロ化が進むかもしれません。
 そうなると「書籍」と呼ぶには短いコンテンツである電子書籍と少し長くなったWeb。それを同じ端末で読むことになったら、その違いは有料か無料かの違いになってしまうのでしょうか。どちらにしても、これまでのように「紙の本 VS Web」という対立を前提とした比較はあまり意味がなくなり、相対的な関係になっていくのではないかと私は考えています。

Rubyがインストールされていない環境下でRubyのirbをなんとか使う方法

 Rubyのマニュアルを読んでいると、サンプルとして掲載されているプログラムを実行して挙動を確認したいということがままあり、そういう時にirbは非常に重宝しています。しかし、移動している時などいつも手元にRubyがインストールされている環境があるわけではありません。そんなときでもirbを使う方法をまとめてみました。
 

Web

 Webベースのirbです。ネットに接続された環境下ならブラウザ上でirbを使用することができます。
try ruby! (in your browser)
http://tryruby.org/

 

For iOS

 私はiPhoneユーザーですので、一番よく利用しているのが以下のアプリです。移動中にRubyのマニュアルを読みながらメソッドの挙動などを確かめるのに非常に重宝しています。これもネット経由でリモートにirbを利用するサービスです。
irb for iPhone
http://itunes.apple.com/jp/app/irb/id409540962?mt=8
irb for iPhone
 
 Googleで「irb for iPhone」で検索するとiOSでirbを使えるようにしようという試みはいくつもされているみたいです。ここういうのがどんどん生まれてくるといいですね。できれば、ローカルで実行できるものが欲しい。 
 

For Android

 これはもしかするとAndroidにJRubyをインストールするものなのでしょうか。ならば正確には「Rubyがインストールされていない環境下」とはいえませんが、趣旨としては同じなので紹介してみます。とはいえ、私はAndroidユーザーではないので使用したことがありませんが、対話的に実行するirbが使えるだけではなく、Editorも用意されているようですので、コピペなどを駆使すればローカルで書いたスクリプトを実行もできるんではないでしょうか。正直、これは非常にうらやましい。
Ruboto IRB : 過去最大の衝撃。これは凄い!!AndroidでRubyが動く!!Androidアプリ427
Ruboto (JRuby on Android)
http://ruboto.org/