Acme::Chef::Container - Internal module used by Acme::Chef


Acme-Chef documentation Contained in the Acme-Chef distribution.

Index


Code Index:

NAME

Top

Acme::Chef::Container - Internal module used by Acme::Chef

SYNOPSIS

Top

  use Acme::Chef;

DESCRIPTION

Top

Please see Acme::Chef;

METHODS

This is a list of methods in this package.

new

This is the Acme::Chef::Container constructor. Creates a new Acme::Chef::Container object. All arguments are treated as key/value pairs for object attributes.

put

This method implements the 'put' command. Please refer to Acme::Chef for details.

fold

This method implements the 'fold' command. Please refer to Acme::Chef for details.

add

This method implements the 'add' command. Please refer to Acme::Chef for details.

remove

This method implements the 'remove' command. Please refer to Acme::Chef for details.

combine

This method implements the 'combine' command. Please refer to Acme::Chef for details.

divide

This method implements the 'divide' command. Please refer to Acme::Chef for details.

put_sum

This method takes a number of Acme::Chef::Ingredient objects as arguments and creates and 'puts' the sum of the ingredients.

Please refer to Acme::Chef for details.

liquify_contents

This method implements the 'liquify' command for all ingredients. Please refer to Acme::Chef for details.

stir_time

This method implements the 'stir' command. First argument should be the depth ("time") to stir. Please refer to Acme::Chef for details.

stir_ingredient

This method implements the 'stir_ingredient' command. Please refer to Acme::Chef for details.

mix

This method implements the 'mix' command. Please refer to Acme::Chef for details.

Shuffles the container's contents.

clean

This method implements the 'clean' command. Please refer to Acme::Chef for details.

Empties the container.

pour

This method implements the 'pour' command. Please refer to Acme::Chef for details.

Returns the contained ingredients.

print

Returns stringification of the object.

AUTHOR

Top

Steffen Mueller.

Chef designed by David Morgan-Mar.

COPYRIGHT AND LICENSE

Top


Acme-Chef documentation Contained in the Acme-Chef distribution.
package Acme::Chef::Container;

use strict;
use warnings;

use Carp;

use Acme::Chef::Ingredient;

use vars qw/$VERSION/;
$VERSION = '1.00';

sub new {
   my $proto = shift;
   my $class = ref $proto || $proto;

   my $self = {};

   if (ref $proto) {
      %$self = %$proto;
      $self->{contents} = [ map { $_->new() } @{$self -> {contents}} ];
   }

   %$self = (
     contents => [],
     %$self,
     @_,
   );

   return bless $self => $class;
}


sub put {
   my $self = shift;

   my @ingredients = @_;

   push @{$self->{contents}}, $_->new() for @ingredients;

   return $self;
}

sub fold {
   my $self = shift;

   my $ingredient = shift;

   croak "Invalid operation on empty container: fold."
     unless @{$self->{contents}};

   my $new_val = pop @{ $self->{contents} };

   $ingredient->value( $new_val->value() );

   return $ingredient;
}

sub add {
   my $self = shift;

   my $ingredient = shift;

   croak "Invalid operation on empty container: add."
     unless @{$self->{contents}};

   $self->{contents}->[-1]->value(
     $self->{contents}->[-1]->value() +
     $ingredient->value()
   );

   return $ingredient;
}


sub remove {
   my $self = shift;

   my $ingredient = shift;

   croak "Invalid operation on empty container: remove."
     unless @{$self->{contents}};

   $self->{contents}->[-1]->value(
     $self->{contents}->[-1]->value() -
     $ingredient->value()
   );

   return $ingredient;
}


sub combine {
   my $self = shift;

   my $ingredient = shift;

   croak "Invalid operation on empty container: combine."
     unless @{$self->{contents}};

   $self->{contents}->[-1]->value(
     $self->{contents}->[-1]->value() *
     $ingredient->value()
   );

   return $ingredient;
}


sub divide {
   my $self = shift;

   my $ingredient = shift;

   croak "Invalid operation on empty container: divide."
     unless @{$self->{contents}};

   $self->{contents}->[-1]->value(
     $self->{contents}->[-1]->value() /
     $ingredient->value()
   );

   return $ingredient;
}

sub put_sum {
   my $self = shift;

   my @ingredients = @_;

   my $sum = 0;
   $sum += $_->value() for @ingredients;

   my $ingredient = Acme::Chef::Ingredient->new(
     name    => '',
     value   => $sum,
     measure => '',
     type    => 'dry',
   );

   $self->put($ingredient);

   return $ingredient;
}

sub liquify_contents {
   my $self = shift;

   foreach my $ingredient (@{$self->{contents}}) {
      $ingredient->liquify();
   }

   return $self;
}

sub stir_time {
   my $self = shift;

   my $depth = shift;

   return $self unless scalar @{$self->{contents}};

   $depth = $#{$self->{contents}} if $depth > $#{$self->{contents}};

   my $top = pop @{ $self->{contents} };
   splice @{$self->{contents}}, (@{$self->{contents}}-$depth), 0, $top;

   return $self;
}



sub stir_ingredient {
   my $self = shift;

   my $ingredient = shift;

   $self->stir_time($ingredient->value());

   return $self;
}

sub mix {
   my $self = shift;

   _fisher_yates_shuffle( $self->{contents} );

   return $self;
}

sub clean {
   my $self = shift;

   @{$self->{contents}} = ();

   return $self;
}


sub pour {
   my $self = shift;

   return @{ $self->{contents} };
}


sub print {
   my $self = shift;

   my $string = '';

   foreach my $ingr ( reverse @{$self->{contents}} ) {
      if ($ingr->type() eq 'liquid') {
         $string .= chr( $ingr->value() );
      } else {
         $string .= ' '.$ingr->value();
      }
   }

   return $string;
}


# From the Perl FAQ: (NOT a method)
# fisher_yates_shuffle( \@array ) :
# generate a random permutation of @array in place
sub _fisher_yates_shuffle {
    my $array = shift;
    my $i;
    for ($i = @$array; --$i; ) {
        my $j = int rand ($i+1);
        @$array[$i,$j] = @$array[$j,$i];
    }
}

__END__