3
votes

I have a repetitive set of boilerplate code that looks like this:

type Object
    ptr::Ptr{Void}

    function Object()
        ptr = ccall( (:createObject, LIB_SMILE), Ptr{Void}, ())
        smart_p = new(ptr)
        finalizer(smart_p, obj -> ccall( (:freeObject, LIB_SMILE), Void, (Ptr{Void},), obj.ptr ))
        smart_p
    end
end

I would like to auto-generate a set of these type definitions:

for str = ("Obj1","Obj2","Obj3")
    op_fname = symbol(str)
    op_create = ???
    op_free   = ???

    @eval begin
        type $op_fname
            ptr::Ptr{Void}

            function ($fname)()
                ptr = ccall( ($op_create, LIB_SMILE), Ptr{Void}, ())
                smart_p = new(ptr)
                finalizer(smart_p, obj -> ccall( ($op_free, LIB_SMILE), Void, (Ptr{Void},), obj.ptr ))
                smart_p
            end
        end
    end
end

I have not figured out how to generate the correct "symbol symbols" for op_create and op_free. As in, I need op_create = :(:createObj) but I cannot replicate this. Is there a way to generate the needed symbol in this context?

Thank you.

1

1 Answers

4
votes

Update: the original answer works (see below), but as @mlubin points out, QuoteNode is an internal implementation function. The quot function in Base.Meta is better:

import Base.Meta.quot
str = "Obj1"
quot(symbol("create$str"))

returns :(:createObj1). But I don't think that Meta.quot is documented either.

Original answer: You're looking for QuoteNode:

str = "Obj1"
QuoteNode(symbol("create$str"))

returns :(:createObj1) But this seems like a clear application for a macro!