go-gem-wrapper

module
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2025 License: MIT

README

go-gem-wrapper

go-gem-wrapper is a wrapper for creating Ruby native extension in Go

GitHub Tag build Coverage Status Go Report Card Go Reference

Overview

Directory Name API Reference
/ github.com/ruby-go-gem/go-gem-wrapper (Go module) https://pkg.go.dev/github.com/ruby-go-gem/go-gem-wrapper
/_gem/ go_gem (Ruby gem) https://ruby-go-gem.github.io/go-gem-wrapper/

Requirements

See .github/workflows/matrix.json for details

Getting started

At first, patch to make a gem into a Go gem right after bundle gem

See _tools/patch_for_go_gem/

Please also add the following depending on the CI you are using.

GitHub Actions

e.g.

- uses: actions/setup-go@v5
  with:
    go-version-file: ext/GEM_NAME/go.mod

Implementing Ruby methods in Go

For example, consider the following Ruby method implemented in Go

module Example
  def self.sum(a, b)
    a + b
  end
end
1. Implementing function in Go
// ext/GEM_NAME/GEM_NAME.go

//export rb_example_sum
func rb_example_sum(_ C.VALUE, a C.VALUE, b C.VALUE) C.VALUE {
	aLong := ruby.NUM2LONG(ruby.VALUE(a))
	bLong := ruby.NUM2LONG(ruby.VALUE(b))

	sum := aLong + bLong

	return C.VALUE(ruby.LONG2NUM(sum))
}
2. Write C function definitions for Go functions
// ext/GEM_NAME/GEM_NAME.go

/*
#include "example.h"

// TODO: Append this
VALUE rb_example_sum(VALUE self, VALUE a, VALUE b);
*/
import "C"
3. Call exported C functions with the Init function
// ext/GEM_NAME/GEM_NAME.go

//export Init_example
func Init_example() {
	rb_mExample := ruby.RbDefineModule("Example")

	// TODO: Append this
	ruby.RbDefineSingletonMethod(rb_mExample, "sum", C.rb_example_sum, 2)
}
More examples

See also

Coverage

We provide auto-generated bindings for (almost) all CRuby functions available when including ruby.h 💪

See below for details.

Specification

Method name mapping from CRuby to Go

CRuby methods are mapped to Go methods based on the following rules

  • No lowercase letters included (/^[A-Z0-9_]+$/)
    • No changes
    • e.g. RB_NUM2UINT (CRuby) -> ruby.RB_NUM2UINT (Go)
  • Lowercase letters included
    • Converted to CamelCase
    • e.g. rb_define_method (CRuby) -> ruby.RbDefineMethod (Go)
Limitation

Most of the methods defined in ruby.h are automatically generated and defined in ruby/function_ruby_3_3_generated.go.

However, some of the methods listed below are not supported.

1. deprecated or internal methods

See function.exclude_name in https://github.com/ruby-go-gem/ruby_header_parser/blob/main/config/default.yml

2. Methods with variable-length arguments

Because Go's variable-length arguments couldn't be passed directly to C.

However, it is possible to execute functions with variable length arguments in CRuby from Go with a hack like RbRaise in ruby/ruby_internal_error.go

3. Macro functions

https://github.com/ruby-go-gem/ruby_header_parser parses the preprocessed ruby.h. ^preprocessed

Since preprocessed header files don't contain macro functions, they are not automatically generated.

If you need a macro function, please implement it yourself and submit a patch.

See https://github.com/ruby-go-gem/go-gem-wrapper/pull/323

Developing

Build

Run bundle exec rake build_all.

See bundle exec rake -T for more tasks.

See godoc in local
go install golang.org/x/tools/cmd/godoc@latest
godoc

open http://localhost:6060/pkg/github.com/ruby-go-gem/go-gem-wrapper/ruby/

Release
  1. Run bundle exec rake changelog
  2. Add release note to CHANGELOG.md
  3. Update _gem/lib/go_gem/version.rb
  4. Run bundle exec rake release

Original idea

Ruby meets Go - RubyKaigi 2015

Presentation

Directories

Path Synopsis
Package ruby is a wrapper for creating Ruby native extension in Go
Package ruby is a wrapper for creating Ruby native extension in Go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL