Useful resources when studying Ruby's internals

tanguyandreani

Tanguy Andreani

Posted on July 19, 2019

Useful resources when studying Ruby's internals

I'm gonna list a few places I visit whenever I want to learn more about a specific part of Ruby.

Ruby MRI on Github

Link: https://github.com/ruby/ruby

The whole source code is mirrored there. Here you can learn how the language is implemented.

For example, if we want to learn about the Array class, we can look in array.c.

Let's say I'm interested in the Array#count method:

static VALUE
rb_ary_count(int argc, VALUE *argv, VALUE ary)
{
    long i, n = 0;

    if (rb_check_arity(argc, 0, 1) == 0) {
    VALUE v;

    if (!rb_block_given_p())
        return LONG2NUM(RARRAY_LEN(ary));

    for (i = 0; i < RARRAY_LEN(ary); i++) {
        v = RARRAY_AREF(ary, i);
        if (RTEST(rb_yield(v))) n++;
    }
    }
    else {
        VALUE obj = argv[0];

    if (rb_block_given_p()) {
        rb_warn("given block not used");
    }
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
    }
    }

    return LONG2NUM(n);
}

// ...

rb_define_method(rb_cArray, "count", rb_ary_count, -1);
Enter fullscreen mode Exit fullscreen mode

The Ruby Spec Suite

Link: https://github.com/ruby/spec

Let's say I'm interested in the Array#count method:

describe "Array#count" do
  it "returns the number of elements" do
    [:a, :b, :c].count.should == 3
  end

  it "returns the number of elements that equal the argument" do
    [:a, :b, :b, :c].count(:b).should == 2
  end

  it "returns the number of element for which the block evaluates to true" do
    [:a, :b, :c].count { |s| s != :b }.should == 2
  end
end
Enter fullscreen mode Exit fullscreen mode

Ruby-doc

Link: https://ruby-doc.org/

Documentation for pretty much every versions of Ruby MRI.

Here is the doc for Array#count

The Rubinius implementation

Link: https://github.com/rubinius/rubinius

Rubinius is basically Ruby implemented in Ruby. It's fun to compare with the original C implementation.

For example, here is the source code for Array#count:

def count(item = undefined)
  seq = 0
  if !undefined.equal?(item)
    each do
      element = Rubinius.single_block_arg
      seq += 1 if item == element
    end
  elsif block_given?
    each { |element| seq += 1 if yield(element) }
  else
    each { seq += 1 }
  end
  seq
end
Enter fullscreen mode Exit fullscreen mode

Does it look like it match the Ruby spec?

JRuby, Ruby on the JVM

Link: https://github.com/jruby/jruby

I don't know Java but this project motivate me to learn about it.

Here is Array#count source code from JRuby's RubyArray.java:

@JRubyMethod(name = "count")
public IRubyObject count(ThreadContext context, Block block) {
    if (block.isGiven()) {
        int n = 0;
        for (int i = 0; i < realLength; i++) {
            if (block.yield(context, elt(i)).isTrue()) n++;
        }
        return RubyFixnum.newFixnum(context.runtime, n);
    } else {
        return RubyFixnum.newFixnum(context.runtime, realLength);
    }
}

@JRubyMethod(name = "count")
public IRubyObject count(ThreadContext context, IRubyObject obj, Block block) {
    if (block.isGiven()) context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used");

    int n = 0;
    for (int i = 0; i < realLength; i++) {
        if (equalInternal(context, elt(i), obj)) n++;
    }
    return RubyFixnum.newFixnum(context.runtime, n);
}
Enter fullscreen mode Exit fullscreen mode

Those are methods of the Java class RubyArray.

Bonus, the Mailing Lists Archive for Ruby MRI

Link: http://blade.nagaokaut.ac.jp/


Summary:

Regarding gems and their documentation (offtopic but cool to have anyway):

Anything to add to the list?

💖 💪 🙅 🚩
tanguyandreani
Tanguy Andreani

Posted on July 19, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related