|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Data::Transmute;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $DATE = '2020-02-13'; # DATE  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $DIST = 'Data-Transmute'; # DIST  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '0.039'; # VERSION  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
66768
 | 
 use 5.010001;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
9
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
7
 | 
 use strict 'subs', 'vars';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
    | 
| 
10
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
    | 
| 
11
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
1608
 | 
 use Log::ger;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
714
 | 
 use Ref::Util qw(is_hashref is_arrayref is_plain_hashref is_plain_arrayref);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1665
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
    | 
| 
14
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
8
 | 
 use Scalar::Util qw(refaddr);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
16
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use Exporter qw(import);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2372
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our @EXPORT_OK = qw(transmute_data reverse_rules);  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rule_create_hash_key {  | 
| 
20
 | 
63
 | 
 
 | 
 
 | 
  
63
  
 | 
 
 | 
182
 | 
     my %args = @_;  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
22
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
     my $data = $args{data};  | 
| 
23
 | 
63
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
285
 | 
     return unless ($args{transmute_object} // 1) ? is_hashref($data) : is_plain_hashref($data);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
     my $name = $args{name};  | 
| 
26
 | 
46
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
97
 | 
     die "Rule create_hash_key: Please specify 'name'" unless defined $name;  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
28
 | 
45
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
101
 | 
     if (exists $data->{$name}) {  | 
| 
29
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         return if $args{ignore};  | 
| 
30
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
24
 | 
         die "Rule create_hash_key: Key '$name' already exists" unless $args{replace};  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     die "Rule create_hash_key: Please specify 'value' or 'value_code'"  | 
| 
33
 | 
43
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
97
 | 
         unless exists $args{value} || $args{value_code};  | 
| 
34
 | 
42
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
151
 | 
     $data->{$name} = $args{value_code} ? $args{value_code}->($data->{$name}) : $args{value};  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rulereverse_create_hash_key {  | 
| 
38
 | 
30
 | 
 
 | 
 
 | 
  
30
  
 | 
 
 | 
84
 | 
     my %args = @_;  | 
| 
39
 | 
30
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
84
 | 
     die "Cannot generate reverse rule create_hash_key with value_code" if $args{value_code};  | 
| 
40
 | 
29
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
67
 | 
     die "Cannot generate reverse rule create_hash_key with ignore=1"   if $args{ignore};  | 
| 
41
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
     die "Cannot generate reverse rule create_hash_key with replace=1"  if $args{replace};  | 
| 
42
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
     [delete_hash_key => {name=>$args{name}, transmute_object=>$args{transmute_object}}];  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rule_rename_hash_key {  | 
| 
46
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
 
 | 
86
 | 
     my %args = @_;  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
48
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     my $data = $args{data};  | 
| 
49
 | 
23
 | 
  
 50
  
 | 
  
 50
  
 | 
 
 | 
 
 | 
126
 | 
     return unless ($args{transmute_object} // 1) ? is_hashref($data) : is_plain_hashref($data);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
51
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     my $from = $args{from};  | 
| 
52
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
46
 | 
     die "Rule rename_hash_key: Please specify 'from'" unless defined $from;  | 
| 
53
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     my $to   = $args{to};  | 
| 
54
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     die "Rule rename_hash_key: Please specify 'to'" unless defined $to;  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # noop  | 
| 
57
 | 
19
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     return if $from eq $to;  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
59
 | 
19
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
42
 | 
     if (!exists($data->{$from})) {  | 
| 
60
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         die "Rule rename_hash_key: Can't rename '$from' -> '$to': Old key '$from' doesn't exist" unless $args{ignore_missing_from};  | 
| 
61
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         return;  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
63
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     if (exists $data->{$to}) {  | 
| 
64
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         return if $args{ignore_existing_target};  | 
| 
65
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         die "Rule rename_hash_key: Can't rename '$from' -> '$to': Target key '$from' already exists" unless $args{replace};  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
67
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
     $data->{$to} = delete $data->{$from};  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rulereverse_rename_hash_key {  | 
| 
71
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
 
 | 
31
 | 
     my %args = @_;  | 
| 
72
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     die "Cannot generate reverse rule rename_hash_key with ignore_missing_from=1"     if $args{ignore_missing_from};  | 
| 
73
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     die "Cannot generate reverse rule rename_hash_key with ignore_existing_target=1"  if $args{ignore_existing_target};  | 
| 
74
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     die "Cannot generate reverse rule rename_hash_key with replace=1"                 if $args{replace};  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     [rename_hash_key => {  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         from=>$args{to}, to=>$args{from},  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         transmute_object=>$args{transmute_object},  | 
| 
78
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
     }];  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rule_modify_hash_value {  | 
| 
82
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
 
 | 
739
 | 
     require Data::Cmp;  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
84
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
831
 | 
     my %args = @_;  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     my $data = $args{data};  | 
| 
87
 | 
13
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
81
 | 
     return unless ($args{transmute_object} // 1) ? is_hashref($data) : is_plain_hashref($data);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
89
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     my $name = $args{name};  | 
| 
90
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
     die "Rule modify_hash_value: Please specify 'name' (key)" unless defined $name;  | 
| 
91
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $from = $args{from};  | 
| 
92
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     my $from_exists = exists $args{from};  | 
| 
93
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $to   = $args{to};  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     die "Rule rename_hash_key: Please specify 'to' or 'to_code'"  | 
| 
95
 | 
8
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
21
 | 
         unless exists $args{to} || $args{to_code};  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $errprefix = "Rule modify_hash_value: Can't modify key '$name'".  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ($from_exists ? " from '".($from // '') : "").  | 
| 
99
 | 
8
 | 
  
100
  
 | 
  
 50
  
 | 
 
 | 
 
 | 
49
 | 
         ($args{to_code} ? "' using to_code" : "' to '".($to // '')."'");  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
101
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     unless (exists $data->{$name}) {  | 
| 
102
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         die "$errprefix: key does not exist";  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $cur = $data->{$name};  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
107
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     $to = $args{to_code}->($cur) if $args{to_code};  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     if ($from_exists) {  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # noop  | 
| 
111
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
         return unless Data::Cmp::cmp_data($from, $to);  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
113
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
129
 | 
         if (Data::Cmp::cmp_data($cur, $from)) {  | 
| 
114
 | 
1
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
30
 | 
             die "$errprefix: current value is not '".($cur // '')."'";  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117
 | 
     $data->{$name} = $to;  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rulereverse_modify_hash_value {  | 
| 
122
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
20
 | 
     my %args = @_;  | 
| 
123
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     die "Cannot generate reverse rule modify_hash_value without from" unless exists $args{from};  | 
| 
124
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     die "Cannot generate reverse rule modify_hash_value with to_code" if $args{to_code};  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     [modify_hash_value => {  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         name => $args{name}, from => $args{to}, to => $args{from},  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         transmute_object=>$args{transmute_object},  | 
| 
128
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     }];  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rule_delete_hash_key {  | 
| 
132
 | 
43
 | 
 
 | 
 
 | 
  
43
  
 | 
 
 | 
125
 | 
     my %args = @_;  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
134
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
     my $data = $args{data};  | 
| 
135
 | 
43
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
190
 | 
     return unless ($args{transmute_object} // 1) ? is_hashref($data) : is_plain_hashref($data);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
137
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     my $name = $args{name};  | 
| 
138
 | 
39
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
87
 | 
     die "Rule delete_hash_key: Please specify 'name'" unless defined $name;  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
140
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
123
 | 
     delete $data->{$name};  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rulereverse_delete_hash_key {  | 
| 
144
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
38
 | 
     die "Can't create reverse rule for delete_hash_key";  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rule_transmute_array_elems {  | 
| 
148
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
53
 | 
     my %args = @_;  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
150
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     my $data = $args{data};  | 
| 
151
 | 
19
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
113
 | 
     return unless ($args{transmute_object} //1) ? is_arrayref($data) : is_plain_arrayref($data);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     die "Rule transmute_array_elems: Please specify 'rules' or 'rules_module'"  | 
| 
154
 | 
15
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
57
 | 
         unless defined($args{rules}) || defined($args{rules_module});  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
156
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
     my $idx = -1;  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ELEM:  | 
| 
158
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     for my $el (@$data) {  | 
| 
159
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
         $idx++;  | 
| 
160
 | 
38
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
79
 | 
         if (defined $args{index_is}) {  | 
| 
161
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
             next ELEM unless $idx == $args{index_is};  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
163
 | 
34
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
58
 | 
         if (defined $args{index_in}) {  | 
| 
164
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
             next ELEM unless grep { $idx == $_ } @{ $args{index_in} };  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
    | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
166
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
62
 | 
         if (defined $args{index_match}) {  | 
| 
167
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
37
 | 
             next ELEM unless $idx =~ $args{index_match};  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
169
 | 
30
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
61
 | 
         if (defined $args{index_filter}) {  | 
| 
170
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
             next ELEM unless $args{index_filter}->(index=>$idx, array=>$data, rules=>$args{rules});  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $el = transmute_data(  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             data => $el,  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             (rules        => $args{rules})        x !!(exists $args{rules}),  | 
| 
175
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
             (rules_module => $args{rules_module}) x !!(exists $args{rules_module}),  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
178
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     $data;  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rulereverse_transmute_array_elems {  | 
| 
182
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
 
 | 
31
 | 
     my %args = @_;  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     [transmute_array_elems => {  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         rules => reverse_rules(  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             (rules        => $args{rules})        x !!(exists $args{rules}),  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             (rules_module => $args{rules_module}) x !!(exists $args{rules_module}),  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ),  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (index_is     => $args{index_is})     x !!(exists $args{index_is}),  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (index_in     => $args{index_in})     x !!(exists $args{index_in}),  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (index_match  => $args{index_match})  x !!(exists $args{index_match}),  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (index_filter => $args{index_filter}) x !!(exists $args{index_filter}),  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         transmute_object=>$args{transmute_object},  | 
| 
194
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     }];  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rule_transmute_hash_values {  | 
| 
198
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
55
 | 
     my %args = @_;  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
200
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     my $data = $args{data};  | 
| 
201
 | 
19
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
113
 | 
     return unless ($args{transmute_object} //1) ? is_hashref($data) : is_plain_hashref($data);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     die "Rule transmute_hash_values: Please specify 'rules' or 'rules_module'"  | 
| 
204
 | 
15
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
55
 | 
         unless defined($args{rules}) || defined($args{rules_module});  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   KEY:  | 
| 
207
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
     for my $key (keys %$data) {  | 
| 
208
 | 
38
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
99
 | 
         if (defined $args{key_is}) {  | 
| 
209
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
             next KEY unless $key eq $args{key_is};  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
211
 | 
34
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
68
 | 
         if (defined $args{key_in}) {  | 
| 
212
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
             next KEY unless grep { $key eq $_ } @{ $args{key_in} };  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
214
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
55
 | 
         if (defined $args{key_match}) {  | 
| 
215
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
35
 | 
             next KEY unless $key =~ $args{key_match};  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
217
 | 
30
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
59
 | 
         if (defined $args{key_filter}) {  | 
| 
218
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
             next KEY unless $args{key_filter}->(key=>$key, hash=>$data, rules=>$args{rules});  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $data->{$key} = transmute_data(  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             data => $data->{$key},  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             (rules        => $args{rules})        x !!(exists $args{rules}),  | 
| 
223
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
125
 | 
             (rules_module => $args{rules_module}) x !!(exists $args{rules_module}),  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
226
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     $data;  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rulereverse_transmute_hash_values {  | 
| 
230
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
 
 | 
42
 | 
     my %args = @_;  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     [transmute_hash_values => {  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         rules => reverse_rules(  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             (rules        => $args{rules})        x !!(exists $args{rules}),  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             (rules_module => $args{rules_module}) x !!(exists $args{rules_module}),  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ),  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (key_is     => $args{key_is})     x !!(exists $args{key_is}),  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (key_in     => $args{key_in})     x !!(exists $args{key_in}),  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (key_match  => $args{key_match})  x !!(exists $args{key_match}),  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (key_filter => $args{key_filter}) x !!(exists $args{key_filter}),  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         transmute_object=>$args{transmute_object},  | 
| 
242
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     }];  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _walk {  | 
| 
246
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
37
 | 
     my ($data, $rule_args, $seen) = @_;  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # transmute the node itself  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     transmute_data(  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         data => $data,  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (rules        => $rule_args->{rules})        x !!(exists $rule_args->{rules}),  | 
| 
252
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
         (rules_module => $rule_args->{rules_module}) x !!(exists $rule_args->{rules_module}),  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
254
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
     my $refaddr = refaddr($data);  | 
| 
255
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     return unless $refaddr;  | 
| 
256
 | 
11
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
39
 | 
     return if $seen->{$refaddr}++;  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
258
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
37
 | 
     if ($rule_args->{recurse_object} ?  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             is_arrayref($data) : is_plain_arrayref($data)) {  | 
| 
260
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
         for my $elem (@$data) {  | 
| 
261
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
             _walk($elem, $rule_args, $seen);  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($rule_args->{recurse_object} ?  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             is_hashref($data) : is_plain_hashref($data)) {  | 
| 
265
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         for my $key (sort keys %$data) {  | 
| 
266
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
             _walk($data->{$key}, $rule_args, $seen);  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rule_transmute_nodes {  | 
| 
272
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
10
 | 
     my %args = @_;  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
274
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     my $data = $args{data};  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     die "Rule transmute_nodes: Please specify 'rules' or 'rules_module'"  | 
| 
277
 | 
3
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
10
 | 
         unless defined($args{rules}) || defined($args{rules_module});  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
279
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $seen = {};  | 
| 
280
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     _walk($data, \%args, $seen);  | 
| 
281
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     $data;  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rulereverse_transmute_nodes {  | 
| 
285
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
24
 | 
     die "Rule transmute_nodes is not reversible";  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _rules_or_rules_module {  | 
| 
289
 | 
237
 | 
 
 | 
 
 | 
  
237
  
 | 
 
 | 
350
 | 
     my $args = shift;  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
291
 | 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
345
 | 
     my $rules = $args->{rules};  | 
| 
292
 | 
237
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
547
 | 
     if (!$rules) {  | 
| 
293
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
         if (defined $args->{rules_module}) {  | 
| 
294
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
             my $mod = "Data::Transmute::Rules::$args->{rules_module}";  | 
| 
295
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
             (my $mod_pm = "$mod.pm") =~ s!::!/!g;  | 
| 
296
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
540
 | 
             require $mod_pm;  | 
| 
297
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
             $rules = \@{"$mod\::RULES"};  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
    | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
300
 | 
237
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
492
 | 
     $rules or die "Please specify rules (or rules_module)";  | 
| 
301
 | 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
424
 | 
     $rules;  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub transmute_data {  | 
| 
305
 | 
172
 | 
 
 | 
 
 | 
  
172
  
 | 
  
1
  
 | 
270783
 | 
     my %args = @_;  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
307
 | 
172
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
469
 | 
     exists $args{data} or die "Please specify data";  | 
| 
308
 | 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
287
 | 
     my $data  = $args{data};  | 
| 
309
 | 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
337
 | 
     my $rules = _rules_or_rules_module(\%args);  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
311
 | 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
278
 | 
     my $rulenum = 0;  | 
| 
312
 | 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
309
 | 
     for my $rule (@$rules) {  | 
| 
313
 | 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
248
 | 
         $rulenum++;  | 
| 
314
 | 
184
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
423
 | 
         if ($ENV{LOG_DATA_TRANSMUTE_STEP}) {  | 
| 
315
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             log_trace "transmute_data #%d/%d: %s",  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $rulenum, scalar(@$rules), $rule;  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
318
 | 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
413
 | 
         my $funcname = "_rule_$rule->[0]";  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         die "rule #$rulenum: Unknown function '$rule->[0]'"  | 
| 
320
 | 
184
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
252
 | 
             unless defined &{$funcname};  | 
| 
 
 | 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
547
 | 
    | 
| 
321
 | 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
267
 | 
         my $func = \&{$funcname};  | 
| 
 
 | 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
333
 | 
    | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $func->(  | 
| 
323
 | 
183
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
277
 | 
             %{$rule->[1] // {}},  | 
| 
 
 | 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
684
 | 
    | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             data => $data,  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
327
 | 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
424
 | 
     $data;  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub reverse_rules {  | 
| 
331
 | 
66
 | 
 
 | 
 
 | 
  
66
  
 | 
  
1
  
 | 
99996
 | 
     my %args = @_;  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
333
 | 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
     my $rules = _rules_or_rules_module(\%args);  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
335
 | 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
100
 | 
     my @rev_rules;  | 
| 
336
 | 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
131
 | 
     for my $rule (@$rules) {  | 
| 
337
 | 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
180
 | 
         my $funcname = "_rulereverse_$rule->[0]";  | 
| 
338
 | 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
         my $func = \&{$funcname};  | 
| 
 
 | 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
195
 | 
    | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unshift @rev_rules, $func->(  | 
| 
340
 | 
73
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
128
 | 
             %{$rule->[1] // {}},  | 
| 
 
 | 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
262
 | 
    | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
343
 | 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
237
 | 
     \@rev_rules;  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: Transmute (transform) data structure using rules data  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |