Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a non-public function from within a macro?

Tags:

I have a macro that is getting too big so I wanted to extract part of the code into a function. When I do that, I have a problem because the function is not in scope when the macro is expanded at the call-site:

#[macro_use]
mod macros {
    fn hi() {
        println!("Hello")
    }

    #[macro_export]
    macro_rules! say_hi {
        () => {
            hi();
        };
    }
}

fn main() {
    say_hi!();
}

This does not compile:

error[E0425]: cannot find function `hi` in this scope
  --> src/main.rs:10:13
   |
10 |             hi();
   |             ^^ not found in this scope
...
16 |     say_hi!();
   |     ---------- in this macro invocation
   |
help: possible candidate is found in another module, you can import it into scope
   |
15 | fn main() use macros::hi;
   |

I tried making hi public (though I didn't want to) but since it is not imported in the context of the caller, it doesn't work anyway.

How can I solve this problem?

like image 594
Renato Avatar asked Oct 09 '17 20:10

Renato


People also ask

How do you call a private function in VBA?

Using Option Private Module (at module scope) and Public Sub ... makes the Sub visible in other modules, but invisible in Excel Macro list - Alt-F8.

Can you use a function in a macro?

You can't use a built-in worksheet function in a macro by calling the function as a method of the Application object or the WorksheetFunction object if there is an equivalent function in Visual Basic.

How do you call a function from another module in VBA?

VBA Example: Run Another Macro from a Macro Just type the word Call then space, then type the name of the macro to be called (run).

How do I make a macro private?

3. Add the word “Private” at the beginning of the “Sub” line with a space between the word and the name of the macro. Save the macro and it will no longer appear on the list of macros within the workbook.


1 Answers

The first problem is that in the context of the caller of the macro, the function cannot be visible unless the function is public, thus I'm afraid it's not possible to call non-pub functions from macros.

Another problem is that functions referred to by macros should always use their fully qualified paths (so that they work from any context). Assuming the function hi is made pub, this will work:

#[macro_export]
macro_rules! say_hi {
    () => {
        $crate::macros::hi();
    };
}

Note: use $crate to make sure the macro works when used from any crate, see the $crate documentation for details.

like image 155
Renato Avatar answered Oct 04 '22 15:10

Renato