Customize println

When with std enabled, we always have a println macro, but sometimes, for example, with FFI, the original println may not always functions, and it is some other customized function should be called.

Is it possible to provide a override that mask the original print* macros and use the crate provided ones?

If it is not possible to hide the print*! macros, what is the best practice to suggest people use the crate provided print macro, rather than the std one?


For a detailed view, the statictical program, R, has an Rprintf function which should be used to deal with output, rust's println! works with R console (in both linux and windows), but failed to work with Rgui.exe (windows gui), thus it might be better to hide the println! macro and use the new one.

With #![no_std] enabled, I can write the customized println! macros, but in case the std is used, using println! generates an error:

    = note: `println` could refer to a macro from prelude
note: `println` could also refer to the macro imported here

What is the best practice to override the println! macro? Is it possible put an warning about misuse about std::println! macro with 3rd party crates?

I don't get what you are describing here. How would FFI even relate to whether or not println!() works?

It sounds to me like you should be redirecting stdout of the compiled executable instead of performing dirty tricks and "overriding" macros.

1 Like

I cannot tell the details, but I have found that,

with

std::println!("output")

R console will print "output" directly, but Rgui.exe will not show any output. If we want to show something in both R console and Rgui.exe,

unsafe {Rprintf(c"%s".as_ptr(), format_args("{}\0",format_args!($(tt)*)).as_ptr())}

should be called.

I've wrote a macro rmin::println to do such conversion, but it conflict with std::println.

This is why I found the solution that hide std::println.


Since there is no interface provided by Rgui.exe, there might be no way to perform a successful redirect.

What error did you get? How did you get it?

this is a common error. Since I wrote a rmin::println macro, with

use rmin::*;
println!(something)

the ambiguous error occurs.

compiler suggests use either std::println! or crate::println!, but I just wonder whether the std::println could be hided and using rmin::println generates no error.

This is the error:

error[E0659]: `println` is ambiguous
 --> src/main.rs:4:5
  |
4 |     println!();
  |     ^^^^^^^ ambiguous name
  |
  = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
  = note: `println` could refer to a macro from prelude
note: `println` could also refer to the macro imported here
 --> src/main.rs:1:5
  |
1 | use rmin::*;
  |     ^^^^^^^
  = help: consider adding an explicit import of `println` to disambiguate
  = help: or use `crate::println` to refer to this macro unambiguously

It's not a common error. It only happens with macros. For everything else, glob imports override standard library prelude imports.

You'll either need to import it explicitly or use a different name.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.