Strange behavior with built-in ruby

We observe strange behavior of our built-in ruby ​​application. We split the code into the minimum and were able to re-create the problem. See below for details.

1. ruby ​​code

#!/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. Source code for 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(); } 

When we need the file "MyLibrary.so" inside the loadFunction in the rb file, we get the following error

undefined `loopFunc 'method for main: Object
NoMethodError

However, when we require at the top of the rb file, everything works fine.

Our first assumption was that rb_eval_string () runs inside the AA module. In this way, loopFunc gets the definition inside the AA module instead of being global. Therefore, a NoMethodError is reported. When we call AA :: BC.new (). LoopFunc () inside the cpp file, the method starts successfully; which confirmed our assumption.

Is this the expected behavior from the embedded Ruby point, because if we need an rb file (instead of .so) with the same code that is passed to rb_eval_string, we get no errors.

+4
source share
1 answer

rb_eval_string () defines the methods in the module from which it is called. We can use rb_require / rb_load to get the correct behavior.

+1
source

Source: https://habr.com/ru/post/1432082/


All Articles