AcePerl

 view release on metacpan or  search on metacpan

Ace/Model.pm  view on Meta::CPAN

package Ace::Model;
# file: Ace/Model.pm
# This is really just a placeholder class.  It doesn't do  anything interesting.
use strict;
use vars '$VERSION';
use Text::Tabs 'expand';

use overload
  '""' => 'asString',
  fallback => 'TRUE';

$VERSION = '1.51';

my $TAG     = '\b\w+\b';
my $KEYWORD  = q[^(XREF|UNIQUE|ANY|FREE|REPEAT|Int|Text|Float|DateType)$];
my $METAWORD = q[^(XREF|UNIQUE|ANY|FREE|REPEAT|Int|Text|Float|DateType)$];

# construct a new Ace::Model
sub new {
  my $class = shift;
  my ($data,$db,$break_cycle)  = @_;
  $break_cycle ||= {};

  $data=~s!\s+//.*$!!gm;  # remove all comments
  $data=~s!\0!!g;
  my ($name) = $data =~ /\A[\?\#](\w+)/;
  my $self = bless { 
		    name      => $name,
		    raw       => $data,
		    submodels => [],
	       },$class;

  if (!$break_cycle->{$name} && $db && (my @hashes = grep {$_ ne $name} $data =~ /\#(\S+)/g)) {
    $break_cycle->{$name}++;
    my %seen;
    my @submodels = map {$db->model($_,$break_cycle)} grep {!$seen{$_}++} @hashes;
    $self->{submodels} = \@submodels;
  }

  return $self;
}

sub name {
  return shift()->{name};
}

# return all the tags in the model as a hashref.
# in a list context returns the tags as a long list result
sub tags {
  my $self = shift;
  $self->{tags} ||= { map {lc($_)=>1}
		      grep {!/^[\#\?]/o} 
		      grep {!/$KEYWORD/o} 
		      $self->{raw}=~m/(\S+)/g,
		      map {$_->tags} @{$self->{submodels}}
		    };
  return wantarray ? keys %{$self->{tags}} : $self->{tags};
}

# return the path to a particular tag
sub path {
  my $self = shift;
  my $tag = lc shift;
  $self->parse;
  return unless exists $self->{path}{$tag};
  return @{$self->{path}{$tag}};
}

# parse out the paths to each of the tags
sub parse {
  my $self = shift;
  return if exists $self->{path};
  my @lines = grep { !m[^\s*//] } $self->_untabulate;

  # accumulate a list of all the paths
  my (@paths,@path,@path_stack);
  my $current_position = 0;

 LINE:
  for my $line (@lines) {

  TOKEN:
    while ($line =~ /(\S+)/g) { # get a token
      my $tag = $1;
      my $position = pos($line) - length $tag;
      next TOKEN if $tag =~ /$METAWORD/o;
      if ($tag =~ /^[?\#]/) {



( run in 0.991 second using v1.01-cache-2.11-cpan-99c4e6809bf )