I have a variable that I need to pass to a subroutine. It is very possible that the subroutine will not need this variable, and providing the value for the variable is expensive. Is it possible to create a "lazy-loading" object that will only be evaluated if it is actually being used? I cannot change the subroutine itself, so it must still look like a normal Perl scalar to the caller.
You'll want to look at Data::Lazy and Scalar::Defer. Update: There's also Data::Thunk and Scalar::Lazy.
I haven't tried any of these myself, but I'm not sure they work properly for an object. For that, you might try a Moose class that keeps the real object in a lazy attribute which handles
all the methods that object provides. (This wouldn't work if the subroutine does an isa
check, though, unless it calls isa
as a method, in which case you can override it in your class.)
Data::Thunk
is the most transparent and robust way of doing this that i'm aware of.
However, I'm not a big fan of it, or any other similar modules or techniques that try to hide themself from the user. I prefer something more explicit, like having the code using the value that's hard to compute simply call a function to retrieve it. That way you don't need to precompute your value, your intent is more clearly visible, and you can also have various options to avoid re-computing the value, like lexical closures, perl's state variables, or modules like Memoize
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With