今回は【Red Data Tools開発者に聞け!】第14回目の振り返り記事になります!いよいよ拡張ライブラリのコードを修正していきます。今回は拡張ライブラリに新しくメソッドを追加する方法を学びます!
今回やったこと
- 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::Table
に each_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
のロジックの実装に入っていきます。お楽しみに!
コメント