I am passionate about ruby, but to date it is complicated to implement more complex data structures. In general, data structures in interpreted languages become incredibly slow compared to compiled languages.
This is one of the reasons I was interested in using GoLang code snippets within the ruby environment. For this, I studied how to export compiled golang codes to shared libraries.
For those who do not know the operation of the shared libraries, they work in a similar way as the dll files in windows, however it is a native code with a direct interface to the C compiler.
Note: Windows uses the DLL system, and in this case, this does not necessarily have to be in native code. One example is DLLs with C #, which runs on a virtual machine. Because I do not use windows, I ended up not testing if it is possible to perform these steps on this operating system.
It would be like any library, but it must have some peculiar characteristics.
You need GoLang 1.5 or higher.
For signing external functions to your library, you will need to use the C language typing. For the rest of the code you can convert to the standard GoLang typing.
To do this include library:
import "C"You need to tell the golang compiler which functions will be public in the library. For this you should create a comment above your function.
import "C"
//export MyAdd
func my_add(a, b C.int) C.int {
return a + b
}
func main() {
// This is necessary for the compiler.
// You can add something that will be executed when engaging your library to the interpreter.
}Remember that the exported functions must be in your main package.
Note: I know that the Golang standard for function names is not this, but it is the default for functions in C and Ruby. For this reason, I got used to writing the functions that will be exported to the same pattern.
Just type:
go build -o my_lib.so -buildmode=c-shared my_file.goThere are more efficient ways to write native Ruby code, but this is the most readable and efficient way I've found.
You need to be in an environment **ix. That is, linux or MacOS. We will need these two systems because the gem
we will use only guarantees its operation in these two environments.
Add to your gemfile the following line:
gem 'ffi'Or of course, install manually: gem install ffi
Just create a module and write your function signatures inside the ruby package.
This will act as your library .h file.
require 'ffi'
module Foo
extend FFI::Library
ffi_lib './my_lib.so'
attach_function :my_add, [:int, :int], :int
end
puts Foo.my_add(2, 2)
# => 4Running the native code is very fast, however, the interface call is not so fast.
It's great to use this to solve complex computational problems which involve dynamic programming, graphs, ad hoc and others. Some issues I solved in go lang took a thousandths of seconds compared to seconds in ruby.
Another point is the care when writing the exported functions. The C functions have no garbage collector!
Parallelism in GoLang is MUCH BETTER than in Ruby. Think about it carefully and lovingly.