http://qs321.pair.com?node_id=11120169


in reply to Use cases for 'sub Pckg::func { }' ?

Do you mean something like this?

https://rosettacode.org/wiki/Compiler/AST_interpreter#Perl

This reads in a flattened Abstract Syntax Tree (AST) and generates from it a tree of perl objects it can then run with a simple ->run method and polymorphism.
This does have a hash %variables that is shared between several of the subs in different packages(classes).

There is also this, a simpler tree based expression parser and evaluator that again uses perl polymorphism to calculate a result from a tree of objects. I'm considering submitting this to https://rosettacode.org/wiki/Arithmetic_evaluation but I'm not sure if I will.

#!/usr/bin/perl use strict; # https://rosettacode.org/wiki/Arithmetic_evaluation use warnings; sub node { bless [ splice @_, 1 ], shift } sub error { die s/\G.*//sr =~ tr/\t/ /cr, "^ $_[0] !\n" } sub want { /\G$_[1]/gc ? shift : error pop } sub expr { /\G\h+/gc; my $tree = /\G\d+/gc ? node NUMBER => $& : /\G\(/gc ? want expr(0), qr/\)/, 'Missing Right Paren' : error 'Operand Expected'; $tree = /\G\h+/gc ? $tree : $_[0] <= 0 && /\G\+/gc ? node ADD => $tree, expr(1) : $_[0] <= 0 && /\G\-/gc ? node SUBTRACT => $tree, expr(1) : $_[0] <= 1 && /\G\*/gc ? node MULTIPLY => $tree, expr(2) : $_[0] <= 1 && /\G\//gc ? node DIVIDE => $tree, expr(2) : return $tree while 1; } sub ADD::value { $_[0][0]->value + $_[0][1]->value } sub SUBTRACT::value { $_[0][0]->value - $_[0][1]->value } sub MULTIPLY::value { $_[0][0]->value * $_[0][1]->value } sub DIVIDE::value { $_[0][0]->value / $_[0][1]->value } sub NUMBER::value { $_[0][0] } sub NUMBER::show { "$_[0][0]\n" } sub UNIVERSAL::show { ref($_[0]) . "\n" . join('', map $_->show, @{$_[0]}) =~ s/^/ /g +mr } while( <DATA> ) { eval { print; my $tree = want expr(0), "\n", 'Incomplete Parse'; print $tree->show, "value of tree = ", $tree->value, "\n\n"; } or print "$@\n"; } __DATA__ (1+3)*7 42 + ( 33 + ( 7 * 8 ) 123 456 foobar 7 / foobar 7 foobar 10 - 3 - 1 10 - (3 - 1) 2 * 3 + 4 * 5 2 + 3 * 4 + 5 ((((( 7 / 4 ))))) ((((( 7 / 4 )))))))) 2 + (3 + 4 no_names_allowed ) 7 ) 1 + 3 )

Replies are listed 'Best First'.
Re^2: Use cases for 'sub Pckg::func { }' ?
by LanX (Saint) on Aug 01, 2020 at 14:22 UTC
    Didn't the requirement from Rosetta forbid the use of eval ?

    I'm a bit puzzled why you need all those packages, instead of defining separate methods in the same namespace.

    Tho I'm often not "skilled" enough to understand your code... ;-)

    ++ for creativity! =)

    update

    Ah, I think I got it, those packages are classes and you populate them with methods in a shorter syntax.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      I'm using the "block" eval, which is just a "try/catch" mechanism, so I can "die" deep in parsing recursion and still be able to go on to the next test case. It's just a different feature with the same name as the "string" eval, which is what they don't want to allow.

      I could have used a hash to map operations to their proper subs, but why bother when perl already has a hash that does that for me. "Polymorphism forever!" hehehe

      "Ah, I think I got it," - yes, yes you do :)

        Thanks.

        I can see two/three use patters now

        • your demo: ad hoc definition of small but related OOP classes in a horizontal way (contrary to "vertical" inheritance)
        • keeping the class' namespace clean of imported subs (kind of namespace::clean but right from the beginning)
        the latter even
        • on a method basis
        • without need of explicit import
        { package Subs::I::Want; sub Target::Class::method { my ($self) = shift; $self->method2(); sub_I_want() } } { package Other::Subs::I::Want; sub Target::Class::method2 { other_sub_I_want() } }

        hence

        • Target::Class->method() or ->method2() work
        • Target::Class->sub_i_want() or ->other_sub_I_want() won't work
        GREAT, learned something new! :)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery