in reply to Auto-evaluating anonymous subroutines

I recommend against your plan -- it is unduly complex -- but it is possible using operator overloading.
use strict; use warnings; package Character; use AutoExecute; sub new { my ($class) = @_; return bless({ poisoned => 0, }, $class); } sub poisoned { my ($self) = @_; return auto_execute { my ($poisoned) = @_; $self->{poisoned} = $poisoned if @_; return $self->{poisoned}; }; } package main; my $char = Character->new(); my $poisoned = $char->poisoned; print($poisoned, "\n"); # 0 $poisoned->(1); print($poisoned, "\n"); # 1 $poisoned->(0); print($poisoned, "\n"); # 0

AutoExecute.pm: (Could probably use a better name)

package AutoExecute; BEGIN { our @EXPORT = qw( auto_execute ); *import = \&Exporter::import; } use overload '""' => \&stringify, '&{}' => \&code_ref, ; sub auto_execute(&) { my ($sub) = @_; return bless(\$sub); } sub new { my ($class, $sub) = @_; return bless(\$sub, $class); } sub stringify { my ($self) = @_; my $sub = $$self; return $sub->(); } sub code_ref { my ($self) = @_; my $sub = $$self; return $sub; } 1;

But all of the above would be much faster and just as neat if written as follows:

use strict; use warnings; package Character; sub new { my ($class) = @_; return bless({ poisoned => 0, }, $class); } sub poisoned { my ($self, $poisoned) = @_; $self->{poisoned} = $poisoned if @_ >= 2; return $self->{poisoned}; } package main; my $char = Character->new(); print($char->poisoned, "\n"); # 0 $char->poisoned(1); print($char->poisoned, "\n"); # 1 $char->poisoned(0); print($char->poisoned, "\n"); # 0

Replies are listed 'Best First'.
Re^2: Auto-evaluating anonymous subroutines
by diotalevi (Canon) on Feb 21, 2006 at 02:12 UTC

    There's no need to put your @EXPORT and *import assignment in a BEGIN block. File-level code in modules is run just after it's been compiled. It's where the required "true" value comes from. That is, if Character uses AutoExecute, the work required to set up Exporter has already completed by the time AutoExecute->import() is run. You only need to use a BEGIN block if other code in the same module cares that your snippet runs before later code in the same file is compiled.

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

        I'm ttrying to think of the last time I wrote modules that used each other. A few years? They were OO and didn't use Exporter either.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re^2: Auto-evaluating anonymous subroutines
by skx (Parson) on Feb 21, 2006 at 14:44 UTC

    ++ for the stringify use.

    I've not used the overload module before, and that was a nice introduction.

    It almost makes me feel Java-esque to realise I can have a toString routine in my objects!

    Steve
    --