まず第一に、この振る舞いとその根底にある推論は常に存在していました。1.9 にとって新しいことではありません。これが発生する技術的な理由は、main
が特別であり、他のオブジェクトとは異なる方法で処理されるためです。派手な説明はありません。そのように設計されているため、そのように動作します。
わかりましたが、なぜですか?main
魔法使いになる根拠は?Ruby の設計者 Yukihiro Matsumoto は、この振る舞いが言語をより良くすると考えているからです:
では、トップレベルのメソッドが Object クラス自体のインスタンス メソッドとして取り込まれるのではなく、このオブジェクトのシングルトン メソッドにならないのはなぜですか (したがって、他のすべてのクラスに、つまり、通常意図されているよりも多くの名前空間汚染が発生します)。これにより、トップレベルのメソッドが他のトップレベルのメソッドを呼び出すことができます。また、最上位オブジェクトが Main などの定数によって参照される場合、これらのメソッドは Main.method(...) を使用してどこからでも呼び出すことができます。
どこにでも「Main.print」と入力しますか?
さらに議論の中で、彼は「仮定が自然である」と感じているため、このように振る舞うと説明しています。
編集:
あなたのコメントに応えて、あなたの質問は、メインの固有クラスhello
がプライベート インスタンス メソッドとして報告されているように見える理由を対象としています。問題は、トップレベルの関数が実際に に追加されるmain
のではなく、 に直接追加されることObject
です。固有クラスをinstance_methods
扱う場合、関数のファミリは常に、固有クラスがまだ元のクラスであるかのように動作します。つまり、クラスで定義されたメソッドは、固有クラスで直接定義されているものとして扱われます。例えば:
class Object
private
def foo
"foo"
end
end
self.send :foo # => "foo"
Object.private_instance_methods(false).include? :foo # => true
self.meta.private_instance_methods(false).include? :foo # => true
class Bar
private
def bar
"bar"
end
end
bar = Bar.new
bar.send :bar # => "bar"
Bar.private_instance_methods(false).include? :bar # => true
bar.meta.private_instance_methods(false).include? :bar # => true
ただし、メソッドを の固有クラスに直接追加することはできmain
ます。元の例をこれと比較してください:
def self.hello; "hello world"; end
Object.instance_methods.include? :hello # => false
self.meta.instance_methods.include? :hello # => true
わかりましたが、特定の関数が元のクラスではなく、固有クラスで定義されていることを本当に知りたい場合はどうすればよいでしょうか?
def foo; "foo"; end #Remember, this defines it in Object, not on main
def self.bar; "bar"; end #This is defined on main, not Object
foo # => "foo"
bar # => "bar"
self.singleton_methods.include? :foo # => false
self.singleton_methods.include? :bar # => true