Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I lazily load a Perl variable?

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.

like image 952
Thilo Avatar asked Dec 10 '22 13:12

Thilo


2 Answers

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.)

like image 105
cjm Avatar answered Jan 07 '23 08:01

cjm


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.

like image 32
rafl Avatar answered Jan 07 '23 08:01

rafl