rhaiscript / rhai

Rhai - An embedded scripting language for Rust.
https://crates.io/crates/rhai
Apache License 2.0
3.81k stars 179 forks source link

overload print #734

Closed soerenmeier closed 1 year ago

soerenmeier commented 1 year ago

I wanted to add a print function which takes an array and prints each element on a new line. When executing print with an array i now get the error Error: ErrorMismatchOutputType("string", "()", 1:1). See this commit where i added the following code to reproduce the issue:

#[test]
fn test_print_overload() -> Result<(), Box<EvalAltResult>> {
    let mut engine = Engine::new();

    engine.register_fn("print", |arr: Array| -> Result<(), Box<EvalAltResult>> {
        for el in arr {
            let s = el.into_immutable_string()?;
            println!("{}", s.as_str());
        }

        Ok(())
    });

    // Evaluate script
    engine.run("print(40 + 2)")?;
    engine.run("print([\"abc\", \"def\"])")?;

    Ok(())
}
emesare commented 1 year ago

Hello, the reason it is giving you that error is the print function[^1], sort of confusingly, does not actually do any printing, instead it returns a string representing the given value. What you want to do instead is register the appropriate functions outlined here. For example if you wanted to override just print level calls for arrays you could do something like so:

engine.register_fn("print", |arr: &mut Array| -> String {
    arr.iter()
        .map(|i| i.to_string())
        .fold(String::new(), |a, b| a + b.as_str() + "\n")
        .trim_end()
        .to_string()
});

Usage:

print([\"abc\", \"def\"])
abc
def

[^1]: well it does, but not the overridable one, see on_print for overriding actual printing

schungx commented 1 year ago

The print or to_string functions take data and return a text representation as a string.

That's why you get an error... Rhai expects you give it a string. Actually am empty string would do just fine.

Rhai takes this string and displays it, usually. This behaviour is controlled by the on_print callback on the Engine, which you can also override.

http://rhai.rs/book/language/print-debug.html

soerenmeier commented 1 year ago

Thanks for quick response, that makes sense. I will update my function accordingly.