블로그 이미지
JEEN

서울에 사는 꽃청년의 IT찌질모험기

Rss feed Tistory
IT/Perl 2008.06.07 14:27

[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #3 - 형태에 관한 이야기

사용자 삽입 이미지

 지난번에는 Moose 의 상속에 대한 이야기를 해봤습니다. 사실 이것저것 빼먹고 가는 것이 많기 때문에, 개인적으로 좀 더 알아봐주셨으면 하는 심정이 있고, 좀 더 알아보자 라고 했을 때 좀 지루할 것 같아서... 일단 원리를 알고 쓰기보다는 쓰면서 원리를 알아가는 게 더 쉬운 방법인 것 같기도 합니다.

2008/06/02 - [IT/Perl] - [ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #1-2

여기에서 isa 에 들어가는 형태에 대한 언급이 있었고, Int 에서 문자열 쓰면 에러난다는 등의 해서는 안될 짓에 대한 이야기를 한 적이 있습니다. 이번에는 형태에 대한 좀 더 자세한 이야기입니다.
 
package Me2day::Request;
use Moose;
use Moose::Util::TypeConstraints;

subtype 'URI' # 자기가 정의하고픈 형태의 이름
  => as 'Object'  # 계승한 형태
  => where { $_->isa('URI') }; # 형태의 Validation 체크 

has 'uri' => (is => 'rw', isa => 'URI');

1;

  일단 가장 간단한 예제를 주워와봤습니다. 이런 'URI' 같은 자신이 직접 형태를 정해줄 경우에는
use Moose::Util::TypeConstraints;
이 필수입니다.

 그런 다음에는 자기 나름대로 URI 이라는 형태를 지정해 줍니다.
subtype 'URI'
  => as 'Object'
  => where { $_->isa('URI') };
 이제 uri 접근자는 URI가 아니면 받아들일 수 없게 되어버립니다. 이 말인 즉슨...

 my $blah = Me2day::Request->new( 'uri' => 'http://jeen.tistory.com' );

 일 때, uri 의 값을 문자열인 http://jeen.tistory.com 으로 지정했습니다. 이러면 자신이 정의한 URI 의 타입에 맞지 않게 됩니다. URI 는 Object 이기를 기대하며, URI 모듈을 사용하기를 원하고 있죠. 그럼 이 입맛에 맞춰주면 됩니다.
 my $blah = Me2day::Request->new( 'uri' => URI->new('http://jeen.tistory.com') );

 그러면 이제 화를 내지 않는 우리의 Moooooose ~
 Moose 특유의 뿔 처럼 엄격함만을 강조하는 것이냐면, 그럴 수도 있습니다만, 여기서 더욱 유연하게 처리해줄 수 도 있습니다.
 coerce 'URI'
   => from 'Str'
   => via { URI->new($_) }
   => from 'Int'
   => via { blahblah... }
 coerce 를 사용하는 것입니다. 이러면 URI 속성을 사용하는 접근자에 문자열('Str') 이 올때에는 URI 모듈을 사용해서 부르게 됩니다. 이때는 여러 상속형태에 대해서 강제변경을 지정할 수 있습니다.

 여기서 중요한 것은 coerce 를 사용해서 강제로 형태변경할 경우에는 접근자에 옵션을 하나 더 추가해줘야 합니다.
has 'uri' => (is => 'rw', isa => 'URI', coerce => 1);
 이렇게 말이죠.

 전체코드입니다.

package Me2day::Request;
use Moose;
use Moose::Util::TypeConstraints; # 아래와 같은 일을 하려면 반드시!
use URI;

subtype 'URI' # 자기가 정의하고픈 형태의 이름
  => as 'Object'  # 계승한 형태
    => where { $_->isa('URI') }; # 형태의 Validation 체크

coerce 'URI' # 강제 형태변경
  => from 'Str' # 이런 타입이 오면
  => via { URI->new($_) };  # 이렇게 해줘야지.

has 'uri' => (is => 'rw', isa => 'URI', coerce => 1);

1;

my $blah = Me2day::Request->new ( uri => 'http://jeen.tistory.com' );
print $blah->uri."\n";  # http://jeen.tistory.com
print $blah->uri->scheme;  # http
 
  물론 uri 의 값은 URI->new('http://jeen.tistory.com') 를 써도 됩니다. 이건  subtype 에서 기본적으로 바라고 있는 값의 형태이기 때문입니다.

 이쯤에서 다른 예제를 불러오도록 하죠.
package Me2day::Request;
use Moose;
use Moose::Util::TypeConstraints;
use Digest::MD5;

subtype 'Encrypt'
    => as 'Str';

coerce 'Encrypt'
    => from 'Str'
    => via {
        my $nonce = sprintf "%08x", rand(16 ** 8);
        $nonce.Digest::MD5->new->add($nonce.$_)->hexdigest;
    };

has 'username' => (is => 'ro', isa => 'Str', required => 1);
has 'password' => (is => 'ro', isa => 'Encrypt', required => 1, coerce => 1);

1;

my $blah = Me2day->new ( username => 'jeen', password => '22830' );
print $blah->password; # 65dfb0a73f23368b4701a2435d8a64cabd26762b

 어떤 별 다른 차이점도 없습니다. Me2day의  인증키 생성을 위한 처리를 coerce 'Encrypt' 에 담아서,
password 값이 들어오면 자동으로 인증키를 만들고 그 값이 password 의 값으로 강제변경되는 것입니다. 위에서 언급을 빼먹었는데. coerce 를 사용하기 위해서는 subtype 이 지정되어 있어야 합니다.

 이상으로 Moose 의 형태변경에 대한 이야기를 마치겠습니다.
신고
IT/Perl 2008.06.03 14:08

[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #2 - 상속

사용자 삽입 이미지

 요즘은 미국 쇠고기 사태로 세상이 시끄럽습니다. 그래서 예제도 이 현실에 맞춰서 해볼까 합니다.

package Cow;
use Moose;

has name => (is => 'ro');
has age  => (is => 'ro', isa => 'Int', required => 1);

sub cry {
  my $self = shift;
  warn "Umme~";
}

sub walk {
  my $self = shift;
  warn "ummmme~ I'm walking";
}

sub eat {
    my $self = shift;
    warn "umme~ I'm eating!";
}

 Cow 라는 놈을 만들어봤습니다. 나름대로 누렁이, 흰둥이라는 이름(name)을 가질 것이고, 몇 개월짜리 인지 나이(age)를 가지게 됩니다. 이름은 속일 수 있어도, 나이는 속여서는 안된다는 신념하에서 Int 형의 값을 받기를 원하고, 나이는 반드시 넣어줘야 하는 그런 소망을 넣어봤습니다.
 기본적으로 소는 울고(cry), 걷고(walk), 먹는(eat) 행동을 하게 됩니다.

 자, 그리고 위의 Cow를 상속받아서 MadCow 를 만듭니다.

package Madcow;
use Moose;

has 'feed' => (is => 'rw', isa => 'Str', default => 'Animal Feed' );

extends 'Cow';   # Moose 는 다중상속이 가능합니다.
                        # 그럴 때는 extends 'Cow', 'Dog', 'Chicken'; 같이 씁니다.

1;

 자.. 이렇게 만들었습니다.

my $mc = Madcow->new(
    name => 'Downer',
    age => 30,
);

 그리고 30 개월령, Downer씨를 만들어 냅니다.
$mc->cry;   # Umme~
$mc->walk;  # ummmme~ I'm walking
$mc->feed;
$mc->eat;    # umme~ I'm eating!

 Cow 의 모든 속성과 행동을 물려받은 MadCow, Downer 씨는 이렇게 평범한 삶을 살고 있었습니다. 울면(cry) Umme~ 하고 울고, 걸으면(walk) 계속 걸을 수 있었고, 먹으면(eat) 잘먹고 살고 있었다 이거죠.
 하지만 Downer 씨가 먹고 있던 것은 무엇이었을까요?
 
 has 'feed' => (is => 'rw', isa => 'Str', default => 'Animal Feed' );

 맙소사! 먹이('feed') 를 동물성 사료('Animal Feed') 를 먹고 있었던 것이죠. 이렇게 속성 값은 생성자 호출시에 정해줄 수도 있고, 기본값(default) 으로 정해줄 수도 있습니다.

 아무튼 이렇게 동물성 사료만 먹고, 별탈 없던 Downer 씨에게 어느날 PD 수첩이 와서 심층취재를 했습니다.

override 'cry' => sub {
    my $self = shift;
    if ($self->age >= 30 || $self->feed eq 'Animal Feed') {
        warn "BowWow";
    } else {
        super();
    }
};

 우선 PD 수첩 관계자는 Downer 씨가 우는 것에 대해서 진상규명을 했습니다. Downer 씨는 30개월령에다가, 이제껏 먹고 있던 먹이는 동물성 사료였다는 것이죠. 그리고 자기가 우는 소리도 모르고 있었습니다. "Umme~" 가 아니라 "BowWow" 하면서 짖고 있었던 것이었죠! 맙소사! 조금만 더 어리거나, Downer 씨 주인님께서 동물성 사료만 안먹였어도 이런일은 없었을 텐데 말이죠.
after 'walk' => sub {
    my $self = shift;
    if ($self->age >= 30 || $self->feed eq 'Animal Feed') {
        warn "BowWow! I'm down";
    } else {
        warn "Umme~ keep going!";
    }
};

 그리고 언젠가부터 걷고 나서는 계속 쓰러지고는 했습니다. "BowWow"라고 짖으면서 말이죠. 역시나 마찬가지로 조금 더 어렸거나, 동물성 사료만 안먹어도 이런 일은 없었을 텐데 말이죠!
 
 PD수첩 관계자들이 모두 떠나간 뒤로.. Downer 씨는 절망에 빠졌습니다. 내가 뭣땜에 이렇게 변했나 하구요.

before 'eat' => sub {
    my $self = shift;
    if ($self->feed eq 'Animal Feed') {
        warn "Oops.. What is this?";
    } else {
        warn "I washed my hands";
    }
};

 그리고 Downer 씨는 이제부터라도 주의를 기울이기 시작했습니다. 주인이 동물성 사료를 주고, Downer씨는 "이게 뭐냐"고 주인에게 따지기 시작했습니다. 하지만 먹을 수 밖에 없었죠. 이때마다 주인에 대한 불만은 쌓여만 갔습니다. "동물성 사료만 아니었어도..."라고 그는 항상 생각하는 듯 합니다.

...
...
후기..;; 결국 Downer 씨는 조용히 쓰러져 앉아있다가 생을 마감하려고 했는데, 주인은 그런 Downer 씨를 도축해서 <금싸라기 쇠고기 수입국> 한국으로 수출되는 배에 선적했습니다.

 전체코드입니다(Downer 씨가 도축되기 전)

{
package Cow;
use Moose;

has name => (is => 'ro');
has age  => (is => 'ro', isa => 'Int', required => 1); # 나이는 속일 수 없다!

sub cry {
  my $self = shift;
  warn "Umme~";
}

sub walk {
  my $self = shift;
  warn "ummmme~ I'm walking";
}

sub eat {
    my $self = shift;
    warn "I'm eating!";
}

}

{
package Madcow;
use Moose;

has 'feed' => (is => 'rw', isa => 'Str', default => "Animal Feed");
 # 기본적으로 동물성 사료를 제공하고 있지만, 먹이는 바꿀수 있습니다(is => 'rw')

extends 'Cow'; # Cow 를 상속

# 오버라이드
override 'cry' => sub {
    my $self = shift;
    if ($self->age >= 30 || $self->feed eq 'Animal Feed') {
        warn "BowWow";
    } else {
        super(); # Umme~
    }
};

# super() 를 호출한 뒤의 이벤트
after 'walk' => sub {
    my $self = shift;
    if ($self->age >= 30 || $self->feed eq 'Animal Feed') {
        warn "BowWow! I'm down";
    } else {
        warn "Umme~ keep going!";
    }
};

# super() 를 호출하기 전의 이벤트
before 'eat' => sub {
    my $self = shift;
    if ($self->feed eq 'Animal Feed') {
        warn "Oops.. What is this?";
    } else {
        warn "I washed my hands";
    }
};
}

1;

my $mc = Madcow->new(
    name => 'Downer',
    age => 30,
);

$mc->cry; #BowWow

$mc->walk; # BowWow! I'm down

$mc->eat; # Oops.. What is this?
                 # I'm eating

$mc->feed("Grasses");  # Grasses 를 사료로 제공

$mc->eat; # I washed my hands
                 # I'm eating

 Downer 씨, 고인의 명복을 빕니다. 또다른 Downer 씨가 사회에 나오지 않도록, 전세계 축산농가들은...

$mc->feed("Grasses");

 했으면 좋겠습니다.  (_ _)

 현실세태를 반영, Moose 를 이용한 "상속" 에 대해서 알아보았습니다.

 물론 여기에서 언급한 내용에 대한 사실 여부는 전 모르며, 이 내용은 팩션일지도 모릅니다. :-)
신고
IT/Perl 2008.06.02 21:16

[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #1-2

사용자 삽입 이미지

  우선 앞에서 잠깐 맛보기로 봤던 Moose 코드에 대해서 가볍게 집고 넘어가보도록 합니다.  아마 이런 코드 였죠.

package Whitecat;
use Moose;

has name => (is => 'ro');
has age  => (is => 'ro');

1;

 여기에서 has 에 대해서 알아보겠습니다.

 has name => (is => 'ro');

 이것은 name 이라는 속성을 Whitecat 이라는 클래스에 정의하는 것입니다. 기본 형태는
has $name => %options;

 입니다. $name 에는 스칼라값이, %options 에는 해쉬값이 들어가게 됩니다. $name 에는 일반적인 Perl 변수정의 형태를 따르게됩니다. 그럼 %options 의 내용에는 뭐가 들어가게 되느냐에 대해서 가볍게 알아보겠습니다.
has name => (is => '[blah]');
 
 [blah] 에는 ro 나 rw 가 들어갑니다. 뜻은 딱 보나마나 겠죠. readonly 와, read-write 입니다. name 이라는 속성은 이런 속성값을 가지게 됩니다. 만약 ro 인데 값을 바꾸면 어떻게 될까요?

package Whitecat;
use Moose;

has name => (is => 'ro');
has age  => (is => 'ro');

1;

my $whitecat = Whitecat->new(
    name => 'Haak_Cat',
    age  => 30,
);

$whitecat->name("Blah_Cat");

 그래서 해봤습니다.
사용자 삽입 이미지
'Cannot assign a value to a read-only accessor at blahblah...' 라는 에러가 납니다. 절대로 readonly 인 속성값을 바꾸려고 하지 마세요. 한번 지정해 줬으면 그걸로 땡입니다.

 그리고 그 다음으로 해서는 안될 것...
has age  => (is => 'ro', isa => 'Int');

 age 의 형을 Int 로 정의해놓습니다. 그리고는
my $whitecat = Whitecat->new(
    name => 'Haak_Cat',
    age  => "Thirty",
);
  라고 넣어봅니다.

 그리고 이런 경우는 어떨까요?
my $whitecat = Whitecat->new(
    name => 'Haak_Cat',
    age  => "",
);

  당연히 에러가 나오겠죠? 그럼 어떤 에러냐...
사용자 삽입 이미지
'Attribute (age) does not pass the type constraint becaus: Validation failed for 'Int' failed with value [value] at blahblah...' 라고 뜹니다.

 당연히 속성값의 형태를 Int로 정해줬는데 'Thirty' 같은 문자열이 나오면 에러를 뿜어야되겠죠. 그리고 공백은 수치가 아니기 때문에 마찬가지로 에러가 나오게 됩니다.

 isa 로 정의할 수 있는 형태는 많습니다. Class 이름부터, Int, Str, HashRef, ArrayRef, ScalarRef, Object, Bool... 물론 이에 대해서 다 다뤄보지 않았기 때문에 조금조금 해나가보겠습니다. 성급한 성격의 소유자께서는 이에 대한 Moose Document 를 직접 보시면 되겠습니다.

 딱보면 해서는 안되는 짓 다음은...

has age  => (is => 'ro', isa => 'Int', required => 1);

라고 정의합니다. 그리고는
my $whitecat = Whitecat->new(
    name => 'Haak_Cat',
);
 
 age 속성을 정의해 주지 않았습니다. 그러면..
사용자 삽입 이미지

 'Attribute (age) is required at blahblah...' 라고 화를 냅니다.

required 는 이 속성이 필수요소 인가 아닌가를 정의합니다. 값은 0,1로 설정합니다.

 딱봐도 알만한 해서는 안되는 짓 세번째 였습니다.

 이상으로 문서를 읽지 않아도 대충 어떻게 될지 알 수 있는 , "Moose의 딱봐도 알만한 해서는 안되는 짓"이었습니다.
신고
moose, OOP, perl
IT/Perl 2008.06.02 19:29

[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #번외편

사용자 삽입 이미지

 이건 미리 쓸려고 했는데...

 YAPC::Asia 2008 에서 Moose 관련 세션에 대한 소개입니다.

 
  그리고 PT는 여기에 ...
 

 그리고 Moose 에 대한 이야기를 간단하게 번역해 봤습니다.

 1. Moose 는 또다른 OOP 시스템인가요?

 - Perl 5 에서 오브젝트를 생성하는 새로운 방법이 최근 폭발적으로 증가했고, 그 많은 인사이드아웃 오브젝트나 그와 비슷한 것을 기본으로 하고 있는 것을 알았습니다. Moose 는 Perl 5의 새로운 오브젝트 시스템이 아닌 기존의 오브젝트 시스템을 확장한 것입니다.

 2. Moose 는 정말로 쓸 수 있는 것인가요? 아니면 그냥 재미로 만들어 본 건가요?

 - Moose는 Perl 6에서 실험한 메타/모델의 시험작이나 실험을 기반으로 했습니다만 시험삼아서 만든 게 아닙니다. 실제 운용에 쓰일 수 있습니다. Moose 는 몇 명정도의 개인이나 몇 개의 회사에 의해 실제 운용환경에서 사용중입니다. 일년 이상동안, 혹은 전혀 문제없이 실제로 운용되는 Moose 어플리케이션이 몇가지 있습니다. 전 이것이 크게 안정되어 있다고 보고, 앞으로도 그럴 것이라고 약속합니다.          
 
 3.  Moose 는 단순하게 Perl 5에서 움직이는 Perl 6 가 아닌가요?

 - 아뇨. Moose는 Perl 6 에 많은 자극을 받았습니다만, 이것 자체가 Perl6 는 아닙니다. 오히려 Perl5 을 위한 OO시스템입니다. 저는 낡고 지겨운 Perl OO 코드를 쓰는 것에 지쳤고, Perl 6 OO에 감흥을 느꼈기에, Moose 를 만들었습니다. 즉, Ruby 로 가는 대신에 Moose 를 만든 것입니다. :-)

  4. 잠깐. Post Modern 이라구요? 단순히 Modern 으로 생각되는 데요?

 - 전 Larry Wall 의 1999년 Linux World "Perl, 최초의 포스트모던 컴퓨터 언어(Perl, the first postmodern computer language)" 라는 제목의 세션을 읽었습니다. 그 안에서 Larry 가 Perl 의 기능으로써 그가 좋다고 생각하는 것을 넣고, 그가 지겹다고 느끼는 것을 버리는 것에 대해서 말했었습니다. 이것에는 Moose 로 같은 것을 하기에 어떻게 하면 좋을 까 생각하게 되었습니다. Moose는 Perl 6, CLOS (LISP), Smalltalk, Java, BETA, OCaml, Ruby, 그 외의 많은 기능을 "빌려" 왔고, 몇개인가의 좋지않은 것은 버렸습니다. 이런 이유로(그외 2,3가지 이유로) 저는 Moose 를 "포스트모던" 오브젝트 시스템이라고 다시 부르고 있습니다.

  이 외에 내용은 http://search.cpan.org/~stevan/Moose-0.48/lib/Moose.pm 을 확인하시면 되겠습니다.
 문서화가 아직 덜 되어 있지만, 사용하기에는 충분할 것이라고 생각합니다. :-) 문서화가 덜 되어 있어도 일단 문서화 작업에 뛰어들려고 하는데요. Moose 문서화 작업에 참여하실 분을 모집합니다.

 perldoc-kr 에서 작업을 하려고 합니다. 한번 해보지 않으시겠어요? :-)

 관심있으신 분은 aiatejin _at_ gmail.com 으로 메일, 혹은 댓글 달아주시면 되겠습니다.
신고
IT/Perl 2008.06.02 17:23

[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #1

 -----

 Perl 에서 OOP라면 고개를 갸우뚱 거리실 분들이 많으실 겁니다. 그 이전에 Perl 에서 고개를 갸우뚱 하실 분들도 계실지도 모르겠습니다. orz..

 저 역시도 OOP, Perl 에서의 OOP라면 고개를 갸우뚱 하는 사람 중에 하나 입니다. 서브루틴들을 싹 긁어모아서, package Blah; ~ 1; 안에다가 넣고 어쩌구 저쩌고 하는 게 다였거든요. 그러다 보면 코드는 중복이고, 비슷비슷한 기능하는 것들이 너무나도 많고, 네이밍 센스가 하도 저질이라서 뭘 그렇게 find 하는 것 많고 set 하는 거 많고 write 하는 거 많은 지 모를 정도이죠.

 이렇게 1000줄, 2000줄 넘어가다가 보면 결국은 맥을 놔버립니다. (전 맥을 사용합니다 :-))
 에러나면 부랴부랴 코드보고 대충대충 디버그 해놓으면 나중에는 결국 더 심각한 버그가 쌓이고 쌓이고...
 처음부터 제대로 기반을 만들지 못했으니, GIGO의 예제들을 책으로 내면 그 자체가 GIGO의 바이블이 될 정도로 허접하고 사이비한 코드들이 태반입니다. OOP는 둘째치고 감각적인 코드를 만들어내지 못했던 것이죠. 그냥 평범한 스크립트 작업에 그렇게 기합을 넣고 할 필요가 없다는 것도 제 지론(?)이기도 했습니다.

 그런 지론을 좀 바꿔볼까하며 Perl OOP에 대한 이야기를 시작해보려고 합니다.
package Whitecat;
use strict;
use warnings;

sub new {
  my ($class, $args) = @_;

  return bless {
      name => $args->{name},
      age    => $args->{age},
   }, $class;
}

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

sub age {
 return shift->{age};
}

1;

my $who = Whitecat->new({
    name => 'haak_cat',
    age  => '30',
});

print $who->name; # haak_cat 이 찍힙니다.

 이것이 간단한 Perl OOP의 예제입니다.

 package Whitecat;
 (blahblahblah...)
 1;

 까지가 Class 를 정의한 것입니다. Whitecat 이라는 것은 클래스이름이죠.

 이건 왜 넣어야 되는가? 궁금하시면 IRC로 오세요. #perl-kr@irc.freenode.org

use strict;
use warnings;

 이것은 생성자(Constructor)입니다. 여기서 클래스를 초기화해주겠죠?

sub new {
  my ($class, $args) = @_;

  return bless {
      name => $args->{name},
      age    => $args->{age},
   }, $class;
}

 이것들은 접근자(Accessor) 입니다.

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

sub age {
 return shift->{age};
}

 그리고 이렇게 정의된 클래스를 한번 사용해 봅니다.

my $whitecat = Whitecat->new({
    name => 'haak_cat',
    age  => '30',
});

print $whitecat->name; # haak_cat 이 찍힙니다.

 대충 감을 잡으셨나요? 어때요? 참 쉽죠?
 근데 Perl OOP 이정도면 누구나 다 아는 사실 입니다. 사실 누구나 펄 스크립트 짤 때 이런 식으로 쉽게 한다는 것이죠.
 요즘 Perl 계에서 붐이 불고 있는 하나의 모듈이 있습니다.

사용자 삽입 이미지

간지폭발 Mooooooooose


말그대로 A Postmodern Object System 인데요. 그럼 왜 이게 Postmodern 한지 한번 보도록 하죠.

package Whitecat;
use Moose;

has name => (is => 'ro');
has age  => (is => 'ro');

1;

my $whitecat = Whitecat->new(
    name => "haak_cat",
    age  => 30,
);

print $whitecat->name;

 위의 장황하던 코드가 이렇게 깔끔하게 바뀌었습니다.

 이 부분은 바뀐 것이 없습니다.
 package Whitecat;
 (blahblahblah...)
 1;

 use Moose; 함으로써 ust strict; use warnings; 를 해줄 필요가 없어집니다. 
use Moose;

 접근자는 이렇게 간단하게 만들 수 있습니다. 
has name => (is => 'ro');
has age  => (is => 'ro');

 그리고 이렇게 정의된 클래스를 어떻게 사용하느냐면...

my $whitecat = Whitecat->new(
    name => "haak_cat",
    age  => 30,
);

print $whitecat->name;

 사용법은 같습니다. 생성자(new) 를 정의하지 않아도 Moose 가 알아서 해주죠. 이 부분은 걱정해주지 않으셔도 됩니다. 이름찍으면 역시 이름이, 나이를 찍으면 나이가 나옵니다.
 
 Moo~~~se. 어떤가요? 보다 가독성 있고, 간결한 코드를 만들어버릴 수 있을 것 같지 않나요?
 일단은 첫번째 이야기는 이정도에서 그치겠습니다. 저도 좀 더 봐둬야 되겠고,
 보면서 기존의 IRC BOT 스크립트를 Moose 로 바꿔볼까 하고 생각하고 있습니다.


신고
TOTAL 473,882 TODAY 60

티스토리 툴바