Rubyのオブジェクトは生物なんかじゃない、トップレベルこそが生物なんだ!

RubyのTopLevelは不思議だ
Rubyオブジェクト指向言語だから
普通まずクラスでオブジェクトを定義し
これをインスタンス化し
この生まれたオブジェクトにメッセージを送る
という手続きを経てプログラムが組成される

  class Person
    def initialize(name)
      @name = name
    end
    def name
      @name
    end
  end

  me = Person.new("Charlie")
  me.name # => "Charlie"

でもTopLevelではそんな手続きを吹っ飛ばして
いきなりメソッドが実行できたり書けたりする

  rand(10) # => 4

  def hello(name)
    puts "hello, #{name}"
  end
  hello("Charlie")
        # >> hello, Charlie

なぜ?
メソッドのレシーバは誰?
此処は一体どこ?


それを知るにはselfが使える

  self  #  => main

ここはどうやらmainらしい

Rubyの操作対象はすべてオブジェクトだから
mainもきっとオブジェクトに違いない
とすればIDを持っているはずだ

  self.object_id # => 107690

やはりオブジェクトだった
そうなると当然に
その基となるクラスが存在するはずだ

  self.class  # => Object

クラスはObjectクラスだった
mainはObjectクラスのインスタンスなんだ
だからObjectクラスに定義されたinstanceメソッドが使えるんだな
他にも使えるメソッドを調べてみよう

  self.methods.sort # => ["==", "===", "=~", "__id__", "__send__", "class", "clone", "display", "dup", "enum_for", "eql?", "equal?", "extend", "freeze", "frozen?", "hash", "id", "include", "inspect", "instance_eval", "instance_exec", "instance_of?", "instance_variable_defined?", "instance_variable_get", "instance_variable_set", "instance_variables", "is_a?", "kind_of?", "method", "methods", "nil?", "object_id", "private", "private_methods", "protected_methods", "public", "public_methods", "respond_to?", "send", "singleton_methods", "taint", "tainted?", "tap", "to_a", "to_enum", "to_s", "type", "untaint"]

ずいぶんあるけどちょっと変だな
さっき使ったrandも定義したhelloもこのリストにはないぞ

レシーバがはっきりしたんだから
もう一度レシーバを明示してメソッドを呼んでみよう

  main.rand(10) # => 
      # ~> -:10: undefined local variable or method `main' for main:Object (NameError)
  main.hello("Charlie") # => 
      # ~> -:10: undefined local variable or method `main' for main:Object (NameError)

だめだ
selfでどうかな

  self.hello("Charlie") # => 
      # ~> -:10: private method `hello' called for main:Object (NoMethodError)
  self.rand(10) # => 
      # ~> -:10: private method `rand' called for main:Object (NoMethodError)

あれ?
randもhelloもprivateメソッドて書いてあるぞ!
privateメソッドっていうのは確か
レシーバを明示しては呼び出せないメソッドだったよね
じゃあmainのprivateメソッドのリストを見てみようか

  self.private_methods.sort # => ["Array", "Float", "Integer", "String", "__method__", "`", "abort", "at_exit", "autoload", "autoload?", "binding", "block_given?", "callcc", "caller", "catch", "chomp", "chomp!", "chop", "chop!", "eval", "exec", "exit", "exit!", "fail", "fork", "format", "getc", "gets", "global_variables", "gsub", "gsub!", "hello", "initialize", "initialize_copy", "iterator?", "lambda", "load", "local_variables", "loop", "method_missing", "open", "p", "print", "printf", "proc", "putc", "puts", "raise", "rand", "readline", "readlines", "remove_instance_variable", "require", "scan", "select", "set_trace_func", "singleton_method_added", "singleton_method_removed", "singleton_method_undefined", "sleep", "split", "sprintf", "srand", "sub", "sub!", "syscall", "system", "test", "throw", "trace_var", "trap", "untrace_var", "warn"]

リストが長くて見つけられないなあ
じゃあスーパークラスのものを除外して表示してみよう

  self.private_methods(false) # => ["initialize", "hello"]

helloがあったぞ!
でもずいぶんときれいさっぱり他のメソッドが無くなっちゃったね
randも見つからないし
スーパークラスにあるのかな?

あれ?ちょっと待った
mainのクラスはObjectだったよね
それにスーパークラスなんてあるの?

  Object.superclass # => nil

やっぱり無い*1
じゃあさっきの長いメソッドリストはどこから来たの?

そうか!
きっとモジュールだよ
Objectクラスには他のモジュールがMix-inされていて
そのモジュールにさっきのメソッドたちが定義されてるんだ
調べてみよう

  Object.included_modules # => [Kernel]

KernelというモジュールがMix-inされている
じゃあKernelに定義されているprivateなInstanceメソッドをリストしてみよう

  Kernel.private_instance_methods.sort # => ["Array", "Float", "Integer", "String", "__method__", "`", "abort", "at_exit", "autoload", "autoload?", "binding", "block_given?", "callcc", "caller", "catch", "chomp", "chomp!", "chop", "chop!", "eval", "exec", "exit", "exit!", "fail", "fork", "format", "getc", "gets", "global_variables", "gsub", "gsub!", "initialize_copy", "iterator?", "lambda", "load", "local_variables", "loop", "method_missing", "open", "p", "print", "printf", "proc", "putc", "puts", "raise", "rand", "readline", "readlines", "remove_instance_variable", "require", "scan", "select", "set_trace_func", "singleton_method_added", "singleton_method_removed", "singleton_method_undefined", "sleep", "split", "sprintf", "srand", "sub", "sub!", "syscall", "system", "test", "throw", "trace_var", "trap", "untrace_var", "warn"]

今度は目を凝らしてみつけるぞ
randがあったぞ!
randはKernelモジュールに定義されたprivateメソッドだったんだ
するとここに並んでいるメソッドはTopLevelで使えるんだね

じゃあKernelにメソッドを定義して
TopLevelで呼べるか試してみよう

  module Kernel
    private
    def kernel_private_hello
      "hello of Kernel Private called from #{self}"
    end
  end

  kernel_private_hello # => "hello of Kernel Private called from main"

うまくいった


でも不思議だなあ
mainはオブジェクトなのに
Kernelのprivateメソッドがなぜ使えるんだろう
ここがObjectクラス内だったら分かるんだけど…
それからなぜオブジェクトにhelloメソッドが定義できたんだろう
メソッド定義はクラスにしかできないと思ってたのに…


もしかして…
そうかSingletonメソッドがあるじゃないか
helloはきっとmainのSingletonメソッドになってるんだよ

  self.singleton_methods # => ["public", "to_s", "include", "private"]

違った…
なんか違うの出てきちゃったな


試しにSingletonメソッドをTopLevelで定義して
ここにリストアップされるか見てみよう

  def self.toplevel_singleton_hello
    "hello of TopLevl Singleton from #{self}}"
  end

  class << self
    def toplevel_singleton_class_hello
      "hello of TopLevel Singleton Class from #{self}"
    end
  end

  toplevel_singleton_hello # => "hello of TopLevl Singleton from main}"
  toplevel_singleton_class_hello # => "hello of TopLevel Singleton Class from main"

  self.singleton_methods # => ["public", "toplevel_singleton_class_hello", "to_s", "include", "toplevel_singleton_hello", "private"]

ちゃんとリストアップされるなあ
やっぱりここはmainオブジェクトだよ


まさか…


ここはObjectクラス?
試しにObjectクラスが持っているprivateなinstanceメソッドを調べてみよう

  Object.private_instance_methods(false) # => ["initialize", "hello"]

あっ!
TopLevelで定義したhelloがある!
つまりここは…
Objectクラスの中なんだ!
これでprivateメソッドが呼べるのにも筋が通る


よしもう一つ確かめてみよう
ここがObjectクラスの中なら
そこに定義されるクラスはネストされたクラスになるはずだ

  class Nested
  
  end

  Object::Nested # => Nested
  ::Nested # => Nested
  Object::Nested.new # => #<Nested:0x1bf58>
  Object.constants.detect{ |c| c =~ /^Ne/ } # => "Nested"

確かにObjectにネストされているぞ


これで答えが出た


RubyのTopLevelは
Objectクラスであり
かつ
そのインスタンスであるmainオブジェクトだったんだ!
だからそこでクラスとしてinstanceメソッドを定義でき
しかもそのメソッドをそのインスタンスとして呼び出せる


つまり自身で自身を作るという自己増殖の機能を備えている!


そうRubyのTopLevelは…


生物だったんだ!


不思議の国Rubyでは
ClassクラスがClassクラスを生成するように
TopLevelがTopLevelを生成していたんだ!

*1:Ruby1.9ではBasicObjectがある