嵌入ruby的奇怪行为

嵌入ruby的奇怪行为,ruby,embedded-ruby,Ruby,Embedded Ruby,我们在嵌入式ruby应用程序上观察到一个奇怪的行为。我们已经将代码精简到最低限度,并能够重新生成问题。详情如下 1。ruby代码 #!/usr/bin/env ruby #require "MyLibrary.so" *// Works fine* module AA class BC def initialize end def loadFunction require "MyLibrary.so" *//Gives error* end

我们在嵌入式ruby应用程序上观察到一个奇怪的行为。我们已经将代码精简到最低限度,并能够重新生成问题。详情如下

1。ruby代码

#!/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的方法'loopFunc'
命名错误

然而,当我们需要在rb文件的顶部时,一切都很好

我们的第一个猜测是rb_eval_string()在模块AA内执行。因此,loopFunc是在模块AA中定义的,而不是全局的。因此,正在报告NoMethodError。当我们在cpp文件中调用AA::BC.new().loopFunc()时,该方法被成功调用;这证实了我们的猜测


从嵌入式ruby的角度来看,这是否是预期的行为,因为如果我们需要一个rb文件(而不是.so),该文件的代码与传递给rb_eval_string的代码相同,那么我们不会得到任何错误。

rb_eval_string()确实定义了调用它的模块中的方法。我们可以使用rb_require/rb_load来获得正确的行为。

这是一个如何提出清晰的SO问题的示例。