| Category: | Fun |
| Author/Contact Info | davidhj at mail dot com |
| Description: | Ever write code like this?
This is particularly common when you're outputting HTML or whatever. You have to write the same for loop or if ... else structure over and over again. This is not lazy! To encourage laziness, here is an idea. Comments very welcome - this is version 0.0001 at most. I will improve it but only if it is useful and has not been done before. The logic is to make control structures into objects. You can then reuse them more elegantly by manipulating them. E.g., you can have the same array for a foreach loop, but change what you do in the loop body. If you need to change the array, you only have to do it once. Packaging structure is non-existent as yet, bugs have not been found. YHBW. |
package Control;
use strict;
use vars qw/$AUTOLOAD/;
sub new {
my $class = shift;
my $self = { @_ };
bless $self, $class;
}
sub _do_code {
my $self = shift;
my ($code, $context) = @_;
if (ref $code) {
local $_ = $context if $context;
return &$code;
} else {
local $_ = $context if $context;
my $rv = eval $code;
die $@ if $@;
return $rv;
}
}
sub AUTOLOAD {
my $self = shift;
my $name = $AUTOLOAD;
$name =~ s/.*:://;
my $rv = $self->{$name};
if (@_) {
$self->{$name} = shift;
}
return $rv;
}
package Foreach;
use strict;
use vars qw/@ISA/;
use Control;
@ISA = qw/Control/;
sub run {
my $self = shift;
foreach (@{ $self->{array} }) {
$self->_do_code($self->{body}, $_);
}
}
package If;
use strict;
use vars qw/@ISA/;
use Control;
@ISA = qw/Control/;
sub run {
my $self = shift;
if ( $self->_do_code( $self->{condition} ) ) {
$self->_do_code( $self->{body}, $_ );
} else {
my $done;
ELSIF: foreach my $elsif ( @{ $self->{elsifs} } ) {
if ( $self->_do_code( $elsif->{condition} ) ) {
$self->_do_code( $elsif->{body}, $_ );
$done++;
last ELSIF;
}
}
if ($self->{else} and not $done) {
$self->_do_code($self->{else}, $_ );
}
}
}
sub elsif {
my $self = shift;
my $elsif = { @_ };
push @{ $self->{elsifs} }, $elsif;
}
1;
=head1 Name
Control - OO control structures
=head1 Synopsis
#!/usr/bin/perl -w
use Control;
my @bar = (1,2,3,"dog");
my $loop = new Foreach (
body => 'print $_ . "\n"',
array => \@bar
);
$loop->run;
$loop->{array} = [3,4,5,"cat"];
$loop->run;
$loop->{body} = sub { print "The length of $_ is " . (length $_) . "\
+n";};
$loop->run;
my $if = new If (
condition => '$_ % 2',
body => sub { print "$_ is an odd number\n" }
);
for ( 0 .. 10 ) {
$if->run;
}
$if->elsif (
condition => 'not $_ % 2',
body => 'print "$_ is an even number\n"'
);
for (11 .. 20) {
$if->run;
}
=cut
|
|
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: OO Control loops
by Juerd (Abbot) on Jan 04, 2002 at 01:11 UTC | |
by dash2 (Hermit) on Jan 04, 2002 at 15:43 UTC | |
by Juerd (Abbot) on Jan 04, 2002 at 16:28 UTC |