用mruby执行Ruby代码

用mruby执行Ruby代码

来源  http://mruby.org/docs/articles/executing-ruby-code-with-mruby.html

http://mruby.org/
https://github.com/mruby/mruby
http://bip.cnrs-mrs.fr/bip06/qsoas/downloads.html
https://github.com/fourmond/QSoas
http://plato.click/

$ wget --no-hsts --no-check-certificate https://github.com/mruby/mruby/archive/2.1.2.tar.gz
$ mv 2.1.2.tar.gz mruby-2.1.2.tar.gz
$ tar -zxvpf mruby-2.1.2.tar.gz
$ 
$ cd mruby-2.1.2
$ ./minirake all
$ tree ./bin/
$ 
$ tree ./bin/host/bin/
$ tree ./bin/host/lib/
$ tree ./build/host-debug/bin/
$ tree ./build/host-debug/lib/
$ tree ./build/test/bin/
$ tree ./build/test/lib/
$ 

最初由Daniel Bovensiepen撰写

执行Ruby代码的传统方法是分发纯源代码,并需要安装大量文件的Ruby解释器。mruby也可以这样使用。因此,如果您有使用其他Ruby实现的经验,那么您可能会知道此处列出的一些示例。但是,使用mruby,您还可以构建独立的程序并编译为可以转储和加载的字节码。

test_program.rb在某些示例中使用了一个名为的文件其内容是:

puts 'hello world'

REPL (mirb)

并非完全直接用于程序执行,但仍可以使用以下mirb程序来评估Ruby代码

$ mruby/bin/mirb
mirb - Embeddable Interactive Ruby Shell

> puts 'hello world'
hello world
 => nil

优点缺点

✔直接反馈,无需任何间接文件

✘不适用于生产执行

✘输入需要解析两次:首先mirb检查代码是否完整,然后mirb将其编译为字节码并执行

Source code (.rb)

运行Ruby代码的最常见方法是将文件名作为参数传递给解释器。在mruby中,该mruby程序是:

$ mruby/bin/mruby test_program.rb
hello world

优点缺点

✔非常简单的开发周期:编程→测试→编程

has必须向用户提供Ruby代码

✘需要mruby程序和文件系统

execution必须先将Ruby代码解析并编译为字节码

Source code (.c)

Ruby代码也可以编写为C字符串。这类似于程序-e切换mruby

#include <mruby.h>
#include <mruby/compile.h>

int
main(void)
{
  mrb_state *mrb = mrb_open();
  if (!mrb) { /* handle error */ }
  // mrb_load_string(mrb, str) to load from NULL terminated strings
  // mrb_load_nstring(mrb, str, len) for strings without null terminator or with known length
  mrb_load_string(mrb, "puts 'hello world'");
  mrb_close(mrb);
  return 0;
}

编译和链接:

$ gcc -std=c99 -Imruby/include test_program.c -o test_program mruby/build/host/lib/libmruby.a -lm

执行:

$ ./test_program
hello world

优点缺点

✔简单的开发周期:编程→编译(gcc)→测试→编程

✔该程序是完全独立的

✘需要额外的样板才能启动程序并运行

execution必须先将Ruby代码解析并编译为字节码

✘更新Ruby代码可能需要重新编译C代码或高级更新机制

Bytecode (.mrb)

mruby通过编译为将要执行的中间表示形式来提供类似于Java的执行样式。

第一步是使用mrbc程序将源代码编译为字节码

$ mruby/bin/mrbc test_program.rb

这将产生一个名为的文件test_program.mrb,其中包含先前给定Ruby代码的中间表示形式:

$ hexdump -C test_program.mrb
00000000  52 49 54 45 30 30 30 33  e1 c0 00 00 00 65 4d 41  |RITE0003.....eMA|
00000010  54 5a 30 30 30 30 49 52  45 50 00 00 00 47 30 30  |TZ0000IREP...G00|
00000020  30 30 00 00 00 3f 00 01  00 04 00 00 00 00 00 04  |00...?..........|
00000030  00 80 00 06 01 00 00 3d  00 80 00 a0 00 00 00 4a  |.......=.......J|
00000040  00 00 00 01 00 00 0b 68  65 6c 6c 6f 20 77 6f 72  |.......hello wor|
00000050  6c 64 00 00 00 01 00 04  70 75 74 73 00 45 4e 44  |ld......puts.END|
00000060  00 00 00 00 08                                    |.....|
00000065

该文件可以由mruby程序或mrb_load_irep_file() 功能执行。-b开关告诉程序,该文件是字节码,而不是普通的Ruby代码:

$ mruby/bin/mruby -b test_program.mrb
hello world

优点缺点

✔无需向用户提供Ruby代码

✔无需解析任何Ruby代码

✔通过替换.mrb文件可以轻松更新字节码

✘复杂的开发周期:编程→编译(mrbc)→测试(mruby)→编程

✘需要mruby程序和文件系统

Bytecode (.c)

对于希望将Ruby代码直接集成到其C代码中的人来说,此变体很有趣。它将创建一个包含字节码的C数组,然后您必须自己执行该字节码。

第一步是编译Ruby程序。这是通过使用mrbc 及其-B开关来完成的数组的标识符也必须给出:

$ mruby/bin/mrbc -Btest_symbol test_program.rb

这将创建一个test_program.c包含test_symbol数组的文件

/* dumped in little endian order.
   use `mrbc -E` option for big endian CPU. */
#include <stdint.h>
const uint8_t
#if defined __GNUC__
__attribute__((aligned(4)))
#elif defined _MSC_VER
__declspec(align(4))
#endif
test_symbol[] = {
0x45,0x54,0x49,0x52,0x30,0x30,0x30,0x33,0x73,0x0d,0x00,0x00,0x00,0x65,0x4d,0x41,
0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x00,0x47,0x30,0x30,
0x30,0x30,0x00,0x00,0x00,0x3f,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x04,
0x06,0x00,0x80,0x00,0x3d,0x00,0x00,0x01,0xa0,0x00,0x80,0x00,0x4a,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x00,0x00,0x0b,0x68,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,
0x6c,0x64,0x00,0x00,0x00,0x01,0x00,0x04,0x70,0x75,0x74,0x73,0x00,0x45,0x4e,0x44,
0x00,0x00,0x00,0x00,0x08,
};

要执行此字节码,必须编写以下样板文件(将此文件命名为test_stub.c):

#include <mruby.h>
#include <mruby/irep.h>
#include <test_program.c>

int
main(void)
{
  mrb_state *mrb = mrb_open();
  if (!mrb) { /* handle error */ }
  mrb_load_irep(mrb, test_symbol);
  mrb_close(mrb);
  return 0;
}

这将从数组中读取字节码并立即执行:

编译和链接:

$ gcc -std=c99 -Imruby/include test_stub.c -o test_program mruby/build/host/lib/libmruby.a -lm

执行:

$ ./test_program
hello world

优点缺点

✔无需向用户提供Ruby代码

✔无需解析任何Ruby代码

✔该程序是完全独立的

✘更加复杂的开发周期:编程→编译(mrbc)→集成C代码→编译(gcc)→测试→编程

✘需要额外的样板才能启动程序并运行

✘更新字节码需要重新编译C代码或高级更新机制

Fazit

REPL(mirb)的早期发育过程中主要使用。 如今,源代码(.rb)是mruby的最常用用法,因为它强调Ruby作为一种脚本语言,可以通过更改计算机上的源代码轻松对其进行修改。源代码(.c) 是将mruby嵌入到您自己的应用程序中的最简单步骤。 字节码(.mrb)提供Java应用程序的感觉,该Java应用程序可以基于文件安装,但不提供对源代码的访问。 字节码(.c)对于许多人来说很可能是使用mruby的最复杂方法,但同时它提供了在程序内部执行mruby代码的最有效方法。

========== End

原文地址:https://www.cnblogs.com/lsgxeva/p/14248362.html