mruby
Who I am
- Full stack Developer
- Working for Pilot.co
- Traveling
- Cycling in free time
@michalkozminski
Michał Koźmiński
What is mruby?
- CRuby subset
- Lua alternative
- no need for POSIX
- Could be embedded
- mostly compatible with CRuby 2.1
Lets start
mruby toolset
mirb
mrbc
Compiles *.rb to *.mrb which is bytecode for RiteVM
cat test.rb
puts "ok"
./mrbc --verbose -g test.rb
00001 NODE_SCOPE:
00001 NODE_BEGIN:
00001 NODE_CALL:
00001 NODE_SELF
00001 method='puts' (218)
00001 args:
00001 NODE_STR "ok" len 2
irep 0x7fef0340d720 nregs=4 nlocals=1 pools=1 syms=1 reps=0
file: test.rb
1 000 OP_LOADSELF R1
1 001 OP_STRING R2 L(0) ; "ok"
1 002 OP_SEND R1 :puts 1
1 003 OP_STOP
cat test1.rb
puts 1+2
./mrbc --verbose -g test1.rb
00001 NODE_SCOPE:
00001 NODE_BEGIN:
00001 NODE_CALL:
00001 NODE_SELF
00001 method='puts' (218)
00001 args:
00001 NODE_CALL:
00001 NODE_INT 1 base 10
00001 method='+' (117)
00001 args:
00001 NODE_INT 2 base 10
irep 0x7f98a1c0d730 nregs=5 nlocals=1 pools=0 syms=2 reps=0
file: test1.rb
1 000 OP_LOADSELF R1
1 001 OP_LOADI R2 1
1 002 OP_ADDI R2 :+ 2
1 003 OP_SEND R1 :puts 1
1 004 OP_STOP
mrdb
mruby debugger
mruby
Differences
- no require file
- no threads
- there ise mruby-thread gem
- no native support of Kernel#sleep
Embedded usage
Ruby in C/C++
mruby in C
#include <mruby.h>
#include <mruby/compile.h>
int main(void) {
mrb_state *mrb = mrb_open();
mrb_load_string(mrb, "puts \"hello world! #{1+1}\"");
mrb_close(mrb);
return 0;
}
-----------------------
gcc -Iinclude hello.c build/host/lib/libmruby.a -lm -o hello.out
./hello.out
hello world! 2
Bytecode in C
./mrbc -Btest_string test.rb
-----------
test_string[] = {
0x45,0x54,0x49,0x52,0x30,0x30,0x30,0x33,0x02,0x60,0x00,0x00,0x01,0x9f,0x4d,0x41,
0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x01,0x54,0x30,0x30,
0x30,0x30,0x00,0x00,0x00,0xae,0x00,0x04,0x00,0x07,0x00,0x01,0x00,0x00,0x00,0x13,
0x3d,0x00,0x80,0x00,0x11,0x00,0x00,0x02,0x01,0x40,0x80,0x02,0x40,0x01,0x00,0x03,
0xa1,0x40,0x00,0x02,0x01,0x00,0x01,0x01,0x20,0x80,0x00,0x02,0x01,0x00,0x81,0x01,
0x06,0x00,0x00,0x02,0xbd,0x00,0x80,0x02,0x01,0x40,0x00,0x03,0x3e,0x80,0x81,0x02,
0xa0,0xc0,0x00,0x02,0x06,0x00,0x00,0x02,0xbd,0x01,0x80,0x02,0x01,0xc0,0x00,0x03,
0x3e,0x80,0x81,0x02,0xa0,0xc0,0x00,0x02,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
0x00,0x00,0x03,0x66,0x6f,0x6f,0x00,0x00,0x0e,0x69,0x6e,0x20,0x6d,0x61,0x69,0x6e,
0x3a,0x20,0x76,0x20,0x69,0x73,0x20,0x00,0x00,0x00,0x00,0x00,0x0e,0x69,0x6e,0x20,
0x6d,0x61,0x69,0x6e,0x3a,0x20,0x72,0x20,0x69,0x73,0x20,0x00,0x00,0x00,0x04,0x00,
0x06,0x54,0x68,0x72,0x65,0x61,0x64,0x00,0x00,0x03,0x6e,0x65,0x77,0x00,0x00,0x04,
0x6a,0x6f,0x69,0x6e,0x00,0x00,0x04,0x70,0x75,0x74,0x73,0x00,0x00,0x00,0x00,0xa0,
0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x26,0x00,0x00,0x02,
0x06,0x00,0x80,0x01,0x3d,0x00,0x00,0x02,0x01,0x40,0x80,0x02,0x3e,0x40,0x01,0x02,
0xa0,0x00,0x80,0x01,0x06,0x00,0x80,0x01,0x3d,0x01,0x00,0x02,0x15,0x40,0x80,0x02,
0x20,0x40,0x80,0x02,0x3e,0x40,0x01,0x02,0xa0,0x00,0x80,0x01,0xbd,0x01,0x80,0x01,
0x16,0x40,0x80,0x01,0x3d,0x02,0x80,0x01,0x29,0x00,0x80,0x01,0x00,0x00,0x00,0x05,
0x00,0x00,0x10,0x69,0x6e,0x20,0x74,0x68,0x72,0x65,0x61,0x64,0x3a,0x20,0x78,0x20,
0x69,0x73,0x20,0x00,0x00,0x00,0x00,0x00,0x10,0x69,0x6e,0x20,0x74,0x68,0x72,0x65,
0x61,0x64,0x3a,0x20,0x76,0x20,0x69,0x73,0x20,0x00,0x00,0x03,0x62,0x61,0x72,0x00,
0x00,0x03,0x62,0x61,0x7a,0x00,0x00,0x00,0x02,0x00,0x04,0x70,0x75,0x74,0x73,0x00,
0x00,0x07,0x69,0x6e,0x73,0x70,0x65,0x63,0x74,0x00,0x4c,0x56,0x41,0x52,0x00,0x00,
0x00,0x2d,0x00,0x00,0x00,0x04,0x00,0x01,0x76,0x00,0x02,0x74,0x68,0x00,0x01,0x72,
0x00,0x01,0x78,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x00,
0x03,0x00,0x01,0xff,0xff,0x00,0x00,0x45,0x4e,0x44,0x00,0x00,0x00,0x00,0x08,
};
#include <mruby.h>
#include <mruby/irep.h>
#include <mruby/proc.h>
int main(void)
{
mrb_state *mrb = mrb_open();
int n = mrb_read_irep(mrb, test_symbol);
mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
mrb_close(mrb);
return 0;
}
-------
gcc -Iinclude test_string.c build/host/lib/libmruby.a -lm -o test_string.out
extending mruby
mrbgem.rake
MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'Example mrbgem using C and ruby'
# Example dependency
spec.add_dependency('mruby-parser', '>= 1.0.0', '<= 1.5.2')
end
mrblib
module CRubyExtension
def CRubyExtension.ruby_method
puts "A Ruby Extension"
end
end
src
#include <mruby.h>
#include <stdio.h>
static mrb_value mrb_c_method(mrb_state *mrb, mrb_value self)
{
puts("A C Extension");
return self;
}
void mrb_c_and_ruby_extension_example_gem_init(mrb_state* mrb) {
struct RClass *class_cextension = mrb_define_module(mrb, "CRubyExtension");
mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, MRB_ARGS_NONE());
}
void mrb_c_and_ruby_extension_example_gem_final(mrb_state* mrb) {
/* finalizer */
}
Examples of use
mruby web irb
mruby arduino
unless Object.const_defined? :Serial
Serial = Serial2
end
class Blinker
include Arduino
attr_accessor :interval ,:pin
def initialize(pin, interval_ms)
Serial.println("Blinker initialized")
@pin = pin
@interval = interval_ms
pinMode(@pin, OUTPUT)
end
def run
Serial.println("blink!")
digitalWrite(@pin, HIGH)
delay(@interval)
digitalWrite(@pin, LOW)
delay(@interval)
end
end
MobiRuby
Thanks, Bye
mruby
By Michał Koźmiński
mruby
- 737