macro_rules! methods { ( $rtself_class: ty, $rtself_name: ident, $( fn $method_name: ident ($($arg_name: ident: $arg_type: ty),* $(,)?) -> $return_type: ty $body: block $(,)? )* ) => { ... }; }
Expand description
Creates callbacks for Ruby methods
Unlike unsafe_methods!
, this macro is safe, because:
- it uses safe conversions of arguments (
Object::try_convert_to()
); - it checks if arguments are present;
Each argument will have type Result<Object, AnyException>
.
For example, if you declare number: Fixnum
in the method definition, it will have actual
type number: Result<Fixnum, AnyException>
.
See examples below and docs for Object::try_convert_to()
for more information.
Examples
To launch a server in Rust, you plan to write a simple Server
class
class Server
def start(address)
# ...
end
end
The address
must be Hash
with the following structure:
{
host: 'localhost',
port: 8080,
}
You want to extract port from it. Default port is 8080
in case when:
address
is not aHash
address[:port]
is not presentaddress[:port]
is not aFixnum
#[macro_use]
extern crate rutie;
use rutie::{Class, Fixnum, Hash, NilClass, Object, Symbol, VM};
class!(Server);
methods!(
Server,
rtself,
fn start(address: Hash) -> NilClass {
let default_port = 8080;
let port = address
.map(|hash| hash.at(&Symbol::new("port")))
.and_then(|port| port.try_convert_to::<Fixnum>())
.map(|port| port.to_i64())
.unwrap_or(default_port);
// Start server...
NilClass::new()
}
);
fn main() {
Class::new("Server", None).define(|klass| {
klass.def("start", start);
});
}
Ruby:
class Server
def start(address)
default_port = 8080
port =
if address.is_a?(Hash) && address[:port].is_a?(Fixnum)
address[:port]
else
default_port
end
# Start server...
end
end