go-lazy
This is a simple library to wrap objects whose method one wants to defer the
invocation and cache afterwards.
Consider this example
type MyConf struct {
// internal fields
}
func (c *MyConf) UnmarshalText(data []byte) error {
// how to read the value from text
}
func (c *MyConf) Value() (string, error) {
// complex and possibly compute-heavy/resource intensive logic
}
What if one wants to unmarshal the object when the program starts, but defer the
retrieval of the value at a later time in the program lifecycle? This small
library answers this question:
func ReadConfig() (*internalConf, error) {
c := &MyConf{}
err := myencondinglib.ReadFromFile(confPath, c)
if err != nil {
return nil, err
}
l, err := lazy.NewLazy(c, "Value")
if err != nil {
return nil, err
}
return &internalConf{
// ...
LazyField: l,
// ...
}, nil
}
// ...
func UseConfig(conf *internalConf) error {
// When first calling this function, this call will be resource-intensive.
// Afterwards, it will retrieve the result.
// The returned value is an interface, and has to be cast appropriately to be used
// directly (i.e. when not passed to a function that explicitly expects the right type).
conf, err := conf.LazyField.Eval()
// This error is the one coming possibly from invocation of *MyConf.Value.
if err != nil {
return err
}
// ...
}
The library may also deal with function arguments, either when creating the
Lazy
wrapping object
l, err := NewLazy(obj, "Method", "arg1", 2, []int{4, 5, 6})
or later on in the lifecycle
// This does not stores the new arguments being passed
res, err := l.EvalWithArgs("new", "args")
// This replaces the new arguments
res, err := l.WithArgs("new", "args").Eval()
If you are curious, take a look a the tests.
Requests
Feel free to hack it/fork it. Feel also free to contact the author at
blallo@autistici.org.