Struct VM

Source
pub struct VM;
Expand description

Virtual Machine and helpers

Implementations§

Source§

impl VM

Source

pub fn init()

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
Source

pub fn require(name: &str)

Requires Ruby source file.

§Examples
use ruru::VM;

VM::require("some_ruby_file");

Ruby:

require 'some_ruby_file'
Source

pub fn raise(exception: Class, message: &str)

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'
Source

pub fn block_proc() -> Proc

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!"
Source

pub fn is_block_given() -> bool

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
Source

pub fn parse_arguments( argc: Argc, arguments: *const AnyObject, ) -> Vec<AnyObject>

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);
}
Source

pub fn thread_call_without_gvl<F, R, G>(func: F, unblock_func: Option<G>) -> R
where F: FnOnce() -> R, G: FnOnce(),

👎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);
    });
}
Source

pub fn thread_call_without_gvl2<F, R, G>(func: F, unblock_func: Option<G>) -> R
where F: FnOnce() -> R, G: FnOnce(),

👎Deprecated since 0.9.2: Use Thread::call_without_gvl2() instead
Source

pub fn thread_call_with_gvl<F, R>(func: F) -> R
where F: FnOnce() -> R,

👎Deprecated since 0.9.2: Use Thread::call_with_gvl() instead
Source

pub fn protect<F>(func: F) -> Result<Value, i32>
where F: FnOnce(),

Auto Trait Implementations§

§

impl Freeze for VM

§

impl RefUnwindSafe for VM

§

impl Send for VM

§

impl Sync for VM

§

impl Unpin for VM

§

impl UnwindSafe for VM

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.