【Red Data Tools開発者に聞け!】(第14回) 拡張ライブラリに新たなメソッドを追加する

Red Data Tools

今回は【Red Data Tools開発者に聞け!】第14回目の振り返り記事になります!いよいよ拡張ライブラリのコードを修正していきます。今回は拡張ライブラリに新しくメソッドを追加する方法を学びます!

Red Data Tools開発者に聞け!第18回 (Rubyバインディングに新機能を追加するシリーズpart13)

今回やったこと

  • C++ の拡張ライブラリに新たなエンドポイントを追加する

C++ の拡張ライブラリに新たなエンドポイントを追加する

今回新たに追加する機能は Arrow::Table クラスのメソッドとして追加していきます。初めにこのクラスにアクセスするための値を取得していきます。rb_const_get_at(klass, name)klass::name の値を取得することのできるメソッドです。

また Arrow はトップレベルのクラスなので、Object に含まれています。 ここにアクセスするためには rb_cObject を参照します。

auto mArrow = rb_const_get_at(rb_cObject, rb_intern("Arrow"));
auto cArrowTable = rb_const_get_at(mArrow, rb_intern("Table"));

これで Arrow::Table へアクセスするための値を取得できました。

次にこのクラスにメソッドを定義していきます。メソッドの追加には rb_define_method を使います。

rb_define_method(cArrowTable,
                 "each_raw_record",
                 reinterpret_cast<rb::RawMethod>(red_arrow::table_each_raw_record),
                 0);

rb_define_method(klass, name, func, argc) は以下のように引数をとります。

  • 第1引数: メソッドを追加する klass
  • 第2引数: メソッドの名前
  • 第3引数: 関数
  • 第4引数: 関数に渡される引数の数

今回の例だと、Arrow::Tableeach_raw_record メソッドを追加していることになります。

では実際にこのメソッドが呼び出す関数を実装していきましょう。

先ほど rb_define_method の部分で red_arrow::table_each_raw_record をメソッドが実行する関数として指定しました。まず red_arrow の名前空間に table_each_raw_record を定義していきます。

# red-arrow.hpp

namespace red_arrow {
  // ...
  VALUE table_each_raw_record(VALUE obj);
  // ...
}

C++ では名前空間の定義と関数の実装はファイルを分けることがあるそう。Appach Arrow でも定義は red-arrow.hpp で行いますが、関数の実装自体は red-arrow.cpp の方に実装されています。

今回はひとまず何かしら動くメソッドを追加することが主旨なので、とりあえずで実行されたら Qnil を返すだけの関数として実装してみます。

# red-arrow.cpp

namespace red_arrow {
  // ...
  VALUE
  table_each_raw_record(VALUE rb_table) {
    return Qnil;
  } 
}

最後に修正したソースコードをコンパイルします。

❯❯ !(git:main) ~/dev/apache/arrow/ruby/red-arrow
❯ make -C ext/arrow

実際に each_raw_record メソッドを呼んでみると、成功していることがわかります!(Qnil を返すだけなので出力は何もありませんが…)

irb(main):003:0> Arrow::Table.new(number: [1, 2, 3]).each_raw_record
=> nil

今回の動画では無事新しいメソッドを追加することができました!次回からは実際に each_raw_record のロジックの実装に入っていきます。お楽しみに!

コメント

タイトルとURLをコピーしました