2011-08-07 7 views
8

MRI implementation of gc.cには、undefという名前のオブジェクトがあります。そのundefオブジェクトは何ですか?そのクラスは何ですか?どうすればそれにアクセスできますか?それにはどんなユーティリティがありますか?Rubyの "undef"オブジェクトとは何ですか?

+2

私はそれが何であるか分かりませんが、おそらくメソッドを定義解除するために使用される 'undef'メソッドとは関係ありません。 –

+1

@Andrew Grimm、はい、私は同意します! –

答えて

5

これは私の一部の推測があり、多分マッツがうまくいけば、これはその間に行います、いくつかの点でこの質問を見ると、私たちに決定的な答えを与えるだろう。

ご存知かもしれませんが、ルビーは多少(我々が$ @と$ _などのような変数を持っている理由である)は、少なくとも初期の段階でperlの影響を受けていました。 Perlのキーワード/機能はundefです(たとえば、初期化せずに変数を宣言すると、その値は未定義です)。過去のある時点では、Rubyも何か似たようなもの(つまり、変数は未定義の値を持つことができます)を意味すると私は言います。これをどうやって知るのですか?それが見つかった文脈によって。

このコメントは、さまざまなRubyオブジェクトのobject_idがどのように派生しているかを示しています。その詳細はhereです。しかし、本質的に、私たちは次のことを知っている:

false.object_id == 0 
true.object_id == 2 
nil.object_id == 4 

このコメントは示唆し、これは確かにそうである、あなたはirbセッションを開いて割れて、自分でそれを試してみることができるものです。私たちが知っているように - - undefobject_id今6

の持っているものだったようですが、undefが実際にRubyで予約語であるが、それはnilfalsetrueのように、それは特別なオブジェクトではありませんに見えますメソッドを定義解除するためのキーワード。

だから、あなたの質問に答えるために、それは何のクラスを持っていない、あなたはそれにアクセスすることはできません、何undefオブジェクトはありません。 undefの目的は、今日知られているRubyのnilオブジェクトによって代わりに提供されることです。しかし、私たちがもっと興味をそそられて困惑するためには、時代の遺産としてコードに残っています。

+0

'ObjectSpace._id2ref(6)'でオブジェクトを取得できないので、オブジェクトではないことがわかりました。それは[多くの場所](http://rxr.whitequark.org/mri/ident?i=Qundef)、[ここ](http://rxr.whitequark.org/mri/source/include/ruby/)にあります。 ruby.h#352)、それは "プレースホルダのための未定義の値"と呼ばれます。実際には、0、-1、NULLなどの代わりに未定義(またはnull)の値を表すために使用されます。有効なRubyオブジェクトと競合しないようにする必要があるようです。良い例は[削除されたインスタンス変数を無効にする](http://rxr.whitequark.org/mri/source/variable.c#1279)です。 –

+0

値についてのあなたのリンクは+1です。ありがとうございました! :) –

+0

最後の例では、Qundefが削除されているインスタンス変数の値を上書きするために使用されているように見えます。そのインスタンス変数にアクセスしようとすると、Rubyが例外をスローする必要があります。彼らが単にQnilを使用していたのであれば、私の推測では例外はありませんが、代わりにあなたが望む動作ではない戻り値として戻ってくることはありません。非常に興味深い、私はこれを見て楽しんでいた - 良い質問。 – skorks

-2

これは、定義されていない変数(nilとして定義されている変数ではありません)を参照していることを確信しています。あなたの質問へのより完全な答えと結論するに :

def hello(object = 'World') 
    puts "Hello #{object}" 
end 

hello     #=> 'Hello World' 
hello 'stackoverflow' #=> 'Hello stackoverflow' 
hello nil    #=> 'Hello ' 

EDIT:

はこれを見てください。そのundefオブジェクトにアクセスすることはできません。これはメソッド定義内にのみ存在し、その本文には存在しません。既定値(上記の'World'など)が入力されているか、すべてのメソッドパラメーターを指定していないため、ArgumentErrorが表示されます。

+0

ああ、私にあなたの答えを把握するのに1分かかった。メソッドに引数を全く渡さず、 'nil'を渡すことには違いがあります。その違いは 'undef'オブジェクトです。それはあなたが言っていることですか? – mikezter

+0

文字通り値が渡されない場合、正しいデフォルトの引数値が優先されます。 – Koraktor