mruby

package module
v0.0.0-...-5c800b6 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2015 License: MIT Imports: 8 Imported by: 0

README

MRuby for Go

The mruby-go package enables you to use the embedded Ruby interpreter mruby inside Go projects.

Godoc license

Status

The API is not stable. We consider this early alpha.

We're using mruby-go in pre-production systems and are pretty confident that it behaves as a good citizen. But we don't give any guarantees.

Read the tests to get a feel of what works and what doesn't.

Prerequisites

We're using mruby-go with Google Go 1.4, but it should work with 1.1+ and tip as well.

The mruby interpreter went 1.0.0 on 9th Feb 2014, and we have tested it with that version successfully. We currently use mruby 1.1.0, which has a lot of bug fixes.

You can find a tarball of all mruby releases here.

Installation

Building mruby-go depends on pkg-config. Make sure to have a valid pkg-config file for mruby in your PKG_CONFIG_PATH. I've compiled mruby locally, so here's my mruby.pc:

prefix=<home>/ext/mruby
exec_prefix=${prefix}
libdir=${exec_prefix}/build/host/lib
includedir=${prefix}/include

Name: libmruby
Description: Embedded Ruby (mruby)
Version: 1.1.0
Libs: -L${libdir} -lmruby
Libs.private: -lm
Cflags: -I${includedir}

Make sure that pkg-config --list-all includes mruby.

Notice that the configuration of mruby is quite simple, you can (and probably should) review all settings with regard to your environment. There's a section on configuring mruby below.

Next, build mruby-go:

go build

Then run tests with:

go test

and benchmarks with:

go test -bench .

Getting started

See the examples directory or the tests for example usage. You can run the examples after successfully building mruby and mruby-go.

Example:

go run examples/run.go examples/hello_world.rb

Configuring mruby

There is a short summary of how to configure mruby in the mruby repository, especially in the INSTALL file. However, we will try to summarize configuration in our own words.

  1. Download mruby from here.
  2. Untar the repository and cd into the expanded directory.
  3. Run ruby ./minirake
  4. That should succeed and create some binaries in bin and some libs in lib.

If you want to add some (mruby-specific) gems to your mruby installation, edit the ./build_config.rb and add a line to it, e.g. conf.gem :git => 'git@github.com:iij/mruby-io.git', :branch => master. Then compile again via ruby ./minirake. We're using e.g. mattn/mruby-json. The Internet Initiative Japan Inc. has quite a lot of mruby gems on GitHub. Pick what you need.

For configuring details we edit ./include/mrbconf.h. We're not sure if this is the correct way of doing things, but it works fine.

Support

Feel free to send pull requests.

License

This package has a MIT-LICENSE.

Documentation

Overview

Package mruby embeds the Ruby programming language into your Go project. mruby is a lightweight implementation of the Ruby language complying to the ISO standard. mruby can be linked and embedded within an application. This package makes mruby available in your Go projects, effectively enabling Ruby as a scripting language within your Go code.

mruby went 1.0.0 on 9th Feb 2014. The current version of mruby is 1.1.0, and mruby-go is tested with it.

You can find the mruby source code at https://github.com/mruby/mruby. Tarballs are available from https://github.com/mruby/mruby/releases.

Example:

ctx := mruby.NewContext()
ctx.LoadString("p 'Hello world'")

If successful, these two lines of code will print "Hello world!" to stdout.

Example
// Create a new context
ctx := mruby.NewContext()

// Run a script that returns the value of 1+2
val, err := ctx.LoadString("1 + 2")
if err != nil {
	fmt.Println("LoadStringResult failed")
	return
}

// Convert the value to an int
i, err := val.ToInt()
if err != nil {
	fmt.Println("Result is not a Fixnum")
	return
}
fmt.Printf("1+2=%d\n", i)
Output:

1+2=3
Example (AutomaticallyConvertToGoInterface)
// Create a new context
ctx := mruby.NewContext()

// Run a script that returns the value of 1+2 and directly converts to Go
res, err := ctx.LoadStringResult("1 + 2")
if err != nil {
	fmt.Println("LoadStringResult failed")
	return
}
fmt.Printf("1+2=%d", res)
Output:

1+2=3
Example (WithArguments)
// Create a new context.
ctx := mruby.NewContext()

// Run a script that adds all values and directly converts the result to Go.
// The args of LoadStringXXX will be available via ARGV in the script.
res, err := ctx.LoadStringResult("ARGV.inject { |x,y| x+y }", 1, 2, 3.5)
if err != nil {
	fmt.Println("LoadStringResult failed")
	return
}
fmt.Println(res)
Output:

6.5

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidType is returned when the package cannot convert a Ruby
	// type to the Go equivalent.
	ErrInvalidType = errors.New("invalid type")
)

Functions

func SetFilename

func SetFilename(filename string) func(*Context)

SetFilename sets the filename to be used in the context (default: "(mruby-go)"). It is used for configuring a Context (see NewContext for details).

func SetNoExec

func SetNoExec(noExec bool) func(*Context)

SetNoExec indicates whether scripts given to this context, e.g. via LoadString, are automatically run once loaded and/or parsed. It is used for configuring a Context (see NewContext for details).

Types

type Args

type Args C.mrb_aspec

Args is used to specify the number of arguments a Go extension method will use. Use one of the ArgsAny, ArgsNone, ArgsRequired, ArgsOptional, or ArgsArg helper functions to initialize it.

func ArgsAny

func ArgsAny() Args

ArgsAny specifies a function with any number of arguments.

func ArgsArg

func ArgsArg(required, optional int) Args

ArgsArg specifies a function that a number of required and optional arguments.

func ArgsNone

func ArgsNone() Args

ArgsNone specifies a function that accepts no arguments.

func ArgsOptional

func ArgsOptional(optional int) Args

ArgsOptional specifies a function that accepts a number of options arguments.

func ArgsRequired

func ArgsRequired(required int) Args

ArgsRequired specifies a function that accepts a number of required arguments.

type Class

type Class struct {
	// contains filtered or unexported fields
}

Class represents a class in Ruby.

func NewClass

func NewClass(ctx *Context, name string, super *Class) (*Class, error)

NewClass defines a new class with the given name and super-class in the context. If super is nil, ObjectClass is used by default.

func NewClassUnder

func NewClassUnder(ctx *Context, name string, super *Class, outer RClass) (*Class, error)

func (*Class) DefineClassMethod

func (c *Class) DefineClassMethod(name string, f Function)

DefineMethod registers a class method with the name in the class. The function is called when executed in Ruby.

func (*Class) DefineMethod

func (c *Class) DefineMethod(name string, f Function)

DefineMethod registers an instance method with the name in the class. The function is called when executed in Ruby.

func (*Class) RClass

func (c *Class) RClass() *C.struct_RClass

RClass returns the MRuby object of type *struct RClass.

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context serves as the entry point for all communication with mruby.

func NewContext

func NewContext(options ...func(*Context)) *Context

NewContext creates a new mruby context. Use the options to handle configuration.

Examples:

ctx := mruby.NewContext()
ctx := mruby.NewContext(mruby.SetNoExec(true), mruby.SetFilename("simple.rb"))

func (*Context) DefineClass

func (ctx *Context) DefineClass(name string, super *Class) (*Class, error)

DefineClass defines a new class with the given name and super-class in the context. If super is nil, ObjectClass is used by default.

func (*Context) DefineClassUnder

func (ctx *Context) DefineClassUnder(name string, super *Class, outer RClass) (*Class, error)

DefineClassUnder defines a new class with the given name and super-class under e.g. a specific module in the context. If super is nil, ObjectClass is used by default. If under is nil, the top-level module is used.

func (*Context) DefineModule

func (ctx *Context) DefineModule(name string, outer RClass) (*Module, error)

DefineModule defines a new module with the given name under outer. If outer is nil, the registered module is a top-level module.

func (*Context) GC

func (ctx *Context) GC()

GC runs the full MRuby garbage collector.

func (*Context) GetArgs

func (ctx *Context) GetArgs() ([]Value, error)

GetArgs extracts the arguments from args.

func (*Context) GetClass

func (ctx *Context) GetClass(name string, outer RClass) (*Class, bool)

GetClass returns the given class.

func (*Context) GetModule

func (ctx *Context) GetModule(name string, outer RClass) (*Module, bool)

GetModule returns the given module.

func (*Context) HasClass

func (ctx *Context) HasClass(name string, outer RClass) bool

HasClass tests if the context has a class with the given name.

func (*Context) HasModule

func (ctx *Context) HasModule(name string, outer RClass) bool

HasModule tests if the context has a module with the given name.

func (*Context) IncrementalGC

func (ctx *Context) IncrementalGC()

GC runs the incremental MRuby garbage collector.

func (*Context) KernelModule

func (ctx *Context) KernelModule() *Module

KernelModule runs the class for the Kernel module.

func (*Context) LoadString

func (ctx *Context) LoadString(code string, args ...interface{}) (Value, error)

LoadString loads a snippet of Ruby code and returns its output. An error is returned if the interpreter failes or the Ruby code raises an exception of type RunError.

func (*Context) LoadStringResult

func (ctx *Context) LoadStringResult(code string, args ...interface{}) (interface{}, error)

LoadStringResult invokes LoadString and returns the Go value immediately. Use this method to skip testing the returned Value.

func (*Context) ObjectClass

func (ctx *Context) ObjectClass() *Class

ObjectClass runs the class for Object class.

func (*Context) ObjectModule

func (ctx *Context) ObjectModule() *Module

ObjectModule is the same as ObjectClass, however it returns a Module.

func (*Context) Parse

func (ctx *Context) Parse(code string) (*Parser, error)

Parse parses a string into parsed Ruby code. An error is returned if compilation failes.

func (*Context) ToValue

func (ctx *Context) ToValue(value interface{}) (Value, error)

ToValue stores the given value for encoding/decoding from/to Go and MRuby.

type Function

type Function func(ctx *Context) (Value, error)

Function defines the signature of a Go function that can be called from within a MRuby script.

Example
// Create a new context, and set some options
ctx := mruby.NewContext()
if ctx == nil {
	fmt.Println("Cannot initialize context")
	return
}

// sayHello is an extension method that can be called from Ruby.
sayHello := func(ctx *mruby.Context) (output mruby.Value, err error) {
	// We expect a string here.
	args, err := ctx.GetArgs()
	if err != nil {
		return mruby.NilValue(ctx), err
	}
	if len(args) == 1 {
		s, err := args[0].ToString()
		if err != nil {
			return mruby.NilValue(ctx), err
		}
		s = fmt.Sprintf("Hello %s!", s)
		return ctx.ToValue(s)
	}
	return mruby.NilValue(ctx), nil
}

// We create a new module called Helpers that will hold our extension method.
module, err := ctx.DefineModule("Helpers", nil)
if err != nil {
	fmt.Println("Cannot create module")
	return
}
if module == nil {
	fmt.Println("Method is nil")
	return
}

// Now we register the extension method. It will be available as
// Helper.say_hello from within Ruby and requires 1 argument.
module.DefineClassMethod("say_hello", sayHello)

greeting, err := ctx.LoadStringResult("Helpers.say_hello(ARGV[0])", "Matz")
if err != nil {
	fmt.Printf("Cannot execute say_hello method: %v\n", err)
	return
}
fmt.Println(greeting)
Output:

Hello Matz!

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module is a Ruby module.

func NewModule

func NewModule(ctx *Context, name string, outer RClass) (*Module, error)

NewModule defines a new module with the given name under outer. If outer is nil, the registered module is a top-level module.

func (*Module) DefineClassMethod

func (m *Module) DefineClassMethod(name string, f Function)

DefineClassMethod registers a class method with the name in the module. The function is called when executed in Ruby.

func (*Module) DefineMethod

func (m *Module) DefineMethod(name string, f Function)

DefineMethod registers a method with the name in the module. The function is called when executed in Ruby.

func (*Module) RClass

func (m *Module) RClass() *C.struct_RClass

RClass returns the MRuby object of type *struct RClass.

type ParseError

type ParseError struct {
	Line    int    // Line number
	Message string // Message details
}

ParseError is used to indicate errors while parsing Ruby code.

func (*ParseError) Error

func (e *ParseError) Error() string

Error returns the error as a string.

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser is a parser for Ruby code. It can be used to parse Ruby code once and run it multiple times.

Example
// Create a new context
ctx := mruby.NewContext()

// Create a parser to parse the given code
code := `
def concat(a, b)
	a + b
end

concat "Hello", "World"
`
parser, err := ctx.Parse(code)
if err != nil {
	fmt.Println("Parser cannot parse")
	return
}

// Run the code
val, err := parser.Run()
if err != nil {
	fmt.Println("Run failed")
	return
}
res, err := val.ToInterface()
if err != nil {
	fmt.Println("Cannot convert")
	return
}
s, ok := res.(string)
if !ok {
	fmt.Println("Not a string")
	return
}
fmt.Println(s)
Output:

HelloWorld

func (*Parser) Run

func (p *Parser) Run(args ...interface{}) (Value, error)

Run runs a previously compiled Ruby code and returns its output. An error is returned if the Ruby code raises an exception.

type RClass

type RClass interface {
	RClass() *C.struct_RClass
}

type RunError

type RunError struct {
	Message string // Message details
}

RunError is used to indicate errors while running Ruby code.

func (*RunError) Error

func (e *RunError) Error() string

Error returns the error as a string.

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value is used for encoding/decoding data types from MRuby to Go and vice versa.

func NilValue

func NilValue(ctx *Context) Value

NilValue returns a mruby nil value.

func (Value) IsArray

func (v Value) IsArray() bool

IsArray indicates whether this value is an array.

func (Value) IsBool

func (v Value) IsBool() bool

IsBool indicates whether this value is a bool.

Notice: In Ruby, everything that is not false is a boolean. However, this method respects the Go type bool that has two distinct values: true or false.

func (Value) IsFixnum

func (v Value) IsFixnum() bool

IsFixnum indicates whether this value is a fixed number.

Notice: Ruby only has fixed numbers and floats. So there is no equivalent to e.g. int8 or uint16.

func (Value) IsFloat

func (v Value) IsFloat() bool

IsFloat indicates whether this value is a float.

Notice: Ruby only has fixed numbers and floats. So this method returns true if the Ruby type is a float and therefore can be converted to float32.

func (Value) IsHash

func (v Value) IsHash() bool

IsHash indicates whether this value is a hash.

func (Value) IsNil

func (v Value) IsNil() bool

IsNil indicates whether this value is nil.

func (Value) IsProc

func (v Value) IsProc() bool

IsProc indicates whether this value is a Proc.

func (Value) IsString

func (v Value) IsString() bool

IsString indicates whether this value can be converted to a string.

func (Value) IsSymbol

func (v Value) IsSymbol() bool

IsSymbol indicates whether this value is a Ruby symbol.

func (Value) Run

func (v Value) Run() (Value, error)

Run runs the code given that it is a reference to a Proc.

func (Value) String

func (v Value) String() string

String returns a string representation of the value.

func (Value) ToArray

func (v Value) ToArray() ([]interface{}, error)

ToArray treats this value as an array and returns its values. If the value is not a Ruby Array, an error is returned.

func (Value) ToBool

func (v Value) ToBool() (bool, error)

ToBool treats this value as a bool and returns its value. If the value is not a bool, an error is returned.

func (Value) ToFloat32

func (v Value) ToFloat32() (float32, error)

ToFloat32 treats this value as a float32 and returns its value. If the value is not a Ruby Float, an error is returned.

func (Value) ToFloat64

func (v Value) ToFloat64() (float64, error)

ToFloat64 treats this value as a float64 and returns its value. If the value is not a Ruby Float, an error is returned.

func (Value) ToInt

func (v Value) ToInt() (int, error)

ToInt treats this value as an int and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToInt16

func (v Value) ToInt16() (int16, error)

ToInt16 treats this value as an int16 and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToInt32

func (v Value) ToInt32() (int32, error)

ToInt32 treats this value as an int32 and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToInt64

func (v Value) ToInt64() (int64, error)

ToInt64 treats this value as an int64 and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToInt8

func (v Value) ToInt8() (int8, error)

ToInt8 treats this value as an int8 and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToInterface

func (v Value) ToInterface() (interface{}, error)

ToInterface will return the Go-equivalent of the Ruby value. It will only handle the following Ruby types: TrueClass, FalseClass, NilClass, Fixnum, Float, Symbol, String, Array, and Hash. All other Ruby types return nil.

func (Value) ToMap

func (v Value) ToMap() (map[string]interface{}, error)

ToMap treats this value as a hash and returns its values as a map. If the value is not a Ruby Hash, an error is returned.

func (Value) ToString

func (v Value) ToString() (string, error)

ToString returns a string for MRuby types String and Symbol. If the value is not a Ruby String or Symbol, an error is returned.

func (Value) ToUint

func (v Value) ToUint() (uint, error)

ToUint treats this value as an uint and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToUint16

func (v Value) ToUint16() (uint16, error)

ToUint16 treats this value as an uint16 and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToUint32

func (v Value) ToUint32() (uint32, error)

ToUint32 treats this value as an uint32 and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToUint64

func (v Value) ToUint64() (uint64, error)

ToUint64 treats this value as an uint64 and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) ToUint8

func (v Value) ToUint8() (uint8, error)

ToUint8 treats this value as an uint8 and returns its value. If the value is not a Ruby Fixnum, an error is returned.

func (Value) Type

func (v Value) Type() ValueType

Type returns type information.

type ValueType

type ValueType struct {
	// contains filtered or unexported fields
}

ValueType encapsulates information about a Value.

func (ValueType) String

func (vt ValueType) String() string

String returns a representation of the rubyType as a string.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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