Open sbinet opened 6 years ago
A simple example I encountered just now, as I tried to set an unexported variable in Sebastien's go-hep, based on ng:
type A struct { newstuff int; newstring string;}
bb := &A{newstuff:55, newstring:"yolo"}
ng: eval: ng eval panic: reflect.StructOf: field "newstuff" is unexported but missing PkgPath
The example in @sbinet original comment really should (and I think can be made to) work. But @glycerine points out a trickier fundamental limit of the reflect-based approach.
I think for now I'm going to modify the type checker to reject unexported struct fields in type definitions, so at least the errors are clear.
I think you can set unexported fields. https://stackoverflow.com/questions/42664837/access-unexported-fields-in-golang-reflect
I suppose we already use plenty of unsafe
, so we could set unexpected fields. Hmm.
Encouragement: It would seem odd not to be able to set one's own fields, from within one's own package.
I verified that the stackoverflow technique works. When I replaced
ptrFld := fld.Addr()
with something approximately like
ptrFld := reflect.NewAt(fld.Type(), unsafe.Pointer(fld.UnsafeAddr()))
and then writing to unexported fields went through.
This works. Thanks @glycerine. Unfortunately your particular example needs an improvement to reflect.StructOf
, which has to wait out the six month Go release cycle: https://golang.org/cl/85661
More generally, we need to come up with rules for setting unexported fields. It is entirely reasonable when sitting in the ng> interpreter to change any field you want. (In fact, there are lots of other "superuser"-style powers I would like to add to the active interpreter.) But in general, an ng program should follow the exported/unexported rules of Go. So loaded packages shouldn't be able to do this. What about writing to unexported fields from inside blocks?
What about writing to unexported fields from inside blocks?
Cool. I'm not familiar withblocks
in this context. Could you give a small example?
consider the following Go
pkg1
:this will work:
where
simple-ok.ng
is:but this will fail with
simple-err.ng
:this boils down to: how to handle (and represent) values of unexported types?