I think it comes down to passing interfaces for retrieving data (your approach) versus passing just data (my approach). I can see tradeoffs in both directions.
Passing interfaces gives better independence between the template and the code that called it, since the code doesn't need to know what the template will use, and it avoids writing any code to generate data structures to pass. Passing data gives potentially better performance if there is frequent access to certain pieces of data, since these will be simple data structures rather than method calls. It also allows for the possibility of grouping together some queries for better performance, which you can't do easily if you are passing interfaces. On the other hand, passing data might result in wasted effort if the templates change at some point and no longer use some of the data being fetched. I also sometimes rearrange the data I'm passing to give a more natural templating syntax than would be possible with the interfaces that my O/R mapping objects provide, but that's more unusual and esoteric. Anyway, assuming that you simply want to do what you're doing right now but prevent database writes, I think the most efficient solution would be to add an IMMUTABLE option to Class::DBI that makes the objects read-only. It seems like a feature that might be of general interest for Class::DBI users, and it will perform better than a delegation system. - Perrin
