Help us understand the problem. What is going on with this article?

Hello Ruby

More than 1 year has passed since last update.

Ruby始めました

始めたというより、ほぼ10年ぶり。お久しぶりです。
Rails5はじめました。で一瞬試してみたけど、scaffold叩いただけなので、
Rubyの事はもちろん全然わからない。

環境構築

環境構築はどうやるんだろう?docker-composeの出番か?と思ったが、Macに標準で入っていた。
rbenvでインストールしてあったので、もしかしたら昔、自分でインストールしたのかもしれない。

Hello world

Hello worldの出し方がわからなかったので、【Ruby】Ruby入門:hello worldを表示させるを参考にやってみたらできた。

Rubyで重複なしの組み合わせを表示してみた

Array#repeated_combinationという標準モジュールで組み合わせを求めながら、
組み合わせ毎に逐次、渡した関数の処理ができるらしいという事で試してみた。

combination.rb
R = 9.freeze # .freezeとすると定数になるらしい

numbers = []

for i in 1..100 do # 1-100で100回ループ
  numbers.push(i)
end

# 組み合わせを列挙しながらtestメソッドを実行
def test(*combination) # *を頭に付けると引数が可変長配列になるらしい
  p combination
end

numbers.repeated_combination(R) {
  | *combination
  | test(combination)
}

実行

ruby combination.rb

・・・・・・
[[[1, 1, 1, 1, 1, 3, 7, 15, 85]]]
[[[1, 1, 1, 1, 1, 3, 7, 15, 86]]]
[[[1, 1, 1, 1, 1, 3, 7, 15, 87]]]
[[[1, 1, 1, 1, 1, 3, 7, 15, 88]]]
[[[1, 1, 1, 1, 1, 3, 7, 15, 89]]]
[[[1, 1, 1, 1, 1, 3, 7, 15, 90]]]
・・・・・・

ふむ、組み合わせが表示できた。
こいつは、高速に結果を出せる素晴らしいアルティメットなスーパー処理なんだろうか?

100C9=1902231808400通りとなる条件で動かしてみた。
20分待ってるけど処理が終わらないようだ。

Ruby標準モジュールのソースコードを確認したい

Array#repeated_combinationのソースがみたかった。
pry-docでカジュアルにRubyのソースコードを読むを参考に確認してみた。

pry, pry-docをインストール

gem install pry pry-doc

標準モジュールのソース確認

pry

[1] pry(main)> show-source Array#repeated_combination

From: array.c (C Method):
Owner: Array
Visibility: public
Number of lines: 34

static VALUE
rb_ary_repeated_combination(VALUE ary, VALUE num)
{
    long n, i, len;

    n = NUM2LONG(num);                 /* Combination size from argument */
    RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size);   /* Return enumerator if no block */
    len = RARRAY_LEN(ary);
    if (n < 0) {
    /* yield nothing */
    }
    else if (n == 0) {
    rb_yield(rb_ary_new2(0));
    }
    else if (n == 1) {
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
    }
    }
    else if (len == 0) {
    /* yield nothing */
    }
    else {
    volatile VALUE t0;
    long *p = ALLOCV_N(long, t0, n);
    VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
    RBASIC_CLEAR_CLASS(ary0);

    rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
    ALLOCV_END(t0);
    RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
    }
    return ary;
}

表示できた。
ふむふむ。なるほど。よくわからない。
Rubyじゃなくて、C言語だったのか。rcombinate0()が処理本体っぽいけど中身がわからない。
どういう関数がどういうものなのか、地道に調べていこう。
その調べ方も含めてよくわからないが、地道に調べていこう。

githubにソースが丸ごとあった。

なんて事はない、githubに全部ソースが置いてあった。ここを見ればいいのか。
ふむふむ。なるほど。

https://github.com/ruby/ruby/blob/trunk/array.c

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away