Perl 메타프로그래밍
KLDP에서 어느분이 Ruby로 메타프로그래밍에 대해서 소개하시길래 Perl로 따라해봤다.
Perl에서도 현대적이고 최신의 OOP Framework인 Moose를 사용하면 손쉽고 강력한 메타프로그래밍이 가능하다. 그리고 유연하고 풍부한 문법은 다양한 프로그래밍 스타일을 구사하는데 막힘이 없다.
use 5.010;
# Tool 클래스 정의
{
package Tool;
use MooseX::SingletonMethod;
sub setup1 {
say "setup1";
}
}
# Tool 클래스에 setup2 메소드 추가
Tool->meta->add_method( setup2 => sub { say "setup2" } );
my $tool = Tool->new;
# $tool 객체에 singleton 메소드 추가
$tool->add_singleton_method( setup3 => sub { say "setup3" } );
$tool->setup1;
$tool->setup2;
$tool->setup3;
my $tool2 = Tool->new;
$tool2->setup1;
$tool2->setup2;
$tool2->setup3; # error
use 5.010;
# Brain 클래스 정의
{
package Brain;
use Moose;
has iq => ( isa => 'Int', is => 'rw', default => 100 );
}
my $brain = Brain->new;
# 클래스 내부 들여다 보기
say $brain->meta->get_attribute('iq')->type_constraint; # Int
say $brain->meta->get_attribute('iq')->get_value( $brain ); # 100
# 블럭 메소드 호출하기
use 5.010;
sub func {
my ( $block ) = @_;
$block->();
&$block; # 이렇게도 호출~
}
sub func2 {
$_[0]->(); # 더 간단하게
&{ $_[0] }; # 이렇게도 호출~
}
my $block = sub { say "Block" };
func($block);
func2($block);
use strict;
use warnings;
use 5.010;
# 메소드 호출테이블
my $METHOD_TABLE = [ qw/a b c d/ ];
sub a { say "sub a" }
sub b { say "sub b" }
sub c { say "sub c" }
sub d { say "sub d" }
&{$main::{$_}} for @{$METHOD_TABLE};
$main::{$_}->() for @{$METHOD_TABLE};
no strict 'refs';
foreach my $i ( 0 .. $#{$METHOD_TABLE} ) {
&{ $METHOD_TABLE->[$i] };
}
$_->() for @{$METHOD_TABLE};
foreach my $func ( 'a' .. 'd' ) {
&$func;
}
foreach my $func ( 'a' .. 'd' ) {
$func->();
}
# 이런식이 더 나은?
my %METHOD_TABLE2 = (
a => sub { say "sub a" },
b => sub { say "sub b" },
c => sub { say "sub c" },
d => sub { say "sub d" },
);
$METHOD_TABLE2{$_}->() for 'a'..'d';
참고:
Ruby & Javascript Metaprogramming
Perl 5 Metaprogramming
Perl 6 Metaprogramming
Perl에서도 현대적이고 최신의 OOP Framework인 Moose를 사용하면 손쉽고 강력한 메타프로그래밍이 가능하다. 그리고 유연하고 풍부한 문법은 다양한 프로그래밍 스타일을 구사하는데 막힘이 없다.
use 5.010;
# Tool 클래스 정의
{
package Tool;
use MooseX::SingletonMethod;
sub setup1 {
say "setup1";
}
}
# Tool 클래스에 setup2 메소드 추가
Tool->meta->add_method( setup2 => sub { say "setup2" } );
my $tool = Tool->new;
# $tool 객체에 singleton 메소드 추가
$tool->add_singleton_method( setup3 => sub { say "setup3" } );
$tool->setup1;
$tool->setup2;
$tool->setup3;
my $tool2 = Tool->new;
$tool2->setup1;
$tool2->setup2;
$tool2->setup3; # error
use 5.010;
# Brain 클래스 정의
{
package Brain;
use Moose;
has iq => ( isa => 'Int', is => 'rw', default => 100 );
}
my $brain = Brain->new;
# 클래스 내부 들여다 보기
say $brain->meta->get_attribute('iq')->type_constraint; # Int
say $brain->meta->get_attribute('iq')->get_value( $brain ); # 100
# 블럭 메소드 호출하기
use 5.010;
sub func {
my ( $block ) = @_;
$block->();
&$block; # 이렇게도 호출~
}
sub func2 {
$_[0]->(); # 더 간단하게
&{ $_[0] }; # 이렇게도 호출~
}
my $block = sub { say "Block" };
func($block);
func2($block);
use strict;
use warnings;
use 5.010;
# 메소드 호출테이블
my $METHOD_TABLE = [ qw/a b c d/ ];
sub a { say "sub a" }
sub b { say "sub b" }
sub c { say "sub c" }
sub d { say "sub d" }
&{$main::{$_}} for @{$METHOD_TABLE};
$main::{$_}->() for @{$METHOD_TABLE};
no strict 'refs';
foreach my $i ( 0 .. $#{$METHOD_TABLE} ) {
&{ $METHOD_TABLE->[$i] };
}
$_->() for @{$METHOD_TABLE};
foreach my $func ( 'a' .. 'd' ) {
&$func;
}
foreach my $func ( 'a' .. 'd' ) {
$func->();
}
# 이런식이 더 나은?
my %METHOD_TABLE2 = (
a => sub { say "sub a" },
b => sub { say "sub b" },
c => sub { say "sub c" },
d => sub { say "sub d" },
);
$METHOD_TABLE2{$_}->() for 'a'..'d';
참고:
Ruby & Javascript Metaprogramming
Perl 5 Metaprogramming
Perl 6 Metaprogramming
0 TrackBacks
Listed below are links to blogs that reference this entry: Perl 메타프로그래밍.
TrackBack URL for this entry: http://aero.sarang.net/cgi-bin/mt/mt-tb.cgi/150
Leave a comment