Spelunking in Ruby's Source

  • Thread starter James Edward Gray II
  • Start date
J

James Edward Gray II

Ruby for Rails makes an interesting claim that object_id(), send(),
and respond_to?() are defined on Kernel. I didn't expect this, so I
went into the source to verify and it does seem to be true in Ruby
1.8.x. These seem to be the relevant lines of eval.c:

rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);

rb_define_method(rb_mKernel, "send", rb_f_send, -1);
rb_define_method(rb_mKernel, "__send__", rb_f_send, -1);

and gc.c:

rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0);
rb_define_method(rb_mKernel, "object_id", rb_obj_id, 0);

My first question is, why are these Kernel methods, instead of
methods on Object?

I thought Kernel was for methods like puts() that we wanted to have
globally available but that weren't necessarily inherent to Object.
Clearly my understanding is flawed, so would someone please explain
how it is decided if a method belongs in Object or Kernel?

Fast forwarding to HEAD, this seems to have changed in Ruby 1.9.
Here are the now relevant lines of eval.c:

rb_define_method(rb_cBasicObject, "respond_to?", obj_respond_to,
-1);

rb_define_method(rb_cBasicObject, "send", rb_f_send, -1);
rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);

and again for gc.c:

rb_define_method(rb_cBasicObject, "__id__", rb_obj_id, 0);
rb_define_method(rb_cBasicObject, "object_id", rb_obj_id, 0);

Am I reading this right in that the methods have been moved to
BasicObject in Ruby 1.9?

An unrelated curiosity: while browsing the source I saw these likes
in eval.c:

rb_define_method(rb_cBasicObject, "send", rb_f_send, -1);
rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
rb_define_method(rb_cBasicObject, "__send", rb_f_send, -1);
rb_define_method(rb_cBasicObject, "funcall", rb_f_funcall, -1);
rb_define_method(rb_cBasicObject, "__send!", rb_f_funcall, -1);

Does that last one mean Matz is cracking under the pressure? ;)

James Edward Gray II
 
L

Logan Capaldo

I thought Kernel was for methods like puts() that we wanted to have
globally available but that weren't necessarily inherent to
Object. Clearly my understanding is flawed, so would someone
please explain how it is decided if a method belongs in Object or
Kernel?

Everything (almost) belongs in Kernel <g>

% irb
irb(main):001:0> obj = Object.new
=> #<Object:0x35477c>
irb(main):002:0> obj.methods.map { |x| obj.method(x).inspect }.grep(/
Kernel/).size
=> 40
irb(main):003:0> obj.methods.size
=> 40

I believe the purpose of BasicObject in 1.9 is to be able to say

class O < BasicObject # I want BlankSlate without all the extra work
of undef_method
end

I don't know anything about matz. cracking under the pressure <g>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top