How to call a macro with ::Second as argument?

Hi all :slight_smile:

Just a quick question.
How would I call the following macro?

macro a(s::Second)
    ...do stuff
end

Thanks :slight_smile:

Can you explain what you’re trying to do? From the context here, I don’t think macro is the right tool for you.

Macros pick up the literal symbols in the source code, not their values at run time. A macro’s job is to transform the code it is passed into new code. It’s basically like a fancy way to automate writing repetitive code (this is an oversimplification, but it’s a helpful starting point when thinking about macros).

So you can’t pass an object of type Second to a macro because the object doesn’t exist yet.

You might be looking for @generated functions. Generated functions allow you to compose a new function body based on the types of the arguments passed to the function.

Most likely, the thing you are trying to do can be done with a normal old function :slight_smile:

1 Like

Thank you for your detailed answer. Why I use a macro is because I want to know the line of code and file in which the macro is called. The reason for that it error logging. It’s quite convenient to get the information in an automated manner

You can get the file and line info inside a regular function with @__FILE__ and @__LINE__. Also, regular old Logging statements collect the file and line numbers. Also, when you throw an error, it records the line number too. I’m not sure what your function is trying to do and why ::Second is particularly important, so I might be missing the mark here, but you could do something like:

using Logging

function a(s::Second)
    @info "Running `a`" input=s
    # do stuff with s
    if err # whatever your error check is
        error("Something went wrong, oh no!")
    end
end

I basically want to do this but check at compile time if pause_duration isa Period

using Dates
mutable struct _LogMessageHistoryInfo
    last_time::DateTime
    counter::Int
end

macro error(ex, pause_duration::Union{Symbol, Expr, Nothing} = nothing)
    
    file = string(__source__.file)
    line = string(__source__.line)
    pause_duration = esc(pause_duration)
    history_info = _LogMessageHistoryInfo(
        typemin(DateTime),
        0,
    )

    quote
        local is_logging = true
        local prefix = ""

        if !isnothing($pause_duration)

            local now_time = $(Dates).now(UTC)
            local history_info = $(history_info)

            if now_time - history_info.last_time >= $pause_duration
                is_logging = true
                prefix = """
                This is a summary message:
                Last time: $(history_info.last_time)
                Nummer of messages since last time: $(history_info.counter) \n
                """
                history_info.last_time = now_time
                history_info.counter = 0
            else
                is_logging = false
                history_info.counter += 1 
            end
        end

        if is_logging
            local  current_stacktrace = string.(StackTraces.stacktrace())
            local calling_function = "no function found"
            for line in current_stacktrace
                if !startswith(line, "macro expansion")
                    calling_function = line
                    break
                end
            end
            println(
                string(
                    prefix,
                    $(esc(ex)), "\n",
                    split(string(@__MODULE__), ".")[end], ".", 
                        calling_function, "\n",
                    $file, ":", $line
                ),
                string(@__MODULE__)
            )
        end
    end
end