Mojo::Base deflate/(inflate)拡張
deflate拡張してみた。以下テスト
package Onihei::Hoge; use base 'Onihei::ORM::Component'; __PACKAGE__->attr( 'hoge' , deflate => sub { 'deflate:' . $_[0] } ); package main ; use Test::Base qw/no_plan/; my $hoge = Onihei::Hoge->new(); $hoge->hoge( 'hoge' ); is( $hoge->hoge() , 'deflate:hoge' , 'deflate' ); 1;
ソース
package Onihei::ORM::Component; use warnings; use strict; use base 'Mojo::Base'; sub attr { my $class = shift; my $attrs = shift; # Shortcut return unless $class && $attrs; # Check arguments my $args; if (exists $_[1]) { my %args = (@_); $args = \%args; } else { $args = $_[0] } $args ||= {}; my $chained = delete $args->{chained}; my $default = delete $args->{default}; my $weak = delete $args->{weak}; # 拡張 my $deflate = delete $args->{deflate}; my $inflate = delete $args->{inflate}; undef $args; # Check default Carp::croak('Default has to be a code reference or constant value') if ref $default && ref $default ne 'CODE'; # Allow symbolic references no strict 'refs'; # Create attributes $attrs = ref $attrs eq 'ARRAY' ? $attrs : [$attrs]; my $ws = ' '; for my $attr (@$attrs) { Carp::croak("Attribute '$attr' invalid") unless $attr =~ /^[a-zA-Z_]\w*$/; # Header my $code = "sub {\n"; # Warning gets optimized away unless ($ENV{MOJO_BASE_OPTIMIZE}) { # Check invocant $code .= "${ws}Carp::confess(q["; $code .= qq/Attribute "$attr" has to be called on an object, not a class/; $code .= "])\n ${ws}unless ref \$_[0];\n"; } # No value $code .= "${ws}if (\@_ == 1) {\n"; $code .= "$ws${ws} \$_[0]->{'$attr'} = \$deflate->(\$_[0]->{'$attr'});\n" if $deflate; unless (defined $default) { # Return value $code .= "$ws${ws}return \$_[0]->{'$attr'};\n"; } else { # Return value $code .= "$ws${ws}return \$_[0]->{'$attr'} "; $code .= "if exists \$_[0]->{'$attr'};\n"; # Return default value $code .= "$ws${ws}return \$_[0]->{'$attr'} = "; $code .= ref $default eq 'CODE' ? '$default->($_[0])' : '$default'; $code .= ";\n"; } $code .= "$ws}\n"; # Store argument optimized if (!$weak && !$chained) { $code .= "${ws}return \$_[0]->{'$attr'} = \$_[1];\n"; } # Store argument the old way else { $code .= "$ws\$_[0]->{'$attr'} = \$_[1];\n"; } # Weaken $code .= "${ws}Scalar::Util::weaken(\$_[0]->{'$attr'});\n" if $weak; # Return value or instance for chained/weak if ($chained || $weak) { $code .= "${ws}return "; $code .= $chained ? '$_[0]' : "\$_[0]->{'$attr'}"; $code .= ";\n"; } # Footer $code .= '};'; # We compile custom attribute code for speed *{"${class}::$attr"} = eval $code; # This should never happen (hopefully) Carp::croak("Mojo::Base compiler error: \n$code\n$@\n") if $@; # Debug mode if ($ENV{MOJO_BASE_DEBUG}) { warn "\nATTRIBUTE: $class->$attr\n"; warn "$code\n\n"; } } } 1;
で、何がいいたいかというと inflate 誰か実装して!取得方法は、$hoge->inflate('hoge'); とかかなぁ。
どういうのがいいんだべか。