#!/usr/bin/perl use Modern::Perl; use Slang qw ( mask ); use Bench; Bench::Start(); local $_; $_->{'mask'} = join ('', ); $_->{'stash'} = { lang => "en", title => { en => "Bob's Bit's Emporium" }, content => { en => "greetings.lang" }, greetings => { en => "Welcome!" } }; say mask($_->{'mask'},$_->{'stash'}); Bench::MileStone(); say mask($_->{'mask'},$_->{'stash'}); say mask($_->{'mask'},$_->{'stash'}); say mask($_->{'mask'},$_->{'stash'}); say mask($_->{'mask'},$_->{'stash'}); say mask($_->{'mask'},$_->{'stash'}); Bench::End(); Bench::Report(); __DATA__ <s>title.<s>lang</></> content.lang #### package Slang; use Modern::Perl; use String::CRC32; require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(mask); our $compiled_masks; my $debug = 0; sub mask { my $crc32 = crc32($_[0]); return $compiled_masks->{$crc32} if (defined $compiled_masks->{$crc32}); my $stash = $_[1]; my $mask = $_[0]; say "compiling from scratch" if $debug; while ($mask =~ m/([^<]*?)<\/>/gs) { my $key = $1; if ($key =~ m@\.@s) { say "dot operator detected" if $debug; my $value; my @keys = split /\./,$key; my $first = 1; foreach my $new_key (@keys) { say $new_key if $debug; if ($first) { $value = $stash->{$new_key}; $first = 0; } else { $value = $value->{$new_key}; } } $mask =~ s/$key<\/>/$value/gs; } else { say "edit : $key = $stash->{$key}" if $debug; $mask =~ s/$key<\/>/$stash->{$key}/gs; } } $compiled_masks->{$crc32} = $mask; return $mask; } #### package Bench; use Modern::Perl; use Time::HiRes qw ( gettimeofday tv_interval ); my ($start,$end,$elapsed,$fps); sub MileStone { End(); Report(); Start(); } sub Start { $start = [ gettimeofday ]; } sub End { $end = [ gettimeofday ]; } sub Report { $end = [ gettimeofday ]; $elapsed = tv_interval($start,$end); $fps = int(1 / $elapsed); say "$elapsed = $fps p/s"; } 1;