Acme-Chef
view release on metacpan or search on metacpan
lib/Acme/Chef.pm view on Meta::CPAN
sub compile {
my $proto = shift;
my $class = ref $proto || $proto;
my $code = shift;
defined $code or croak "compile takes one argument: a code string.";
my $self = {};
bless $self => $class;
my @paragraphs = $self->_get_paragraphs( $code );
my @recipes = $self->_paragraphsToRecipes(\@paragraphs);
$_->compile() foreach @recipes;
$self->{start_recipe} = $recipes[0]->recipe_name();
$self->{recipes} = {
map { ($_->recipe_name(), $_) } @recipes
};
return $self;
}
=item execute
Takes no arguments. Runs the program and returns its output.
=cut
sub execute {
my $self = shift;
my $start_recipe = $self->{recipes}->{ $self->{start_recipe} }->new();
$start_recipe->execute($self->{recipes});
return $start_recipe->output();
}
=item dump
Takes one optional argument. If it equals 'autorun',
dump returns a string that, when evaluated, executes
the program and returns the output.
If the argument does not equal 'autorun', a different
string is returned that reconstructs the Acme::Chef
object.
=cut
sub dump {
my $self = shift;
my $type = shift;
$type = '' if not defined $type;
local $@ = undef;
require Data::Dumper;
my $dumper = Data::Dumper->new([$self], ['self']);
$dumper->Indent(0);
$dumper->Purity(1);
my $dump = $dumper->Dump();
if ($type =~ /^autorun$/) {
$dump = 'do{my ' . $dump . ' bless $self => "' . (__PACKAGE__) . '"; $self->execute();} ';
} else {
$dump = 'do{my ' . $dump . ' bless $self => "' . (__PACKAGE__) . '";} ';
}
return $dump;
}
# private function _get_paragraphs
sub _get_paragraphs {
my $self = shift;
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return split /\n{2,}/, $string;
}
# private function _paragraphsToRecipes
#
# Constructs recipes from an array ref of paragraphs.
sub _paragraphsToRecipes {
my $self = shift;
my $paragraphs = shift;
$paragraphs = shift if not defined $paragraphs or not ref $paragraphs;
while (chomp @$paragraphs) {}
my @recipes;
my $paragraph_no = 0;
while (@$paragraphs) {
my $recipe_name = shift @$paragraphs;
$paragraph_no++;
$recipe_name =~ /^[ ]*([\-\w][\- \w]*)\.[ ]*$/
or croak "Invalid recipe name specifier in paragraph no. $paragraph_no.";
$recipe_name = lc($1);
last unless @$paragraphs;
my $comments = shift @$paragraphs;
$paragraph_no++;
my $ingredients;
if ( $comments =~ /^[ ]*Ingredients\.[ ]*\n/ ) {
$ingredients = $comments;
( run in 1.766 second using v1.01-cache-2.11-cpan-d80b1682f3f )