「シュガー関数=モダン」ではありませんが
「モダンPerlがわからない」
前回紹介したJiftyでは、
このようなシュガー関数は、
もっとも、
設定をまるごと放り込むタイプ
設定を行うためのシュガー関数としては、
これも細かなところは時代とともにいろいろ変わりましたが、
use strict;
use warnings;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'Foo',
VERSION_FROM => 'lib/Foo.pm',
PREREQ_PM => {
'Some::Module' => '0.01',
},
);
呼び出し元のクラスに設定が反映されるわけではない、
また、
複雑な設定に対応するのは大変
その一方で、
たとえば、
WriteMakefile(
NAME => 'Foo',
VERSION_FROM => 'lib/Foo.pm',
PREREQ_PM => {
'Some::Module' => '0.01',
(($^O eq 'MSWin32')
? ('Win32::Module' => '0.01')
: ()
),
},
);
もちろんこれはもう少しベタに、
my %config = (
NAME => 'Foo',
VERSION_FROM => 'lib/Foo.pm',
PREREQ_PM => {
'Some::Module' => '0.01',
},
);
if ($^O eq 'MSWin32') {
$config->{PREREQ_PM}->{'Win32::Module'} = '0.01';
}
WriteMakefile(%config);
ただ、
また、
設定を細分化して可読性を高めたタイプ
こういった問題に対するひとつの回答として登場したのが、
Module::Installを使うと、
use strict;
use warnings;
use inc::Module::Install;
name 'Foo';
all_from 'lib/Foo.pm';
requires 'Some::Module' => '0.01';
requires 'Win32::Module' => '0.01' if $^O eq 'MSWin32';
WriteAll;
ExtUtils::MakeMakerの例に比べると、
タイプ数については微妙なところですが、
Makefile.PLの中で使う分には問題ありませんが
もっとも、
たとえば、
ことModule::Installについては、
また、
noによるキーワードの除去
そのMooseですが、
ただし、
これまではスペースの都合で省略してきましたが、
package MyClass;
use Moose;
has 'foo' => (is => 'rw', isa => 'Str');
no Moose;
sub has { shift; print @_, "\n" }
package main;
my $obj = MyClass->new;
$obj->has('foo'); # foo
$obj->foo('bar');
print $obj->foo; # bar
1;
範囲を明示的に指定してよいとこ取りをする
もっとも、
このClass::Meta::Expressは2004年にリリースされたClass::Metaという、
package Person;
use strict;
use warnings;
use Class::Meta;
use Class::Meta::Types::String;
BEGIN {
my $meta = Class::Meta->new();
$meta->add_constructor( name => 'new' );
$meta->add_attribute(
name => 'name',
is => 'string',
required => 1,
);
$meta->add_method(
name => 'say_hello',
code => sub {
my $self = shift;
print "Hello, I'm ", $self->name, "\n";
},
);
$meta->build;
}
このように簡潔に書けるようになります。
package Person;
use strict;
use warnings;
use Class::Meta::Express;
BEGIN {
class {
ctor 'new';
has name => (is => 'string', required => 1);
method say_hello => sub {
my $self = shift;
print "Hello, I'm ", $self->name, "\n";
};
};
}
これだけならMooseと大差ないように見えますが
また、
また、
package MyApp::Table;
use strict;
use warnings;
use Jifty::DBI::Schema;
use Jifty::DBI::Record schema {
column foo => type is 'text';
};
やりすぎにはご用心
このように、
たとえば、
use MooseX::Declare;
class BankAccount {
has 'balance' => ( isa => 'Num', is => 'rw', default => 0 );
method deposit (Num $amount) {
$self->balance( $self->balance + $amount );
}
method withdraw (Num $amount) {
my $current_balance = $self->balance();
( $current_balance >= $amount )
|| confess "Account overdrawn";
$self->balance( $current_balance - $amount );
}
}
これ、
MooseX::Declareの場合、