For my own code (I'm running 5.18.1), I probably would have used state as you've done there: your post got a ++ from me. However, unless the question specifically involves a more recent Perl, or I know the person I'm responding to is familiar with 5.10.0+, I find providing a pre-5.10 (or, more strict, an any Perl5) solution to be a lot less hassle: that would be non-virtuous laziness on my part. :-)
While there may be some subtlety I'm missing, which I'm more than happy to learn about, I really don't see any "tighter encapsulation". In both cases, the hash is only evaluated once and only visible by the expr subroutine. From a visual perspective, the hash is clearly more closely associated with the subroutine: in fact, that would be one of my reasons for preferring it.
There's another issue which I'd forgotten about until I ran a few tests. You can't simply substitute my with state in my %op_func = (...);. If you try this, you get a compilation error:
"Initialization of state variables in list context currently forbidden"
So, you need to code state $op_func = {...}; as you have here. Having to dereference $op_func incurs a minimal overhead which, in general, wouldn't prevent me from using it unless efficiency was of particular concern. I found the %op_func solution to be consistently 2% faster than the $op_func solution:
$ perl -Mstrict -Mwarnings -E ' use Benchmark qw{cmpthese}; { my %op_func1 = ( "+" => sub { $_[0] + $_[1] }, "-" => sub { $_[0] - $_[1] }, "*" => sub { $_[0] * $_[1] }, "/" => sub { $_[0] / $_[1] }, ); sub expr1 { my ($lhs, $op, $rhs) = split " ", shift; $op_func1{$op}->($lhs, $rhs); } } sub expr2 { state $op_func2 = { "+" => sub { $_[0] + $_[1] }, "-" => sub { $_[0] - $_[1] }, "*" => sub { $_[0] * $_[1] }, "/" => sub { $_[0] / $_[1] }, }; my ($lhs, $op, $rhs) = split " ", shift; $op_func2->{$op}->($lhs, $rhs); } my @ops = ("+","-","*","/"); cmpthese(-1, { with_my => sub { expr1("4 $_ 5") for @ops }, with_state => sub { expr2("4 $_ 5") for @ops }, }); ' Rate with_state with_my with_state 112733/s -- -2% with_my 114840/s 2% --
-- Ken
In reply to Re^3: Array of operators ...
by kcott
in thread Array of operators ...
by janDD
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |