Kernel.test に関する無駄知識

Ruby の Kernel.test の第一引数って普通は ?e みたいに ? 記法で渡すじゃないですか。あれって1.8までは ?e は数値が返ってきて、1.9では文字列が返ってくるようになったんですよね。だから 1.9 では Kernel.test(?e, "test.rb") と書くと結局は第一引数に数値ではなく文字列が渡ることになります。つまり、もう Kernel.test の第一引数に数値を渡すことが出来る必要性って、全くないわけです。

さて、このことを踏まえまして、無駄知識。Kernel.test(?e, "test.rb") と

  • Kernel.test(357, "test.rb")
  • Kernel.test(237413, "test.rb")
  • Kernel.test(1425514341, "test.rb")

などは同一の操作なんですよね。これは第一引数を2進数に直すと簡単なことで、

  • 'e' = 101 = 0b00000000000000000000000001100101
  • 357 = 0b00000000000000000000000101100101
  • 237413 = 0b00000000000000111001111101100101
  • 1425514341 = 0b01010100111101111001111101100101

という感じ。結局のところ内部で char 型にキャストしちゃうので、最後の8bitしか残らないから、これらは同一というわけです。Ruby の file.c の 3360行あたりはこんな感じです。

static VALUE
rb_f_test(int argc, VALUE *argv)
{
    int cmd;

    if (argc == 0) rb_raise(rb_eArgError, "wrong number of arguments");
    cmd = NUM2CHR(argv[0]);
    if (cmd == 0) goto unknown;
    if (strchr("bcdefgGkloOprRsSuwWxXz", cmd)) {
        CHECK(1);
        switch (cmd) {
          case 'b':
            return rb_file_blockdev_p(0, argv[1]);

          case 'c':
            return rb_file_chardev_p(0, argv[1]);

          case 'd':
            return rb_file_directory_p(0, argv[1]);
/* 以下略 */

てなわけですが、まさか本気で Kernel.test に数値を渡す人も居ないでしょうから、どうでも良いと思います。