Skip to content

Commit

Permalink
Merge pull request #9 from zhulik/huge-refactoring
Browse files Browse the repository at this point in the history
Huge refactoring
  • Loading branch information
zhulik authored Aug 7, 2024
2 parents 9621cba + b7cb59c commit 7b7484f
Show file tree
Hide file tree
Showing 30 changed files with 624 additions and 567 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ clean:

libmruby.a: ${MRUBY_VENDOR_DIR}/mruby
cd ${MRUBY_VENDOR_DIR}/mruby && ${MAKE}
cp ${MRUBY_VENDOR_DIR}/mruby/build/host/lib/libmruby.a .

${MRUBY_VENDOR_DIR}/mruby:
mkdir -p ${MRUBY_VENDOR_DIR}
Expand Down
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ This is a fork of amazing [go-mruby](https://github.com/mitchellh/go-mruby).
I'm not sure if I want and I can maintain it for a long time, but I updated it
to support mruby 3.3 and go 1.22.

*The project in being heavily refactored and partially rewritten.*
*Backwards compatibility with go-mruby is broken.*

gruby provides [mruby](https://github.com/mruby/mruby) bindings for
[Go](http://golang.org). This allows Go applications to run a lightweight
embedded Ruby VM. Using the mruby library, Go applications can call Ruby
Expand Down Expand Up @@ -85,27 +88,28 @@ package main

import (
"fmt"

"github.com/zhulik/gruby"
)

func main() {
mrb := gruby.NewMrb()
defer mrb.Close()
grb := gruby.New()
defer grb.Close()

// Our custom function we'll expose to Ruby. The first return
// value is what to return from the func and the second is an
// exception to raise (if any).
addFunc := func(m *mruby.Mrb, self *mruby.MrbValue) (mruby.Value, gruby.Value) {
args := m.GetArgs()
return gruby.Int(ToGo[int](args[0]) + ToGo[int](args[1])), nil
addFunc := func(grb *gruby.GRuby, self gruby.Value) (gruby.Value, gruby.Value) {
args := grb.GetArgs()
return gruby.ToRuby(grb, gruby.ToGo[int](args[0])+gruby.ToGo[int](args[1])), nil
}

// Lets define a custom class and a class method we can call.
class := mrb.DefineClass("Example", nil)
class := grb.DefineClass("Example", nil)
class.DefineClassMethod("add", addFunc, gruby.ArgsReq(2))

// Let's call it and inspect the result
result, err := mrb.LoadString(`Example.add(12, 30)`)
result, err := grb.LoadString(`Example.add(12, 30)`)
if err != nil {
panic(err.Error())
}
Expand Down
15 changes: 12 additions & 3 deletions array.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@ package gruby
// #include "gruby.h"
import "C"

// Array represents an MrbValue that is a Array in Ruby.
// Array represents an GValue that is a Array in Ruby.
//
// A Array can be obtained by calling the Array function on MrbValue.
// A Array can be obtained by calling the Array function on GValue.
type Array struct {
Value
}

func NewArray(grb *GRuby) *Array {
return &Array{grb.value(C.mrb_ary_new(grb.state))}
}

// Push adds an item to the arrayss
func (v *Array) Push(item Value) {
C.mrb_ary_push(v.GRuby().state, v.CValue(), item.CValue())
}

// Len returns the length of the array.
func (v *Array) Len() int {
return int(C._go_RARRAY_LEN(v.CValue()))
Expand All @@ -22,7 +31,7 @@ func (v *Array) Len() int {
func (v *Array) Get(idx int) (Value, error) {
result := C.mrb_ary_entry(v.CValue(), C.mrb_int(idx))

val := v.Mrb().value(result)
val := v.GRuby().value(result)
if val.Type() == TypeNil {
val = nil
}
Expand Down
6 changes: 3 additions & 3 deletions array_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ func TestArray(t *testing.T) {
t.Parallel()
g := NewG(t)

mrb := gruby.NewMrb()
defer mrb.Close()
grb := gruby.New()
defer grb.Close()

value, err := mrb.LoadString(`["foo", "bar", "baz", false]`)
value, err := grb.LoadString(`["foo", "bar", "baz", false]`)
g.Expect(err).ToNot(HaveOccurred())

array := gruby.ToGo[*gruby.Array](value)
Expand Down
30 changes: 15 additions & 15 deletions class.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package gruby

import "unsafe"

// #include <stdlib.h>
// #include "gruby.h"
import "C"

// Class is a class in gruby. To obtain a Class, use DefineClass or
// one of the variants on the Mrb structure.
// one of the variants on the GRuby structure.
type Class struct {
Value
class *C.struct_RClass
Expand All @@ -20,13 +19,13 @@ func (c *Class) String() string {

// DefineClassMethod defines a class-level method on the given class.
func (c *Class) DefineClassMethod(name string, cb Func, spec ArgSpec) {
insertMethod(c.Mrb().state, c.class.c, name, cb)
c.GRuby().insertMethod(c.class.c, name, cb)

cstr := C.CString(name)
defer C.free(unsafe.Pointer(cstr))
defer freeStr(cstr)

C.mrb_define_class_method(
c.Mrb().state,
c.GRuby().state,
c.class,
cstr,
C._go_mrb_func_t(),
Expand All @@ -36,20 +35,21 @@ func (c *Class) DefineClassMethod(name string, cb Func, spec ArgSpec) {
// DefineConst defines a constant within this class.
func (c *Class) DefineConst(name string, value Value) {
cstr := C.CString(name)
defer C.free(unsafe.Pointer(cstr))
defer freeStr(cstr)

C.mrb_define_const(c.Mrb().state, c.class, cstr, value.CValue())
C.mrb_define_const(c.GRuby().state, c.class, cstr, value.CValue())
}

// DefineMethod defines an instance method on the class.
func (c *Class) DefineMethod(name string, cb Func, spec ArgSpec) {
insertMethod(c.Mrb().state, c.class, name, cb)
grb := c.GRuby()
grb.insertMethod(c.class, name, cb)

cstr := C.CString(name)
defer C.free(unsafe.Pointer(cstr))
defer freeStr(cstr)

C.mrb_define_method(
c.Mrb().state,
grb.state,
c.class,
cstr,
C._go_mrb_func_t(),
Expand All @@ -70,17 +70,17 @@ func (c *Class) New(args ...Value) (Value, error) {
argvPtr = &argv[0]
}

result := C.mrb_obj_new(c.Mrb().state, c.class, C.mrb_int(len(argv)), argvPtr)
if exc := checkException(c.Mrb()); exc != nil {
result := C.mrb_obj_new(c.GRuby().state, c.class, C.mrb_int(len(argv)), argvPtr)
if exc := checkException(c.GRuby()); exc != nil {
return nil, exc
}

return c.Mrb().value(result), nil
return c.GRuby().value(result), nil
}

func newClass(mrb *GRuby, c *C.struct_RClass) *Class {
func newClass(grb *GRuby, c *C.struct_RClass) *Class {
return &Class{
Value: mrb.value(C.mrb_obj_value(unsafe.Pointer(c))),
Value: grb.value(C.mrb_obj_value(unsafe.Pointer(c))),
class: c,
}
}
46 changes: 23 additions & 23 deletions class_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ func TestClassDefineClassMethod(t *testing.T) {
t.Parallel()
g := NewG(t)

mrb := gruby.NewMrb()
defer mrb.Close()
grb := gruby.New()
defer grb.Close()

class := mrb.DefineClass("Hello", mrb.ObjectClass())
class := grb.DefineClass("Hello", grb.ObjectClass())
class.DefineClassMethod("foo", testCallback, gruby.ArgsNone())
value, err := mrb.LoadString("Hello.foo")
value, err := grb.LoadString("Hello.foo")
g.Expect(err).ToNot(HaveOccurred())

testCallbackResult(g, value)
Expand All @@ -26,12 +26,12 @@ func TestClassDefineConst(t *testing.T) {
t.Parallel()
g := NewG(t)

mrb := gruby.NewMrb()
defer mrb.Close()
grb := gruby.New()
defer grb.Close()

class := mrb.DefineClass("Hello", mrb.ObjectClass())
class.DefineConst("FOO", gruby.ToRuby(mrb, "bar"))
value, err := mrb.LoadString("Hello::FOO")
class := grb.DefineClass("Hello", grb.ObjectClass())
class.DefineConst("FOO", gruby.ToRuby(grb, "bar"))
value, err := grb.LoadString("Hello::FOO")

g.Expect(err).ToNot(HaveOccurred())
g.Expect(value.String()).To(Equal("bar"))
Expand All @@ -41,12 +41,12 @@ func TestClassDefineMethod(t *testing.T) {
t.Parallel()
g := NewG(t)

mrb := gruby.NewMrb()
defer mrb.Close()
grb := gruby.New()
defer grb.Close()

class := mrb.DefineClass("Hello", mrb.ObjectClass())
class := grb.DefineClass("Hello", grb.ObjectClass())
class.DefineMethod("foo", testCallback, gruby.ArgsNone())
value, err := mrb.LoadString("Hello.new.foo")
value, err := grb.LoadString("Hello.new.foo")
g.Expect(err).ToNot(HaveOccurred())

testCallbackResult(g, value)
Expand All @@ -56,10 +56,10 @@ func TestClassNew(t *testing.T) {
t.Parallel()
g := NewG(t)

mrb := gruby.NewMrb()
defer mrb.Close()
grb := gruby.New()
defer grb.Close()

class := mrb.DefineClass("Hello", mrb.ObjectClass())
class := grb.DefineClass("Hello", grb.ObjectClass())
class.DefineMethod("foo", testCallback, gruby.ArgsNone())

instance, err := class.New()
Expand All @@ -75,18 +75,18 @@ func TestClassNewException(t *testing.T) {
t.Parallel()
g := NewG(t)

mrb := gruby.NewMrb()
grb := gruby.New()

defer mrb.Close()
defer grb.Close()

class := mrb.DefineClass("Hello", mrb.ObjectClass())
class := grb.DefineClass("Hello", grb.ObjectClass())
class.DefineMethod("initialize", testCallbackException, gruby.ArgsNone())

_, err := class.New()
g.Expect(err).To(HaveOccurred())

// Verify exception is cleared
val, err := mrb.LoadString(`"test"`)
val, err := grb.LoadString(`"test"`)
g.Expect(err).ToNot(HaveOccurred())

g.Expect(val.String()).To(Equal("test"))
Expand All @@ -96,9 +96,9 @@ func TestClassValue(t *testing.T) {
t.Parallel()
g := NewG(t)

mrb := gruby.NewMrb()
defer mrb.Close()
grb := gruby.New()
defer grb.Close()

class := mrb.DefineClass("Hello", mrb.ObjectClass())
class := grb.DefineClass("Hello", grb.ObjectClass())
g.Expect(class.Type()).To(Equal(class.Type()))
}
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func main() {
grb := gruby.NewMrb()
grb := gruby.New()
defer grb.Close()

workDir, err := os.Getwd()
Expand Down
12 changes: 6 additions & 6 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import "C"
type CompileContext struct {
ctx *C.mrbc_context
filename string
mrb *GRuby
grb *GRuby
}

// NewCompileContext constructs a *CompileContext from a *Mrb.
func NewCompileContext(mrb *GRuby) *CompileContext {
// NewCompileContext constructs a *CompileContext from a *GRuby
func NewCompileContext(grb *GRuby) *CompileContext {
return &CompileContext{
ctx: C.mrb_ccontext_new(mrb.state),
ctx: C.mrb_ccontext_new(grb.state),
filename: "",
mrb: mrb,
grb: grb,
}
}

Expand All @@ -27,7 +27,7 @@ func NewCompileContext(mrb *GRuby) *CompileContext {
// This is safe to call once the context has been used for parsing/loading
// any Ruby code.
func (c *CompileContext) Close() {
C.mrbc_context_free(c.mrb.state, c.ctx)
C.mrbc_context_free(c.grb.state, c.ctx)
}

// Filename returns the filename associated with this context.
Expand Down
6 changes: 3 additions & 3 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ func TestCompileContextFilename(t *testing.T) {
t.Parallel()
g := NewG(t)

mrb := gruby.NewMrb()
defer mrb.Close()
grb := gruby.New()
defer grb.Close()

ctx := gruby.NewCompileContext(mrb)
ctx := gruby.NewCompileContext(grb)
defer ctx.Close()

g.Expect(ctx.Filename()).To(BeEmpty())
Expand Down
Loading

0 comments on commit 7b7484f

Please sign in to comment.