defined?
1.9.3 のソースをたどると、次のように実装されていることがわかりますinsns.def
。
DEFINE_INSN
defined
(rb_num_t op_type, VALUE obj, VALUE needstr)
/* ... */
switch (type) {
/* ... */
case DEFINED_CONST:
klass = v;
if (vm_get_ev_const(th, GET_ISEQ(), klass, SYM2ID(obj), 1)) {
expr_type = "constant";
}
break;
だから、あなたdefined? SomeConstant
はその大きなものを少しずつ通り抜けてswitch
、最後に電話をかけvm_get_ev_const
ます。関数は次のように定義されていvm_insnhelper.c
ます。
static inline VALUE
vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq,
VALUE orig_klass, ID id, int is_defined)
その関数はたまたま静的であるため、取得できません。andvm_get_ev_const
の観点から定義されているように見えますが、これらの両方が C で使用できるはずなので、それらを試すことができます。しかし、あなたはそれらのための権利を見つけなければならないでしょう.rb_const_defined
rb_const_defined_from
klass
または、あなたのアイデアをそのまま使用することもできますObject.const_defined?
。それに関する1つの問題は、それが正しいことをしないということA::B
です. ここでの一般的な解決策には、反復とクラス ルックアップが必要です。ただし、見ているクラスがすべて最上位の名前空間にある場合は、単純な方法でうまくいくはずです。Object.const_defined? :A && A.const_defined? :B
Object.const_defined? :'A::B'
Object.const_defined?