How to separate between hash and array in data returned from function (was: Re: [Templates] Fun with arrays)

Robin Smidsrød robin@smidsrod.no
Sun, 11 Feb 2007 00:56:17 +0100


Randal L. Schwartz wrote:
> If I recall, you can return an arrayref, which will always be interpreteed
> correctly as an "array" in TT-side.  So, returning [] will correctly
> be seen as "size of 0" and [42] will be seen as "size of 1", etc.
>   

I have a similar problem. My function has this return statement:

my %hash=( one => 1, two => 2 );
return wantarray ? %hash : \%hash;

But when I try to access a member in the hash it fails.

[% function.one %] this returns nothing (I was expecting 1)
[% function.size %] this returns 4 (I was expecting 2)

Is there something I'm forgetting? Do I need to use some kind of keys() 
construct to make it treat the returned value as a hash? Or is there 
some way to force "wantarray" to fail when this method is called from 
TT? Because if I don't use this wantarray return call and only return 
the hashref it works as intended. I know about the .list. method for 
arrays, but didn't find anything similar for hashes.

One a sidenote, is there some way for an object method to know if it is 
being called from a template (instead of from normal perl code)? Is 
there some variable that is set that the function has access to which is 
not set otherwise? Or can I use some kind of function (caller) to 
inspect the call stack to figure it out? My object contains both read 
and write methods, and I want to make sure the write method calls are 
not callable from within a template, only from native perl code. Any 
pointers would be most helpful.

-- Robin