組み込みの Ruby アプリケーションで奇妙な動作が見られます。コードを最小限に抑え、問題を再現することができました。詳細は以下のとおりです。
1. ルビーコード
#!/usr/bin/env ruby
#require "MyLibrary.so" *// Works fine*
module AA
class BC
def initialize
end
def loadFunction
require "MyLibrary.so" *//Gives error*
end
end
end
#Invoke the method
AA::BC.new().loadFunction
2. MyLibrary.so のソースコード
#include "ruby.h"
const char loop[] =
"def loopFunc\n"
"puts \"HERE\"\n"
"end\n"
"begin\n"
"loopFunc()\n"
"rescue StandardError\n"
"puts $!\n"
"puts $!.class\n"
"end\n";
void initialize()
{
ruby_init();
ruby_init_loadpath();
rb_eval_string(loop);
}
extern "C" void Init_MyLibrary()
{
initialize();
}
rb ファイルの loadFunction 内で "MyLibrary.so" ファイルを必要とすると、次のエラーが発生します。
main:Object NoMethodErrorの未定義メソッド「loopFunc」
ただし、rb ファイルの先頭で必要な場合は、すべて正常に動作します。
私たちの最初の推測は、rb_eval_string() がモジュール AA 内で実行されるというものでした。そのため、loopFunc はグローバルではなく、モジュール AA 内で定義されています。したがって、NoMethodError が報告されています。cpp ファイル内で AA::BC.new().loopFunc() を呼び出すと、メソッドが正常に呼び出されます。これは私たちの推測を確認しました。
rb_eval_string に渡されたものと同じコードで (.so ではなく) rb ファイルが必要な場合、エラーは発生しないため、これは組み込み Ruby の観点から予想される動作ですか。