RubyConf 2011の発表資料

9/29から10/1に米国で行われたRubyConfの発表資料がいくつかslideshareで公開されているようです。今なら「Rubyconf」で検索してさらに結果を「this month」で期間を絞れば結構出てきます。どこかでまとめられているともっとよいのですが、今のところないみたいです。

RubyConf 2011
http://rubyconf.org/

 会議の様子はRubyコミッタのauthorNariさん(Nariさん?)がブログで紹介してくださったりしています。

Rubyconf参戦記 -0日目- – I am Cruby!
Rubyconf参戦記 -1日目- – I am Cruby!
Rubyconf参戦記 -2日目- – I am Cruby!
Rubyconf参戦記 -3日目- – I am Cruby!
Rubyconf参戦記 -4日目- – I am Cruby! 
Rubyconf参戦記 -最終日- – I am Cruby! 

 以下に上げている発表資料は会議で発表されているもののほんの一部です。

 

 
 

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

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

 

メソッド

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

str.instance_eval{def aaa; puts “a”;end}
str.aaa
⇒”a”
[/ruby]

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

[ruby]
str.class
⇒String

str.aaa.class
⇒NilClass
[/ruby]
 
  ちなみにFixnumクラスを返すはずのインスタンスメソッド”bbb”でも同じ結果です。 
[ruby]
str.instance_eval{def bbb;puts 1;end}
str.bbb
⇒1

str.bbb.class
⇒NilClass
[/ruby]

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

[ruby]
str = “hoge”

str.instance_eval{def aaa;”a”;end}
str.instance_eval{def bbb;1;end}
str.aaa.class
⇒String
str.bbb.class
⇒Fixnum
[/ruby]
 

定数

  インスタンスの中で定数を定義してみます。正直、インスタンスの中で定数を定義することの意味がまだよくわかりませんが、一応可能なようです。これは特異定数というか、インスタンス定数という感じになるのでしょうか・・・?
 
[ruby]
str.instance_eval{AAA = “ccc”}
[/ruby] 

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

クラス – class_evalとの違い –

 さらにこのインスタンス”str”の中でクラスを作ってみたいと思います。
 
[ruby]
str.instance_eval{class BBB;end}
[/ruby]

BBBクラスのインスタンスはつくることができます。
[ruby]
b = BBB.new
b.class
⇒BBB
[/ruby]

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

[ruby]
BBB.ancestors
⇒[BBB,Object,Kernel]
[/ruby] 

 もう少し深く考えるとこの辺の挙動が理解できそうなのですが、今のところ???状態です。

 ちなみにクラスはClassクラスのインスタンスでもあるので、instance_evalを用いるとこんな感じになります。

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

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

[ruby]
CCC.instance_eval{def ccc;puts “123456”;end}
CCC.ccc
⇒”123456″

CCC.instance_eval{EEE = “789101112”}
CCC::EEE
⇒”789101112″
[/ruby]  

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