# Copyright (C) 2003-2007, G. Allen Morris III, all rights reserved
use strict;
package
Data::Tabular::Table::Extra;
use base 'Data::Tabular::Table::Data';
use Carp qw (croak);
sub new
{
my $caller = shift;
my $self = $caller->SUPER::new(@_);
$self->{_all_headers} = [ (@{$self->{data}->{headers} || []}, sort keys(%{$self->extra->{columns} || {}})) ];
$self;
}
sub extra
{
my $self = shift;
$self->{extra};
}
sub is_extra
{
my $self = shift;
my $column_name = shift;
exists $self->extra->{columns}->{$column_name};
}
sub headers
{
my $self = shift;
@{$self->{_all_headers}};
}
sub all_headers
{
my $self = shift;
$self->{_all_headers} = [ (@{$self->{data}->{headers} || []}, sort keys(%{$self->extra->{columns} || {}})) ];
@{$self->{_all_headers}};
}
sub row_package
{
require Data::Tabular::Row::Extra;
'Data::Tabular::Row::Extra';
}
sub header_offset
{
die;
my $self = shift;
my $column = shift;
my $count = 0;
unless ($self->{_header_off}) {
for my $header ($self->headers) {
$self->{_header_off}->{$header} = $count++;
}
}
my $ret = $self->{_header_off}->{$column};
croak "column '$column' not found in [",
join(" ",
sort keys(%{$self->{_header_off}})
), ']' unless defined $ret;
$ret;
}
sub get_row_column
{
my $self = shift;
my $row = shift;
my $column = shift;
my $count = scalar(@{$self->{data}->{headers}});
if ($column >= $count) {
die 'column out of range';
} else {
$self->{data}->{rows}->[$row][$column];
}
}
sub extra_column
{
my $self = shift;
my $row = shift;
my $key = shift;
my $ret = 'N/A';
die;
my $extra = $self->{extra};
return undef unless $row;
my $offset = $self->header_offset($key);
my $x = $self->extra_package->new(row => $row, table => $self);
if (ref($extra->{$key}) eq 'CODE') {
eval {
$ret = $extra->{$key}->($x);
};
if ($@) {
die $@;
}
} else {
die 'only know how to deal with code';
}
die $ret;
if (ref($ret)) {
die if (ref($ret) eq 'HASH');
}
$ret;
}
1;
__END__
=head1 NAME
Data::Tabular::Table::Extra
=head1 SYNOPSIS
This object is used by Data::Tabular to hold a table with calculated columns.
=head1 DESCRIPTION
This object holds a table that has calculated columns.
=head1 METHODS
=over 4
=item is_extra
The is extra method is used by underlying row to decide if a column needs to be
calculated.
=back
=head1 SEE ALSO
Data::Tabular::Row::Extra
=cut