Struct ruru::VM
[−]
[src]
pub struct VM;
Virtual Machine and helpers
Methods
impl VM
[src]
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
fn require(name: &str)
Requires Ruby source file.
Examples
use ruru::VM; VM::require("some_ruby_file");
Ruby:
require 'some_ruby_file'
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'
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!"
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
fn parse_arguments(argc: Argc, arguments: *const AnyObject) -> Vec<AnyObject>
Converts a pointer to array of AnyObject
s 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); }
fn thread_call_without_gvl<F, R, G>(func: F, unblock_func: Option<G>) -> R where F: FnOnce() -> R, G: FnOnce()
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); }); }