use Scalar::Util ();
use List::Util ();
-our $VERSION = "1.010";
+our $VERSION = "1.011";
my $list_make_key = sub {
my ($item, $field) = @_;
];
}
+sub _do_maphash {
+ my ($self, $args) = @_;
+
+ @$args <= 2
+ or die [ error => "list.maphash requires 0 to 2 parameters" ];
+
+ if (@$args) {
+ my $id = $args->[0];
+ my $value = @$args > 1 ? $args->[1] : undef;
+
+ my $eval = $self->expreval;
+ if (ref $id) {
+ if (defined $value) {
+ if (ref $value) {
+ return +{
+ map {
+ scalar($eval->call_function($id, [ $_ ])) =>
+ scalar($eval->call_function($value, [ $_ ]))
+ } @{$self->[0]}
+ };
+ }
+ else {
+ return +{
+ map {
+ scalar($eval->call_function($id), [ $_ ]) =>
+ scalar($list_make_key->($_, $value))
+ } @{$self->[0]}
+ };
+ }
+ }
+ else {
+ return +{
+ map {
+ scalar($eval->call_function($id), [ $_ ]) => $_
+ } @{$self->[0]}
+ };
+ }
+ }
+ else {
+ if (defined $value) {
+ if (ref $value) {
+ return +{
+ map {
+ scalar($list_make_key->($_, $id)) =>
+ scalar($eval->call_function($value, [ $_ ]))
+ } @{$self->[0]}
+ };
+ }
+ else {
+ return +{
+ map {
+ scalar($list_make_key->($_, $id)) =>
+ scalar($list_make_key->($_, $value))
+ } @{$self->[0]}
+ };
+ }
+ }
+ else {
+ return +{
+ map {
+ scalar($list_make_key->($_, $id)) => $_
+ } @{$self->[0]}
+ };
+ }
+ }
+ }
+ else {
+ return +{ map {$_ => 1} @{$self->[0]} };
+ }
+}
+
sub _do_slice {
my ($self, $args) = @_;
[ "a", 1, "b", 2 ].as_hash => { a:1, b:2 }
+=item maphash
+
+Returns a new hash with each item from the array as a key, and all values of 1.
+
+This simiplifies turning a list of strings into an existence checking hash.
+
+ <:.set strs = [ "one", "two", "three" ] :>
+ <:.set strhash = strs.maphash :>
+ <:= strhash.exists["one"] :> # 1
+ <:= strhash.exists["four"] :> # (empty string)
+
+=item maphash(key)
+
+=item maphash(key, value)
+
+Returns a new hash with the key and values derived from the elements
+of the list.
+
+Each I<key> and I<value> can be either an element name, treating the
+array elements as hashes/objects, or a block.
+
+If I<value> isn't supplied then the element from the array is used.
+
+ <:.set objs = [ { id: 1, firstn: "Tony", lastn: "Cook", note: "Programming Geek" },
+ { id: 2, firstn: "Adrian", lastn: "Oldham", note: "Design Geek" } ] :>
+ <:.set byid = objs.maphash("id") :>
+ <:= byid[2]firstn :> # Adrian
+ <:.set byname = objs.maphash(@{i: i.firstn _ " " _ i.lastn }) :>
+ <:= byname["Tony Cook"].note :> # Programming Geek
+ <:=.set namebynote = objs.maphash(@{i: i.note.lower }, @{i: i.firstn _ " " _ i.lastn }) :>
+ <:= namebynote["design geek"] :> # Adrian Oldham
+
=item is_list
Test if this object is a list. Always true for a list.
#!perl -w
# Basic tests for Squirrel::Template
use strict;
-use Test::More tests => 209;
+use Test::More;
use HTML::Entities;
sub template_test($$$$;$$);
use Data::Dumper;
Dumper($_[0]);
},
+ objs =>
+ [
+ { id => 1, val1 => "abc", val2 => "def" },
+ { id => 2, val1 => "ghi", val2 => "jkl" }
+ ],
);
template_test("<:str:>", "ABC", "simple", \%acts);
template_test("<:strref:>", "ABC", "scalar ref", \%acts);
[ '[ "A" .. "Z" ].slice([ 0 .. 5 ]).join("")', 'ABCDEF' ],
[ '[ "A" .. "Z" ].slice(0, 1, -2, -1).join("")', 'ABYZ' ],
[ '[ "A" .. "Z" ].splice(0, 5).join("")', 'ABCDE' ],
+ [ 'objs.maphash("id")[2].val2', 'jkl' ],
+ [ 'objs.maphash("id", "val1")[1]', 'abc' ],
+ [ 'objs.maphash("val1", "val2")["abc"]', 'def' ],
+ [ 'objs.maphash("val1", @{i: i.id _ i.val2 })["abc"]', '1def' ],
+ [ 'objs.maphash(@{i: i.val1 _ i.val2 }, @{i: i.id _ i.val2 })["abcdef"]', '1def' ],
+ [ 'somelist.maphash().exists("a")', '1' ],
+ [ 'somelist.maphash().exists("k")', '' ],
# WrapHash
[ '{ "foo": 1 }.is_list', 0 ],
}
}
+done_testing();
+
sub template_test ($$$$;$$) {
my ($in, $out, $desc, $acts, $stripnl, $vars) = @_;