This is an approximation of the error you'd get.
Couldn't render template "undef error - Can't call method "name" onThis error is actually a copy from bug #15457 but I happen to know it's basically the same error you'd get with an eval.
unblessed reference at /usr/lib/perl5/site_perl/5.8.0/Template/Timer.pm line
66. "
So what's the problem? can you spot it? ( original timer code )
Ugh! That's ugly, let's take a cue from Perl Best Practices
Bug #13225 suggests a problem with eval and the following fix (which I translated into something more similar to the current code).
well that should fix our eval problem... since an eval will be a reference of type SCALAR. but what happens if it's a reference not of type ARRAY or SCALAR? then we'll still get that error.
According to the ref function documentation
If the referenced object has been blessed into a package, then that package name is returned instead. You can think of ref as a typeof operator.what this means is I could check what type of object it was that I was normally getting. In order to do this I put $what into the output I get. I found out that most of the time $what is a Template::Document. So now I optimized my code for that situation.
See the thing is that we really don't want $what->name method to be called unless it's a Template::Document which actually has that method. I'm not sure that I'm not missing any tests at this point, but I'm pretty confident that, at least, this kind of bug won't crash my module anymore.
$what->can('name')?
ReplyDeleteis that better in some way? I suppose maybe it allows for other object types than can do name... though I don't know what one of those would be...
ReplyDeleteIt could be module (class) derived from Template::Document.
ReplyDeleteWell, it should be '(ref($what) && $what->can('name'))', or '(blessed($what) && $what->can('name'))' with 'blessed' from Scalar::Util;.
tried converting to this code.
ReplyDeletemy $template
# conditional # set $template to
= (ref($what) && $what->can('name')) ? $what->name
: ref($what) eq 'ARRAY' ? join( ' + ', @{$what} )
: ref($what) eq 'SCALAR' ? '(evaluated block)'
: $what
;
it fails to pass the test suite and seems to end up as $what instead of $what->name