|
List Info
Thread: Proposed changes to list.hash and hash.list vmethods
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-01-27 12:54:32 |
I just got bitten (again) by a limitation in
Template::Stash. Stephen
Howard provided a patch to fix it and I added it, but left
it commented
out pending comments from anyone (and also pending the tuits
to dive
into the XS Stash to make the same fix).
http://template-toolkit.org/pipermail/t
emplates/2003-December/005417.html
The essence of the problem is this: if you have an object
(list or hash)
which doesn't implement the method that you call, then it
should fall
back on hash/list vmethods, or accessing the numerical item
you asked
for in a list.
[% hashobject.keys %] # should call hash vmethod, but
doesn't
[% listobject.first %] # ditto list vmethod
[% listobject.3 %] # should return
$listobject->[3]
Needless to say, the problem is that it doesn't, but with
Stephen's
patch, it does (in the Perl Template::Stash at least).
Well we don't seem to have had any comments since then, and
with fresh
bite marks to show for it, I'm going ahead and activating it
unless I
hear any blood-curdling screams to the contrary.
I'll also have a look at updating the XS Stash to do the
same thing
so you may be hearing a few blood-curdling screams from me
While I'm there, I'm also planning to "fix" the
hash.list and list.hash
methods to Do The Right Thing.
For some totally half-baked reason that now I can fathom
not, I made
the hash.list method return a stupidly complex list of hash
references:
{ pi => 3.14 } => [ { key ='pi', value='3.14' } ]
and the list.hash method return an equally useless hash:
[ 3.14, 2.718 ] => { 0 => 3.14, 1 => 2.718 }
Having just activated Stephen's patch, these vmethods kicked
in and
made a handful of tests failed because they were expecting
some kind
of sensible values returned and instead got this
crack-fuelled nonsense.
So I'm proposing that I fix them too and make them do what
they should
always have done - a straight conversion between list and
hash
hash.list => [ %$hash ]
list.hash => { $list }
I realise that it might break code that relies on the old
behaviour,
but I think it's for the best in the long run.
Any objections?
A
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-01-27 19:11:40 |
Andy Wardley wrote:
> I just got bitten (again) by a limitation in
Template::Stash. Stephen
> Howard provided a patch to fix it and I added it, but
left it commented
> out pending comments from anyone (and also pending the
tuits to dive
> into the XS Stash to make the same fix).
>
> http://template-toolkit.org/pipermail/t
emplates/2003-December/005417.html
>
> Well we don't seem to have had any comments since then,
and with fresh
> bite marks to show for it, I'm going ahead and
activating it unless I
> hear any blood-curdling screams to the contrary.
>
> I'll also have a look at updating the XS Stash to do
the same thing
> so you may be hearing a few blood-curdling screams from
me
------------------------------------------------------------
------
This seems ok to me. This one seems like one that will not
hit too many people. Probably should make a note to look out
for it in the release notes, though.
------------------------------------------------------------
------
> For some totally half-baked reason that now I can
fathom not, I made
> the hash.list method return a stupidly complex list of
hash references:
>
> { pi => 3.14 } => [ { key ='pi', value='3.14' }
]
>
> and the list.hash method return an equally useless
hash:
>
> [ 3.14, 2.718 ] => { 0 => 3.14, 1 => 2.718 }
>
> So I'm proposing that I fix them too and make them do
what they should
> always have done - a straight conversion between list
and hash
>
> hash.list => [ %$hash ]
> list.hash => { $list }
> Any objections?
------------------------------------------------------------
------
This seems to make sense to me. The hash method (on lists)
is probably rarely used as I don't think it's documented as
a list vmethod currently.
The hash.list one is a little worrying, though. I can see
someone doing the following:
[% hash = {a => 1, b => 2, c=> 3,} %]
[% FOREACH h IN hash.list %]
[% h.key %] [% h.value %]<br>
[% END %]
Granted that doesn't make much sense when you can do:
[% FOREACH h IN hash %]
[% h.key %] [% h.value %]<br>
[% END %]
Not only that, but if a user does:
hash.list.size();
They will not get the number of elements in the hash.
(Someone might do this if they have multiple objects coming
to that point, be it scalar, list, or hash.
For example:
obj_array = [ ['x', 'y', 'z'], {a => 3, b=> 3}, 'b'
];
[% FOREACH obj IN obj_array %]
[% IF (obj.list.size > 2) %]
# do something
[% END %]
[% END %]
Other than those two, I can't really think of any other
uses, and even those two seem like they'd be rare. I'd say
the list.hash one sounds fine, but I'm neutral on the
hash.list() one. On one hand it probably should return a
normal list, but on the other, it could break something.
Also that functionality is already provided (wrongly?) via
the 'each' parameter and the 'each' virtual method. I think
it could be argued (for TT3, or if we're changing
hash.list() then maybe now) that the 'each' parameter and
virtual method should return an array of arrays instead. It
doesn't really match the functionality of Perl. For example,
it's like doing:
my array = each %hash;
and expecting it to do this:
my array = %hash;
When you use each, you expect a key and a value to be
returned, not the entire list of the hash. So I think an
array of arrays would probably be good there. That way you
can iterate through the list and have access to each
key/value pair.
Just my $0.02 to muddy the waters. ;)
-- Josh
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-01-27 19:58:51 |
Andy,
> So I'm proposing that I fix them too and make them do
what they should
> always have done - a straight conversion between list
and hash
>
> hash.list => [ %$hash ]
> list.hash => { $list }
Actually, interestingly enough, I'm already overriding
HASH_OPS->{'list'} in one of my two projects. But I
don't use
what you're suggesting there; rather I use
hash.list => [ $hash ]
which seems to me to match better the way a scalar would
convert. Specifically, I use Config::General to read in a
file, then toss the resulting hash directly to TT2. So if I
have a section:
<Thing>
name=Fred
foo=bmoogle
</Thing>
then .Thing is a hash, whereas if I have multiple sections,
like so:
<Thing>
name=Fred
foo=bmoogle
</Thing>
<Thing>
name=Sue
foo=rorschach
</Thing>
then .Thing is an array of hashes. So this way I can use
.Thing.list() when I'm not sure which one I'll have. For
this, it seems like [$hash] is better than [%$hash] (and
exactly matches the way scalar.list works). Just a thought.
Not sure about the list.hash aspect; never used that one.
Here's my question about XS Stash changes: I saw in the
documentation that tie'd hashes don't really work with the
XS
Stash. (Took me a while to find it, and I can't find it
again now, but I did eventually come across it.) Is this
one
of those things that's too horrifically bitchy to even think
about fixing, or just something nobody ever got around to?
I wish I knew enough about XS and C reps of Perl vars to
submit a patch, but, alas, I don't. Just wondering if that
was something you could take a look at while you're poking
around, or if it's as I say too horrific to even even
contemplate.
-- Buddy
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-01-27 21:19:24 |
>
> then .Thing is an array of hashes. So this way I can
use .Thing.list() when I'm not sure which one I'll have.
For
> this, it seems like [$hash] is better than [%$hash]
(and exactly matches the way scalar.list works). Just a
thought.
That's because Config::General needs a ForceArray analogue
to the one
in XML::Simple.
Clayton
--
Clayton Scott
clayton.scott gmail.com
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-01-27 22:04:15 |
Clayton,
> That's because Config::General needs a ForceArray
analogue to the one
> in XML::Simple.
Enh. I always thought that ForceArray was a bit too
agressive anyways. But then I suppose I didn't like
XML::Simple
all that much in general, or I wouldn't have switched to
Config::General. So I
guess I'm not a good authority on that.
But I don't have any problem with the way Config::General
does things, especially since TT2 thoughtfully provides me
with the list() vmethod that makes it all work out. Except
that it didn't, for hashes. But it was trivial to override,
so I didn't mind it even then.
I was just offering another viewpoint on how it might be
changed, since it apparently _is_ going to change. But if
it
doesn't change the way I was suggesting, I'll just keep my
override in place and it's no skin off my nose.
-- Buddy
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-01-27 22:35:52 |
> Well we don't seem to have had any comments since then,
and
> with fresh
> bite marks to show for it, I'm going ahead and
activating it
unless I
> hear any blood-curdling screams to the contrary.
That's nice.
> I realise that it might break code that relies on the
old
behaviour,
> but I think it's for the best in the long run.
>
> Any objections?
I think the only right way is "never change the
behavior", which
was discussed here many times. For me, such a changes to
'list'
and 'hash' vmethods will be all right, and even wanted. But
Josh
writes the right thing - it may break some code, so this
solution
is unacceptable.
--
Sergey Martynoff
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-01-28 10:53:10 |
Buddy Burden wrote:
> rather I use
>
> hash.list => [ $hash ]
>
> which seems to me to match better the way a scalar
would convert.
Yes, I'm coming around to this way of thinking. It makes a
lot of sense.
And you can always do hash.each if you do want [ %$hash ].
> Here's my question about XS Stash changes: I saw in the
documentation that
> tie'd hashes don't really work with the XS Stash.
(Took me a while to find
> it, and I can't find it again now, but I did eventually
come across it.)
> Is this one of those things that's too horrifically
bitchy to even think
> about fixing, or just something nobody ever got around
to?
It's a bitchy job :-(
In Perl, tied hashes and arrays behave more-or-less just
like regular ones
because the magic is hidden. But at the XS layer you have
to code the magic
yourself. From what I recall of last time I looked into it,
it all gets
messy very quickly.
Having said that, adding Stephen's fallback checks to the XS
Stash
turned out to be relatively painless. I'd forgotten how
much I enjoy
writing C. It's just the Perl XS layer and all that
worrying about
reference counting that takes the fun out of it. I'm taking
another
look...
A
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-01-30 19:00:38 |
Andy,
> Yes, I'm coming around to this way of thinking. It
makes a lot of sense.
Cool; thanx.
> It's a bitchy job :-(
>
> In Perl, tied hashes and arrays behave more-or-less
just like regular ones
> because the magic is hidden. But at the XS layer you
have to code the magic
> yourself. From what I recall of last time I looked
into it, it all gets
> messy very quickly.
>
> Having said that, adding Stephen's fallback checks to
the XS Stash
> turned out to be relatively painless. I'd forgotten
how much I enjoy
> writing C. It's just the Perl XS layer and all that
worrying about
> reference counting that takes the fun out of it. I'm
taking another
> look...
Well, if it's too evil, it's too evil. I dunno how much
slower the non-XS stuff is, realistically. Maybe I'd never
even notice. (Is there a benchmark somewhere?)
You enjoy writing C? <s> Man, I don't know if I could
ever go back. I graduated from C to C++ many years ago, and
then
I graduated from C++ to Perl. I think at this point going
back to writing C would just be too painful, for me at
least.
-- Buddy
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
| Proposed changes to list.hash and
hash.list vmethods |

|
2006-02-01 18:19:27 |
Thanks to everyone for their comments. I've decided that it
would
indeed be wrong to change the hash.list method without
warning, no
matter how broken it is or how much better it could be.
So the existing behaviour has gone back in, but the method
has been
documented as likely to change in TT3 and warning people to
use the
alternative instead.
I've created a new hash.pairs method to go with hash.keys
and hash.values.
This returns what the current hash.list does (a list of
hashes containing
{ key => $k, value => $v }). So the docs tell people
to stop using
hash.list and use hash.pairs instead.
I've also created a new hash.items method which does what
hash.each
currently does in simply expanding the hash into a list: [
%$hash ].
People using hash.each should change this to hash.items at
some point
because in TT3, hash.each will change to return what each
does in Perl,
i.e. the same thing as hash.pairs.
For TT3 we'll continue to provide hash.pairs for those who
start using
it now, but by then hash.each will do the same thing and be
the recommended
method.
So hopefully that gives everyone a clear upgrade path and
plenty of
warning that things are going to change.
TT2 Old | TT2 New | TT3
-----------|-----------------|----------------
hash.list | hash.pairs | hash.each
| (or hash.list) | (or hash.pairs)
hash.each | hash.items | hash.items
| (or hash.each) |
As for the list.hash method, this has never been documented
so I'm not
worried about changing it. By default this now returns a
hash array
composed from the list items, e.g. { $list }. If you provide a
numerical argument, it implements the old (but undocumented)
behaviour
of creating a hash that looks like an array with numerical
keys, starting
at the number provided.
list = [ foo, bar, baz, wiz ]
list.hash # { foo => bar, baz => wiz }
list.hash(0) # { 0 => foo, 1 => bar, 2 => baz,
3 => wiz }
list.hash(1) # { 1 => foo, 2 => bar, 3 => baz,
4 => wiz }
So if anyone is currently using this then they just have to
change
list.hash to list.hash(0) to get the same effect.
Cheers
A
_______________________________________________
templates mailing list
templates template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/t
emplates
|
|
[1-9]
|
|