What I'd like to do is overwrite some boolean values on a given object, such as:
func main() {
manager := dshardmanager.New("Bot " + token)
manager.bareSession.State.TrackRoles = false;
manager.bareSession.State.TrackPresences = false;
// more stuff happens down here
}
However bareSession
is an unexported field, so I need to do this differently from what I'm gathering. I've come across some approaches using reflection but I'd like to learn the best practices approach to doing this.
In my specific case, it looks like the library I'm using offers a method to accomplish this. I've been tinkering with how to overwrite/define such a method but can't seem to figure out how to go about this.
What's the ideal approach to defining this SessionFunc()
to customize the session the way I'm trying to?
I don't know the context of that library, so I'm not sure if what I'll write here makes sense for you :) But by looking at the API, SessionFunc
is a func(token string) (*discordgo.Session, error)
, i.e., a function which receives a string
and returns a Session
and an error
. So you can make something like this to override it:
func main() {
manager := dshardmanager.New("Bot " + token)
manager.SessionFunc = func(token string) (*discordgo.Session, error) {
// use "token"
// if invalid:
if token == "" {
// return an error
return nil, fmt.Errorf("invalid token")
}
// otherwise, return a valid session
return &discordgo.Session{}
}
// more stuff happens down here
}
The code is obviously very generic, but the main idea is that you need to define that function with that exact header, and implement it. I don't know how you can, for example, evaluate the token parameter or create a discordgo.Session
. Or how you can configure the TrackRoles
or TrackPresences
values by using SessionFunc
. That's very specific for that library only, but I guess it makes more sense to you than to me :)
You could also define a regular function elsewhere with that exact header:
func createNewSession(token string) (*discordgo.Session, error) {
// use "token"
// if invalid:
if token == "" {
// return an error
return nil, fmt.Errorf("invalid token")
}
// otherwise, return a valid session
return &discordgo.Session{}
}
And set it with:
func main() {
manager := dshardmanager.New("Bot " + token)
manager.SessionFunc = createNewSession
// more stuff happens down here
}
Both approaches work the same way.
Reflection is [almost] never the recommended way to do those things, if the library creators made those properties private, they shouldn't be changed/accessed from outside.
This will not allow you to change bareSession
. But if you need to derive a new *discordgo.Session
with custom parameters you can do something similar to as follows.
func MySessionFunc(m *dshardmanager.Manager) dshardmanager.SessionFunc {
return func(token string) (*discordgo.Session, error) {
//Call default Session allocator
s, err := m.StdSessionFunc(token)
if err != nil {
return nil, err
}
//Then, change its exported fields
s.State.TrackRoles = false
s.TrackPresences = false
return s, nil
}
}
func main() {
manager := dshardmanager.New("Bot " + token)
manager.SessionFunc = MySessionFunc(manager)
}