each_with_indexの実装を探す

まず、/usr/lib/ruby/1.8の中を見てみる。

% find /usr/lib/ruby/1.8 -name '*numerable*' -print

特にEnumerable.rbってファイルはない。
よく考えたら、require 'Enumerable'ってやるわけじゃなくて、include Enumerableってやってるんだった。
そもそも定義するときは、module Enumerableと書くはずなので、それを探してみる。

% grep -r 'module Enumerable' /usr/lib/ruby/1.8
/usr/lib/ruby/1.8/racc/compat.rb:  module Enumerable
/usr/lib/ruby/1.8/soap/property.rb:  module Enumerable
/usr/lib/ruby/1.8/tmail/compat.rb:  module Enumerable
/usr/lib/ruby/1.8/tmail/compat.rb:  module Enumerable
/usr/lib/ruby/1.8/tmail/compat.rb:  module Enumerable
/usr/lib/ruby/1.8/tmail/compat.rb:  module Enumerable
/usr/lib/ruby/1.8/set.rb:module Enumerable

メソッドの追加をしてるやつだけで、本体がかかってこない。
ソースコードを探してみる

% grep each_with_index *.c
enum.c:each_with_index_i(val, memo)
enum.c: *     enum.each_with_index {|obj, i| block }  -> enum
enum.c: *     %w(cat dog wombat).each_with_index {|item, index|
enum.c:enum_each_with_index(obj)
enum.c:    rb_iterate(rb_each, obj, each_with_index_i, (VALUE)&memo);
enum.c:    rb_define_method(rb_mEnumerable,"each_with_index", enum_each_with_index, 0);

あった。Rubyで書いてあったらテクニックを盗もうと思ったが、Cだったか。
でも、せっかくなので、該当部分(らしき所)のソースを抜き書き。
(個人的好みによりK&Rスタイルから改変)

static VALUE each_with_index_i(VALUE val,VALUE *memo){
    rb_yield_values(2, val, INT2FIX(*memo));
    ++*memo;
    return Qnil;
}
static VALUE enum_each_with_index(VALUE obj){
    VALUE memo = 0;
    rb_need_block();
    rb_iterate(rb_each, obj, each_with_index_i, (VALUE)&memo);
    return obj;
}