[Templates] listifying "scalars"
Jess Robinson
castaway@desert-island.demon.co.uk
Mon, 20 Nov 2006 22:11:42 +0000 (GMT)
On Mon, 20 Nov 2006, Jess Robinson wrote:
>
>
> On Mon, 25 Sep 2006, Jess Robinson wrote:
>
>>
>> Hi folks,
>>
>> The 2.15 has an enhancement whereby using .list on a "scalar" should turn
>> it into a list. I quote the word "scalar", because it appears to really
>> mean "simple scalar", i.e. not references, or blessed refs. The docs
>> should probably reflect this.
>>
>> Anyway, that leaves me with a problem. My sub returns a list of blessed
>> objects, except that when there's only one, TT conveniently de-listifies
>> the result, however since I'd like to access it as a list anyway, I used
>> .list on it, which conveniently turns it into a list of hashrefs with
>> values and keys.. i.e. treats it as a hashref. Code that worked in 2.14,
>> in the SQL::Translator test suite i.e.:
>>
>> [% table.pkey_fields.join(", ") %]
>>
>> Now fails to work in 2.15, when the result of pkey_fields is a single
>> object.. Adding .list does not fix this.
>>
>> Any ideas how to fix this backwards compat problem, or how to make the
>> test suite work with lists of blessed scalars?
>>
>> Jess
>
> Since nobody appears to want to play this game, I've delved in the fun Stash
> code myself.. after much debugging it appears that:
>
> Calling a sub that returns a list of items is a list iff there is more than
> one item in it, in TT. (This behaviour is used internally and thus I guess
> can't be changed).
>
> Calling "list" or "first" or any other list method on a single blessed
> hashref causes, in the first instance, the hash_list method to be called
> (that only appeared in v2.15, and is already marked as planned to disappear
> again by v3.. what is it for?), and in the second instance, .first fails to
> be called at all, as the old ploy of dropping through to try scalar and list
> ops when no matching method was found has been effectively turned off.. Was
> this on purpose?
>
> The relevant change is this code in Stash.pm:
>
> ## under elsif (ref($root) && UNIVERSAL::can($root, 'can')) {
>
> 2.14:
>
> if (UNIVERSAL::isa($root, 'HASH')
> && defined($value = $root->{ $item })) {
> return $value unless ref $value eq 'CODE'; ## RETURN
> @result = &$value(@$args);
> }
>
> Which drops through if it's hash-based and theres no such value
>
> 2.15:
>
> if (UNIVERSAL::isa($root, 'HASH') ) {
> if( defined($value = $root->{ $item })) {
> return $value unless ref $value eq 'CODE'; ## RETURN
> @result = &$value(@$args);
> }
> elsif ($value = $HASH_OPS->{ $item }) {
> @result = &$value($root, @$args);
> }
> }
> Which doesn't..
>
>
> So, a) shall I make a test patch that fails, b) patch Stash.pm to fall
> through, or c) go patch the code that seems to rely on an undocumented 2.14
> feature?
Oops, c) was supposed to mean: "Go patch MY code that relies on
an undocumented feature" .. (or SQL::Translators, anyway)
Jess