-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accessing public class variables #90
Comments
Not yet, but this is begging to be exploited here I think: JuliaLang/julia#24960 Unfortunately I won't have time soon to get to this. |
Given the v1.0 release, is the above possible? Thanks! Snir |
No, although CxxWrap should be fully compatible with 1.0 now, this is a new feature and I haven't implemented it yet. I did think a bit on how it might be implemented, though:
That way, fields can be added without actually duplicating them on the Julia side, and it doesn't matter if getter or setter methods exist, since if they don't exist a lambda can be used to define them. |
Are there any plans to implement this now? |
Another +1 here. I'm finding I have to write a lot of boilerplate code for get/set methods. |
Here's a solution for the Julia half: macro wrapaccessors(T, fields)
@assert fields.head === :tuple
gen_case(i) = :(name === $(QuoteNode(fields.args[i])))
gen_get(i) = quote
$(__module__).$(Symbol(T, :_get_, fields.args[i]))(x)
end
gen_set(i) = quote
$(__module__).$(Symbol(T, :_set_, fields.args[i]))(x, value)
end
# err_ex = :(error($(Expr(:string, "type $T has no field ", :name))))
get_ex = Expr(:block, :($Base.getfield(x, name)))
set_ex = Expr(:block, :($Base.setfield(x, name, value)))
for i=2:length(fields.args)
get_ex = Expr(:elseif, gen_case(i), gen_get(i), get_ex)
set_ex = Expr(:elseif, gen_case(i), gen_set(i), set_ex)
end
get_ex = Expr(:if, gen_case(1), gen_get(1), get_ex)
set_ex = Expr(:if, gen_case(1), gen_set(1), set_ex)
ex = quote
function $Base.getproperty(x::$(__module__).$(T), name::$Symbol)
$get_ex
end
function $Base.setproperty!(x::$(__module__).$(T), name::$Symbol, value)
$set_ex
end
end
esc(ex)
end
# Example:
module M
using ..Main: @wrapaccessors
using MacroTools
one = 0
two = 0
struct Example end
Example_get_val(x::Example) = one
Example_set_val(x::Example, v) = global one = v
println(prettify(@macroexpand @wrapaccessors Example (one, )))
@wrapaccessors Example (one, )
end
x = Example()
@assert x.one == M.one == 0
x.one == 10
@assert x.one == M.one == 10 I'm not familiar enough with C++ & CxxWrap's internals to come up with an elegant solution for the C++ side. But maybe someone else is? :) |
Is it possible to access public class variables without manually writing get and set methods?
For reference -- ".def_readwrite" in pybind11 allows using the "dot" syntax "A.a".
The text was updated successfully, but these errors were encountered: