Class-Spiffy

 view release on metacpan or  search on metacpan

lib/Class/Spiffy.pm  view on Meta::CPAN

    sub_start =>
      "sub {\n",
    set_default =>
      "  \$_[0]->{%s} = %s\n    unless exists \$_[0]->{%s};\n",
    init =>
      "  return \$_[0]->{%s} = do { my \$self = \$_[0]; %s }\n" .
      "    unless \$#_ > 0 or defined \$_[0]->{%s};\n",
    weak_init =>
      "  return do {\n" .
      "    \$_[0]->{%s} = do { my \$self = \$_[0]; %s };\n" .
      "    Scalar::Util::weaken(\$_[0]->{%s}) if ref \$_[0]->{%s};\n" .
      "    \$_[0]->{%s};\n" .
      "  } unless \$#_ > 0 or defined \$_[0]->{%s};\n",
    return_if_get =>
      "  return \$_[0]->{%s} unless \$#_ > 0;\n",
    set =>
      "  \$_[0]->{%s} = \$_[1];\n",
    weaken =>
      "  Scalar::Util::weaken(\$_[0]->{%s}) if ref \$_[0]->{%s};\n",
    sub_end =>
      "  return \$_[0]->{%s};\n}\n",
);

sub field {
    my $package = caller;
    my ($args, @values) = do {
        no warnings;
        local *boolean_arguments = sub { (qw(-weak)) };
        local *paired_arguments = sub { (qw(-package -init)) };
        Class::Spiffy->parse_arguments(@_);
    };
    my ($field, $default) = @values;
    $package = $args->{-package} if defined $args->{-package};
    die "Cannot have a default for a weakened field ($field)"
        if defined $default && $args->{-weak};
    return if defined &{"${package}::$field"};
    require Scalar::Util if $args->{-weak};
    my $default_string =
        ( ref($default) eq 'ARRAY' and not @$default )
        ? '[]'
        : (ref($default) eq 'HASH' and not keys %$default )
          ? '{}'
          : default_as_code($default);

    my $code = $code{sub_start};
    if ($args->{-init}) {
        my $fragment = $args->{-weak} ? $code{weak_init} : $code{init};
        $code .= sprintf $fragment, $field, $args->{-init}, ($field) x 4;
    }
    $code .= sprintf $code{set_default}, $field, $default_string, $field
      if defined $default;
    $code .= sprintf $code{return_if_get}, $field;
    $code .= sprintf $code{set}, $field;
    $code .= sprintf $code{weaken}, $field, $field 
      if $args->{-weak};
    $code .= sprintf $code{sub_end}, $field;

    my $sub = eval $code;
    die $@ if $@;
    no strict 'refs';
    *{"${package}::$field"} = $sub;
    return $code if defined wantarray;
}

t/field3.t  view on Meta::CPAN

use lib 't', 'lib';
use strict;
use warnings;

package Foo;
use Class::Spiffy -base;
my $test1 = field test1 => [];
my $test2 = field test2 => {};
my $test3 = field test3 => [1..4];
my $test4 = field test4 => {1..4};
my $test5 = field test5 => -weaken;
my $test6 = field test6 => -init => '$self->setup(@_)';
my $test7 = field test7 => -weak => -init => '$self->setup(@_)';

package main;
use Test::More tests => 7;

my @expected = map { s/\r//g; $_ } split /\.\.\.\r?\n/, join '', <DATA>;

my $i = 1;
for my $expected (@expected) {

t/field3.t  view on Meta::CPAN

          '3' => 4
        }

    unless exists $_[0]->{test4};
  return $_[0]->{test4} unless $#_ > 0;
  $_[0]->{test4} = $_[1];
  return $_[0]->{test4};
}
...
sub {
  $_[0]->{test5} = '-weaken'

    unless exists $_[0]->{test5};
  return $_[0]->{test5} unless $#_ > 0;
  $_[0]->{test5} = $_[1];
  return $_[0]->{test5};
}
...
sub {
  return $_[0]->{test6} = do { my $self = $_[0]; $self->setup(@_) }
    unless $#_ > 0 or defined $_[0]->{test6};
  return $_[0]->{test6} unless $#_ > 0;
  $_[0]->{test6} = $_[1];
  return $_[0]->{test6};
}
...
sub {
  return do {
    $_[0]->{test7} = do { my $self = $_[0]; $self->setup(@_) };
    Scalar::Util::weaken($_[0]->{test7}) if ref $_[0]->{test7};
    $_[0]->{test7};
  } unless $#_ > 0 or defined $_[0]->{test7};
  return $_[0]->{test7} unless $#_ > 0;
  $_[0]->{test7} = $_[1];
  Scalar::Util::weaken($_[0]->{test7}) if ref $_[0]->{test7};
  return $_[0]->{test7};
}



( run in 0.372 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )