Struct ruru::VM [] [src]

pub struct VM;

Virtual Machine and helpers

Methods

impl VM
[src]

Initializes Ruby virtual machine.

This function should ONLY be used if you write a standalone application which calls Ruby itself, for example:

  • Sidekiq-like background processing

  • Unicorn-like web server

In these cases it should be called before any interaction with Ruby.

If you write a library which is being connected to Ruby in runtime (e.g. some gem), this function should not be used.

Examples

use ruru::{Class, VM};

VM::init();

// VM started, able to use Ruby now
// ...

Class::new("SomeClass", None); // etc

Requires Ruby source file.

Examples

use ruru::VM;

VM::require("some_ruby_file");

Ruby:

require 'some_ruby_file'

Raises an exception.

Examples

Built-in exceptions

use ruru::{Class, VM};

VM::raise(Class::from_existing("ArgumentError"), "Wrong argument");

Ruby:

raise ArgumentError, 'Wrong argument'

Custom exceptions

use ruru::{Class, VM};

let standard_error = Class::from_existing("StandardError");
let custom_exception = Class::new("CustomException", Some(&standard_error));

VM::raise(custom_exception, "Something went wrong");

Ruby:

class CustomException < StandardError
end

raise CustomException, 'Something went wrong'

Converts a block given to current method to a Proc

It works similarly to def method(&block) which converts block to Proc

Examples

#[macro_use]
extern crate ruru;

use ruru::{Class, Object, Proc, RString, VM};

class!(Greeter);

methods!(
    Greeter,
    itself,

    fn greet_rust_with() -> RString {
        let greeting_template = VM::block_proc();
        let name = RString::new("Rust").to_any_object();

        greeting_template.call(vec![name]).try_convert_to::<RString>().unwrap()
    }
);

fn main() {
    Class::new("Greeter", None).define(|itself| {
        itself.def_self("greet_rust_with", greet_rust_with);
    });
}

Ruby:

class Greeter
  def self.greet_rust_with(&greeting_template)
    greeting_template.call('Rust')
  end
end

Greeter.greet_rust_with do |name|
  "Hello, #{name}!"
end
# => "Hello, Rust!"

Checks if a block is given to current method.

Examples

#[macro_use] extern crate ruru;

use ruru::{Class, Fixnum, Object, VM};

class!(Calculator);

methods!(
    Calculator,
    itself,

    fn calculate(a: Fixnum, b: Fixnum) -> Fixnum {
        let a = a.unwrap();
        let b = b.unwrap();

        if VM::is_block_given() {
            let result = VM::block_proc().call(vec![a.to_any_object(), b.to_any_object()]);

            result.try_convert_to::<Fixnum>().unwrap()
        } else {
            Fixnum::new(a.to_i64() + b.to_i64())
        }
    }
);

fn main() {

    Class::new("Calculator", None).define(|itself| {
        itself.def("calculate", calculate);
    });
}

Ruby:

class Calculator
  def calculate(a, b, &block)
    if block_given?
      block.call(a, b)
    else
      a + b
    end
  end
end

Converts a pointer to array of AnyObjects to Vec<AnyObject>.

This function is a helper for callbacks, do not use it directly.

It will be moved to other struct, because it is not related to VM itself.

Examples

use ruru::types::Argc;
use ruru::{AnyObject, Boolean, Class, Object, RString, VM};

#[no_mangle]
pub extern fn string_eq(argc: Argc, argv: *const AnyObject, itself: RString) -> Boolean {
    let argv = VM::parse_arguments(argc, argv);
    let other_string = argv[0].try_convert_to::<RString>().unwrap();

    Boolean::new(itself.to_string() == other_string.to_string())
}

fn main() {
    Class::from_existing("String").define_method("==", string_eq);
}

Deprecated since 0.9.2

: Use Thread::call_without_gvl() instead

Release GVL for current thread.

Warning! Due to MRI limitations, interaction with Ruby objects is not allowed while GVL is released, it may cause unexpected behaviour. Read more at Ruby documentation

You should extract all the information from Ruby world before invoking thread_call_without_gvl.

GVL will be re-acquired when the closure is finished.

Examples

#[macro_use] extern crate ruru;

use ruru::{Class, Fixnum, Object, VM};

class!(Calculator);

methods!(
    Calculator,
    itself,

    fn heavy_computation() -> Fixnum {
        let computation = || { 2 * 2 };
        let unblocking_function = || {};

        // release GVL for current thread until `computation` is completed
        let result = VM::thread_call_without_gvl(
            computation,
            Some(unblocking_function)
        );

        // GVL is re-acquired, we can interact with Ruby-world
        Fixnum::new(result)
    }
);

fn main() {
    Class::new("Calculator", None).define(|itself| {
        itself.def("heavy_computation", heavy_computation);
    });
}

Deprecated since 0.9.2

: Use Thread::call_without_gvl2() instead

Deprecated since 0.9.2

: Use Thread::call_with_gvl() instead