Skip to content

Latest commit

ย 

History

History
1471 lines (1150 loc) ยท 39.9 KB

hatena_perl_oop.md

File metadata and controls

1471 lines (1150 loc) ยท 39.9 KB

Perl ๊ฐ์ฒด์ง€ํ–ฅ(OOP) ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์•Œ๋ฆฌ๋Š” ๋ง

์ด ๋ฌธ์„œ๋Š” ์ผ๋ณธ Hatena ์‚ฌ์˜ ์ธํ„ด๊ต์œก์šฉ ๋ฌธ์„œ์ธ Hatena-TextBook์˜ oop-for-perl ๋ฌธ์„œ https://github.com/hatena/Hatena-Textbook/blob/master/oop-for-perl.md ๋ฅผ ๋ฒˆ์—ญํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ ๋‚ด์šฉ์˜ ์ถ”๊ฐ€ ๋ฐ ์•ฝ๊ฐ„์˜ ์ˆ˜์ •์ด ๊ฐ€ํ•ด์กŒ์Šต๋‹ˆ๋‹ค. ๋ผ์ด์„ผ์Šค๋Š” ์›๋ฌธ๊ณผ ๊ฐ™์ด Creative Commons license๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

(๋ฌธ์„œ ๋ฒˆ์—ญ์— ๋„์›€์„ ์ค€ @JEEN_LEE๊ตฐ๊ณผ Seoul.pm ์—ฌ๋Ÿฌ๋ถ„๋“ค๊ป˜ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.)

์ด ๋ฌธ์„œ๋Š” Perl OOP๋ฅผ ์œ„ํ•œ ํ•ต์‹ฌ๋งŒ์„ ๊ตต์งํ•˜๊ฒŒ ์งš์–ด๋‚˜๊ฐ€๋ฏ€๋กœ ๋ถ€์กฑํ•œ ์ ์€ ๋‹ค์Œ ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€๋กœ ์ฐธ๊ณ ํ•˜์„ธ์š”.

๋ชฉ์ฐจ

  • Perl ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•ต์‹ฌ
  • Perl ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ
  • ํ…Œ์ŠคํŠธ๋ฅผ ์“ฐ์ž
  • ๋„์›€๋ง
  • ๊ณผ์ œ์— ๋Œ€ํ•ด

Perl ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•ต์‹ฌ

Perl์˜ ์ข‹์€์ 

  • CPAN
    • ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒƒ์ด ๋Œ€๋ถ€๋ถ„ ์ด๋ฏธ ๋ชจ๋“ˆํ™”๋˜์–ด ์žˆ๋‹ค.
    • ๊ทธ๊ฑด CPAN์—์„œ ํ•  ์ˆ˜ ์žˆ์–ด
  • ํ‘œํ˜„๋ ฅ์ด ์šฐ์ˆ˜ํ•˜๋‹ค
    • TMTOWTDI (๋ฐฉ๋ฒ•์€ ์–ผ๋งˆ๋“ ์ง€ ์žˆ๋‹ค๏ผ)
  • ์ด๋ฏธ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.
    • DeNA/NHN/mixi๋“ฑ
  • ์ข‹์€ ๊ฐœ๋ฐœ๋ฌธํ™”๊ฐ€ ์žˆ๋‹ค.

์ฐธ๊ณ  ์‹ธ์ดํŠธ

Perlํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•ต์‹ฌ

  • Perl์˜ ์ฃผ์š”ํŠน์ง•์„ ์„ค๋ช…
    • use strict;use warnings;
    • ๋ฐ์ดํ„ฐํ˜•์‹
    • ๋ฌธ๋งฅ/์ปจํ…์ŠคํŠธ(Context)
    • ์ฐธ์กฐ/๋ ˆํผ๋Ÿฐ์Šค(reference)
    • ํŒจํ‚ค์ง€(package)
    • ์„œ๋ธŒ๋ฃจํ‹ด

use strict;use warnings;

  • ํŒŒ์ผ ์‹œ์ž‘๋ถ€๋ถ„์— ๋ฐ˜๋“œ์‹œ ์“ฐ์„ธ์š”
use strict;
use warnings;
  • ์ €๊ฒƒ๋“ค์„ ์“ฐ์ง€ ์•Š๋Š” ๊ธฐ๋ณธ ๋™์ž‘์€ ๊ณผ๊ฑฐ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ์ œํ•œ์‚ฌํ•ญ์ด ์•ฝํ•จ.(์˜ˆ: one-liner)

use strict; use warnings;์„ ์จ์•ผํ•˜๋Š” ์ด์œ 

my $message = "hello";
print $messsage; # typo!
# => ์˜คํƒ€๋ฅผ ๋‚ด๋„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ ์•ˆํ•จ!
$messagge = "bye"; # typo!
# => $messagge ์˜ค๋ฅ˜ ๋ฐœ์ƒ๏ผ
  • Javascript๋„ ์ตœ๊ทผ use strict ๋„์ž…, Python, Ruby์—์„œ๋Š” ์ด๋Ÿฐ ์žฅ์น˜๊ฐ€ ์—†๋‹ค.
  • ์„ฌ์„ธํ•œ ๋™์ž‘์€ perldoc์ฐธ๊ณ 
$ perldoc strict
$ perldoc perllexwarn

๋ฐ์ดํ„ฐํ˜•์‹

  • ์Šค์นผ๋ผ(scalar)
  • ๋ฐฐ์—ด(array)
  • ํ•ด์‹œ(hash)
  • ํŒŒ์ผํ•ธ๋“ค(file handle)
  • ํƒ€์ž…๊ธ€๋กœ๋ธŒ(typeglob)

์Šค์นผ๋ผ

  • 1๊ฐœ์˜ ๊ฐ’
  • ๋ฌธ์ž์—ด/์ˆซ์ž/๋ ˆํผ๋Ÿฐ์Šค
  • $calar ๋กœ ๊ธฐ์–ตํ•ฉ์‹œ๋‹ค.
my $scalar1 = "test";
my $scalar2 = 1000;
my $scalar3 = \@array; # ๋ฐฐ์—ด์˜ ๋ ˆํผ๋Ÿฐ์Šค

๋ฐฐ์—ด

  • @rray ๋กœ ๊ธฐ์–ตํ•ฉ์‹œ๋‹ค.
my @array = ('a', 'b', 'c');
  • Q:@array์˜ ๋‘๋ฒˆ์งธ ์š”์†Œ๋ฅผ ์–ป์œผ๋ ค๋ฉด?

๋ฐฐ์—ด ๋‹ค๋ฃจ๊ธฐ

print $array[1]; # 'b'
  • ์Šค์นผ๋ผ ๊ฐ’์„ ์–ป๋„๋ก $๋กœ ์ ‘๊ทผ
  • $array์™€ @array๋Š” ๋‹ค๋ฅด๋‹ค.

๋ฐฐ์—ด ๋‹ค๋ฃจ๊ธฐ

$array[0]; # get
$array[1] = 'hoge'; # set
my $length = scalar(@array); # ๊ธธ์ด
my $last_ids = $#array; # ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค ๋ฒˆํ˜ธ
my @slice = @array[1..4]; # ์Šฌ๋ผ์ด์Šค ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค 1~4์˜ ๊ฐ’
foreach my $e (@array) { # ๋ชจ๋“  ์š”์†Œ ์ˆœํšŒ
  print $e;
}
  • ์ฒดํฌํ•ด๋‘์ž๏ผ
  • ์กฐ์ž‘ํ•จ์ˆ˜: push / pop / shift / unshift / map / grep / join / sort / splice
  • ๊ด€๋ จ๋ชจ๋“ˆ: List::Util / List::MoreUtils

ํ•ด์‹œ

  • %ash ๋กœ ๊ธฐ์–ตํ•ฉ์‹œ๋‹ค.(%๋Š” key/value๋ฅผ ์ค„์—ฌ๋†“์€ ๋ชจ์–‘?)
my %hash = (
  perl  => 'larry',   # => ์•ž์—๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฌธ์ž์—ด์ผ ๊ฒฝ์šฐ์— ์ธ์šฉ๋ถ€ํ˜ธ๊ฐ€์—†๋Š” ๋ฌธ์ž์—ด(= '"์ด ์—†๋Š” bareword)์ด ํ—ˆ์šฉ๋œ๋‹ค. 
  ruby => 'matz',     # Perl์—์„œ๋Š” ๋’ค์— ๋‚จ๋Š” ,๊ฐ€ ์žˆ์–ด๋„ ์ƒ๊ด€์—†๋‹ค. ๋„ฃ์–ด๋†“์œผ๋ฉด ๋‚˜์ค‘์— ์š”์†Œ๋ฅผ ๋” ์ถ”๊ฐ€ํ•  ๊ฒฝ์šฐ ํŽธ๋ฆฌํ•จ
);
#์œ„๋Š” my %hash = ( 'perl', 'larry', 'ruby', 'matz' ); ์™€ ๊ฐ™๋‹ค. =>์„ ์“ฐ๋ฉด ํ‚ค,๊ฐ’์‚ฌ์ด ์‹œ๊ฐ์  ๊ตฌ๋ณ„ํšจ๊ณผ๋ฅผ ๋†’ํ˜€์คŒ.
  • Q:hash์˜ key:perl์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์„ ์–ป์œผ๋ ค๋ฉด?

ํ•ด์‹œ ๋‹ค๋ฃจ๊ธฐ

print $hash{perl}; # larry
print $hash{ruby}; # matz
my @values = @hash{'perl', 'ruby'};  #ํ•ด์‹œ์Šฌ๋ผ์ด์Šค ํ‚ค perl,ruby์— ๋Œ€ํ•œ ๊ฐ’๋“ค @์™€ { }์— ์ฃผ๋ชฉ
  • ์Šค์นผ๋ผ ๊ฐ’์„ ์–ป๊ธฐ์œ„ํ•ด $์„ ์‚ฌ์šฉ
  • $hash์™€ %hash๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜
  • {} ์•ˆ์˜ ํ‚ค์ง€์ •์— ์ผ๋ฐ˜์ ์ธ ๋ฌธ์ž์—ด์ผ ๊ฒฝ์šฐ์— ์ธ์šฉ๋ถ€ํ˜ธ๊ฐ€์—†๋Š” ๋ฌธ์ž์—ด(= '"์ด ์—†๋Š” bareword)์ด ํ—ˆ์šฉ๋œ๋‹ค.

ํ•ด์‹œ ๋‹ค๋ฃจ๊ธฐ

$hash{perl}; # get
$hash{perl} = 'larry'; # set
for my $key (keys %hash) { # ์ „ ์š”์†Œ ํ‚ค์—๋Œ€ํ•ด ์ˆœํšŒ
  my $value = $hash{$key};
}
  • ์ฒดํฌํ•ด๋‘์ž๏ผ
    • ํ•จ์ˆ˜: keys / values / delete / exists / each

๋ฐ์ดํ„ฐํ˜•์‹ ์š”์•ฝ

  • ์Šค์นผ๋ผ - $ /๋ฐฐ์—ด - @ /ํ•ด์‹œ - %
  • $val๊ณผ @val๊ณผ %val์€ ๋‹ค๋ฅธ ๋ณ€์ˆ˜
$ perldoc perldata

์ปจํ…์ŠคํŠธ

  • Perl์—๋Š” ์ปจํ…์ŠคํŠธ๋ผ๋Š” ๊ฒƒ์ด ์žˆ๋‹ค.
  • ๋Œ€ํ‘œ์ ์ธ ํŠน์ง•
  • ์‹์ด ํ‰๊ฐ€๋˜๋Š” ์žฅ์†Œ(= ์ปจํ…์ŠคํŠธ)์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋ณ€ํ•จ
my @x = (0,1,2);
my ($ans1) = @x;
my $ans2 = @x;
  • ๊ฐ๊ฐ ๋ฌด์—‡์ด ๋“ค์–ด๊ฐˆ๊นŒ?

์ปจํ…์ŠคํŠธ

my @x = (0,1,2);
my ($ans1) = @x; # => 0
my $ans2 = @x; # => 3
  • ๋ฐฐ์—ด/๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•œ ํ• ๋‹น์˜ ์šฐ๋ณ€์€ ๋ฆฌ์ŠคํŠธ ์ปจํ…์ŠคํŠธ
    • 0์ด ํ• ๋‹น๋œ๋‹ค. 1,2๋Š” ๋ฒ„๋ ค์ง(void context)
  • ์Šค์นผ๋ผ์— ๋Œ€ํ•œ ํ• ๋‹น์˜ ์šฐ๋ณ€์€ ์Šค์นผ๋ผ ์ปจํ…์ŠคํŠธ
    • ๋ฐฐ์—ด์ด ์Šค์นผ๋ผ ์ปจํ…์ŠคํŠธ์—์„œ ํ‰๊ฐ€๋˜๋ฉด ๊ธธ์ด๋ฅผ ๋ฐ˜ํ™˜

์ปจํ…์ŠคํŠธ ํ€ด์ฆˆ

  • <์—ฌ๊ธฐ>์˜ ์ปจํ…์ŠคํŠธ๋Š” ์Šค์นผ๋ผ, ๋ฆฌ์ŠคํŠธ์ค‘ ์–ด๋–ค ๊ฒƒ์ผ๊นŒ?
sort <์—ฌ๊ธฐ>;
length <์—ฌ๊ธฐ>;
if (<์—ฌ๊ธฐ>) { }
for my $i (<์—ฌ๊ธฐ>) { }
$obj->method(<์—ฌ๊ธฐ>);
my $x = <์—ฌ๊ธฐ>;
my ($x) = <์—ฌ๊ธฐ>;
my @y = <์—ฌ๊ธฐ>;
my %hash = (
  key0 => 'hoge',
  key1 => <์—ฌ๊ธฐ>,
);
scalar(<์—ฌ๊ธฐ>);
<์—ฌ๊ธฐ>;

ํ•ด๋‹ต

sort <์—ฌ๊ธฐ>;   # sortํ•จ์ˆ˜ ๋’ค๋Š” ๋ฆฌ์ŠคํŠธ์ปจํ…์ŠคํŠธ
length <์—ฌ๊ธฐ>; # lengthํ•จ์ˆ˜ ๋’ค๋Š” ๋ฌธ์ž์—ด์ด ์˜ค๋ฏ€๋กœ ์Šค์นผ๋ผ์ปจํ…์ŠคํŠธ
if (<์—ฌ๊ธฐ>) { } # ์ฐธ,๊ฑฐ์ง“์ด ๋“ค์–ด๊ฐ€๋Š” ๊ณณ์€ ๋ถˆ๋ฆฌ์–ธ(boolen)์ปจํ…์ŠคํŠธ๋ผ๊ณ  ํ•˜๋ฉฐ ์Šค์นผ๋ผ์ปจํ…์ŠคํŠธ์˜ ์ผ์ข…์ด๋‹ค.
foreach my $i (<์—ฌ๊ธฐ>) { }  # ๋ฃจํ”„๋กœ ๋„˜๊ธธ ๊ฒƒ๋“ค์ด ๋“ค์–ด๊ฐ€๋ฏ€๋กœ ๋ฆฌ์ŠคํŠธ์ปจํ…์ŠคํŠธ
$obj->method(<์—ฌ๊ธฐ>);  # ๋ฉ”์†Œ๋“œ์˜ ์ธ์ž๋“ค์ด ๋“ค์–ด๊ฐ€๋ฏ€๋กœ ๋ฆฌ์ŠคํŠธ์ปจํ…์ŠคํŠธ
my $x = <์—ฌ๊ธฐ>;  # ์Šค์นผ๋ผ์ปจํ…์ŠคํŠธ
my ($x) = <์—ฌ๊ธฐ>; # ๋ฆฌ์ŠคํŠธ์ปจํ…์ŠคํŠธ
my @y = <์—ฌ๊ธฐ>; # ๋ฆฌ์ŠคํŠธ์ปจํ…์ŠคํŠธ
my %hash = (
  key0 => 'hoge',
  key1 => <์—ฌ๊ธฐ>, # ๋ฆฌ์ŠคํŠธ์ปจํ…์ŠคํŠธ
);
scalar(<์—ฌ๊ธฐ>); #์Šค์นผ๋ผ์ปจํ…์ŠคํŠธ
<์—ฌ๊ธฐ>; # ๋ฆฌ์ŠคํŠธ์ปจํ…์ŠคํŠธ

์ปจํ…์ŠคํŠธ ์ •๋ฆฌ

  • ์‹/๊ฐ’์ด ๊ณ„์‚ฐ๋˜๋Š” ์œ„์น˜์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋ณ€ํ•จ
  • ์ปจํ…์ŠคํŠธ์˜ ๊ฒฐ์ •๋ฐฉ๋ฒ•์€ ๊ธฐ์–ตํ•ด์•ผ ํ•œ๋‹ค.
    • ๋‚ด์žฅํ•จ์ˆ˜๋’ค์˜ ์ธ์ˆ˜ ๋ถ€๋ถ„ ์ฃผ์˜ (length ๋“ฑ)
    • ๋‚ด์žฅํ•จ์ˆ˜ ์ด์™ธ์—๋„ prototype์ด๋ผ๋Š” ๊ธฐ๋Šฅ์œผ๋กœ ์ง€์ • ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ์ฃผ์˜
$ perldoc perldata
$ perldoc perlsub # Prototype ์ฐธ๊ณ ๋ฌธ์„œ

๋ ˆํผ๋Ÿฐ์Šค/์ฐธ์กฐ

  • ์Šค์นผ๋ผ/๋ฐฐ์—ด/ํ•ด์‹œ ๋“ฑ์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค
    • C++์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ƒ๊ฐ/Ruby๋“ฑ์—์„œ๋Š” ๋ชจ๋“ ๊ฒƒ์ด ๋ ˆํผ๋Ÿฐ์Šค
    • ๋ฐ์ดํ„ฐ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค๋•Œ ๋งค์šฐ ์ค‘์š”ํ•จ

๋ฐ์ดํ„ฐ๊ตฌ์กฐ ์š”์ 1

  • ํ–‰๋ ฌ์„ ๋งŒ๋“ค์–ด ๋ณด์ž
my @matrix = (
  (0, 1, 2, 3),
  (4, 5, 6, 7),
);
  • ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

์ด๋ ‡๊ฒŒ ๋œ๋‹ค.

my @matrix =
  (0, 1, 2, 3, 4, 5, 6, 7);
  • ํ—

๋ฐ์ดํ„ฐ๊ตฌ์กฐ ์š”์ 2

my %entry = (
  body => 'hello!',
  comments => ('good!', 'bad!', 'soso'),
)
  • ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

์ด๋ ‡๊ฒŒ ๋œ๋‹ค.

my %entry = (
  body => 'hello!',
  comments => 'good',
  'bad!' => 'soso',
);
  • ํ—

์™œ?

  • ()์•ˆ์€ ๋ฆฌ์ŠคํŠธ ์ปจํ…์ŠคํŠธ
  • ๋ฆฌ์ŠคํŠธ ์ปจํ…์ŠคํŠธ์—์„œ ๋ฆฌ์ŠคํŠธ๋Š” ํ’€๋ ค๋ฒ„๋ฆผ(flatten). Perl์—์„œ ๊ด„ํ˜ธ๋Š” ํ‰๊ฐ€์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋†’์ด๋Š” ๊ธฐ๋Šฅ๋งŒ ํ•œ๋‹ค.
my @matrix = (
  (0, 1, 2, 3),
  (4, 5, 6, 7),
);

๋ ˆํผ๋Ÿฐ์Šค ์–ป๊ธฐ/๋งŒ๋“ค๊ธฐ(๋ฐฐ์—ด)

my @x = (1,2,3);
my $ref_x1 = \@x;
# ์ฃผ์˜!  my @x = \(1,2,3);๋Š” (\1,\2,\3)์ด๋‹ค. ์œ„์˜ ๋ฐฐ์—ด๋ ˆํผ๋Ÿฐ์Šค \@x์™€๋Š” ๋‹ค๋ฆ„ 

# ์ค„์ด๋ฉด
$ref_x2 = [1,2,3];

# ์ด๋ ‡๊ฒŒ๋„
$ref_x3 = [@x]; # ์ด ๊ฒฝ์šฐ๋Š” @x๊ฐ€ [ ]์•ˆ์˜ ๋ฆฌ์ŠคํŠธ์ปจํ…์ŠคํŠธ์—์„œ ํ™•์žฅ๋˜์–ด @x์˜ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ๋‚ด์šฉ์ด ๋ณต์‚ฌ๋˜์–ด [1,2,3]์ด ๋œ๋‹ค.

๋””๋ ˆํผ๋Ÿฐ์Šค

๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ผ๋ฐ˜์  ์ž๋ฃŒํ˜•์œผ๋กœ ๋˜๋Œ๋ฆฌ๋Š” ์ž‘์—…

use 5.010;
my $scalar_ref = \5;
say $scalar_ref;      # SCALAR(0x1c6fc74)  ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์œ„์น˜ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๊ฐ€ ์ฐํž˜
say ${$scalar_ref};   # 5      ${$scalar_ref}๋Š” $$scalar_ref๋กœ ๊ฐ„๋žตํ™” ๊ฐ€๋Šฅ

my $array_ref = [2,3,4];
say $array_ref;       # ARRAY(0x70ba8c)
say @{$array_ref};    # 234  @{$array_ref}๋Š” @$array_ref๋กœ ๊ฐ„๋žตํ™” ๊ฐ€๋Šฅ
say ${$array_ref}[0]; # 2      ${$array_ref}[0]๋Š” $$array_ref[0]์™€ $array_ref->[0]์œผ๋กœ ๊ฐ„๋žตํ™” ๊ฐ€๋Šฅ
  • ํ˜•ํƒœ์™€ ๊ทœ์น™: ์›ํ•˜๋Š”๋ณ€์ˆ˜ํ˜•_๋””๋ ˆํผ๋Ÿฐ์Šคsigil { ๋ ˆํผ๋Ÿฐ์Šค } ํ•„์š”ํ• ๊ฒฝ์šฐ_์ธ๋ฑ์Šค๋‚˜ ํ‚ค
  • ์šฐ์„ ์ˆœ์œ„์— ๋ฌธ์ œ์—†์„ ๊ฒฝ์šฐ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๊ฐ์‹ธ๋Š” { }๋Š” ์ƒ๋žต๊ฐ€๋Šฅ(์ธ๋ฑ์Šค๋‚˜ ํ‚ค๋ž‘ ๋””๋ ˆํผ๋Ÿฐ์Šคsigil์ค‘ sigil์ด ๋จผ์ € ๊ฒฐํ•ฉํ•œ๋‹ค.)
  • ${$array_ref}[index] ๋Š” $array_ref-&gt;[index], ${$hash_ref}{key} ๋Š” $hashref->{key}๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅ
  • ์ธ๋ฑ์Šค๋‚˜ ํ‚ค๋ฅผ ์ง€์ •ํ•˜๋Š” ๋ฐฐ์—ด์ด๋‚˜ ํ•ด์‹œ์˜ ๋””๋ ˆํผ๋Ÿฐ์Šค์˜ ๊ฒฝ์šฐ ->๋ฅผ ์‚ฌ์šฉํ•œ ํ˜•ํƒœ๊ฐ€ ์ง๊ด€์ ์ด๊ณ  ๋„๋ฆฌ ์‚ฌ์šฉ๋จ

๋””๋ ˆํผ๋Ÿฐ์Šค (๋ฐฐ์—ด)

my $ref_x = [1,2,3];

my @x = map { $_ * 2 } @$ref_x;

print $ref_x->[0]; # 1   ${$ref_x}[0]๊ณผ ๊ฐ™๋‹ค. ${$array_ref}[์ธ๋ฑ์Šค] ๋Š” $array_ref->[์ธ๋ฑ์Šค] ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Œ

my @new_x = @$ref_x;
print $new_x[0]; # 1

๋ ˆํผ๋Ÿฐ์Šค ์–ป๊ธฐ/๋งŒ๋“ค๊ธฐ(ํ•ด์‹œ)

my %y = (
  perl => 'larry',
  ruby  => 'matz',
);
my $ref_y1 = \%y;

# ์ค„์ด๋ฉด
$ref_a2 = {
  perl => 'larry',
  ruby => 'matz',
}

๋””๋ ˆํผ๋Ÿฐ์Šค (ํ•ด์‹œ)

my $ref_y = {
  perl => 'larry',
  ruby => 'matz',
};

my @keys = keys %$ref_y;

print $ref_y->{perl}; # larry ${$ref_y}{perl}๊ณผ ๊ฐ™๋‹ค. ${$hash_ref}{ํ‚ค} ๋Š” $hash_ref->{ํ‚ค} ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Œ

my %new_f = %$ref_y;
print $new_f{perl}; # larry

๋ฐ์ดํ„ฐ๊ตฌ์กฐ ๋งŒ๋“ค๊ธฐ

  • ๋ ˆํผ๋Ÿฐ์Šค๋Š” ์Šค์นผ๋ผ๊ฐ’์ด๋‹ค.(๋ ˆํผ๋Ÿฐ์Šค๋Š” ๋ฉ”๋ชจ๋ฆฌ์ƒ์— ์œ„์น˜ํ•œ ์ฃผ์†Œ๋ฅผ ๋‚˜ํƒ€๋ƒ„์„ ์ƒ๊ธฐ) = ๋ฆฌ์ŠคํŠธ ์ปจํ…์ŠคํŠธ๋กœ ํ™•์žฅ๋˜์ง€ ์•Š์Œ
my $matrix = [
  [0, 1, 2, 3],
  [4, 5, 6, 6],
];
# 5์— ์ ‘๊ทผํ•˜๋ ค๋ฉด? ์ฐจ๋ก€๋กœ ๊นŒ๋ฉด ${${$matrix}[1]}[1] ํ™”์‚ดํ‘œ ํ‘œ๊ธฐ๋กœ ํ•˜๋ฉด $matrix->[1]->[1]
# $matrix->[1]->[1] ๋Š” $matrix->[1][1] ๋กœ ๊ฐ€๋Šฅํ•˜๋‹ค.( ์—ฐ์†์ ์ธ ์ธ๋ฑ์Šค, ํ‚ค ์ง€์ • ์‚ฌ์ด์˜ ->๋Š” ์ƒ๋žต๊ฐ€๋Šฅ )

my @matrix2 = (
  [0, 1, 2, 3],
  [4, 5, 6, 6],
);

# 5์— ์ ‘๊ทผํ•˜๋ ค๋ฉด? ์ฐจ๋ก€๋กœ๊นŒ๋ฉด ${$matrix2[1]}[1] ํ™”์‚ดํ‘œ ํ‘œ๊ธฐ๋กœ ํ•˜๋ฉด $matrix2[1]->[1]
# ์œ„์˜ ๊ทœ์น™์— ์˜ํ•˜์—ฌ ->๋Š” ์ƒ๋žต๊ฐ€๋Šฅ ํ•˜๋ฏ€๋กœ $matrix2[1][1] ๋กœ ์ค„์—ฌ ์“ธ ์ˆ˜ ์žˆ์Œ
# ๋ ˆํผ๋Ÿฐ์Šค๋กœ ๋งŒ๋“  ํ–‰๋ ฌ $matrix, ๋ฐฐ์—ด๋กœ ๋งŒ๋“  ํ–‰๋ ฌ @matrix2์˜ ์ฐจ์ด์ ์„ ํ™•์ธํ•  ๊ฒƒ
my $entry = {
  body => 'hello!',
  comments => ['good!', 'bad!', 'soso'],
};
# good!์— ์ ‘๊ทผํ•˜๋ ค๋ฉด?  ์ฐจ๋ก€๋กœ ๊นŒ๋ฉด ${${$entry}{comments}}[0] ํ™”์‚ดํ‘œ ํ‘œ๊ธฐ๋กœํ•˜๋ฉด $entry->{comments}->[0]

๋ณต์žกํ•œ ๋ ˆํผ๋Ÿฐ์Šค

  • ์˜ˆ: ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ๋””๋ ˆํผ๋Ÿฐ์Šค
my $result = [
    map {
        $_->{bar};  #๊ฐ ๋ฐฐ์—ด์š”์†Œ(ํ•ด์‹œ๋ ˆํผ๋Ÿฐ์Šค)๋ฅผ ๋””๋ ˆํผ๋Ÿฐ์Šค
    }
    @{ $foo->return_array_ref }  #๋ฐฐ์—ด๋ ˆํผ๋Ÿฐ์Šค ๋ฐ˜ํ™˜
     # โ†‘ ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
];

์ถ”์ฒœ

  • ์–ด๋–ค ๋ณ€์ˆ˜๋กœ ์“ฐ๋Š” ๋ณ€์ˆ˜๋ช…์€ ๊ทธ ์ด์™ธ ์ž๋ฃŒํ˜• ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ฒƒ
    • ๊ตฌ๋ณ„์ด ์–ด๋ ต๋‹ค.
my @foo = (1, 2, 3);
my %foo = ( a => 1, b => 2, c => 3);
$foo[1], $foo{a}
# โ†‘ ์–ผํ•๋ณด๋ฉด ๋™์ผํ•œ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ ๊ฐ™์ด ํ˜ผ๋ˆ๋œ๋‹ค.
# ์‹ค์ œ๋กœ๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜
my $foo = [1, 2, 3];
my $foo = { a => 1, b => 2, c => 3};
# โ†‘ ๊ฐ™์€ ๋ณ€์ˆ˜์ด๋ฏ€๋กœ warning์ด ๋‚˜์˜จ๋‹ค.

์ถ”์ฒœ

ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋””๋ ˆํผ๋Ÿฐ์Šคํ•œ๋‹ค.

my $list = [1, 2, 3];
push @$list, 4;  # push๋Š” ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ๋ฐฐ์—ด์„ ๋ฐ›์œผ๋ฏ€๋กœ

๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์•„๋‹Œ ๋ฆฌ์ŠคํŠธ/ํ•ด์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•œ ๋•Œ

  • ์„œ๋ธŒ๋ฃจํ‹ด ์ธ์ˆ˜์ฒ˜๋ฆฌ
  • ์—ฌ๋Ÿฌ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ• ๋•Œ
sub hello {
  my ($arg1, $arg2, %other_args) = @_;
  return ($arg1, $arg2);
}
my ($res1, $res2) 
  = hello('hey', 'hoy', opt1 => 1, opt2 =>2);

๋ ˆํผ๋Ÿฐ์Šค ์ •๋ฆฌ

  • ์Šค์นผ๋ผ/๋ฐฐ์—ด/ํ•ด์‹œ์— ๋Œ€ํ•œ ์ฐธ์กฐ
  • ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ๊ตฌ์กฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ํ•„์ˆ˜
  • ํ‘œ๊ธฐ๋ฒ•์ด ๋‹ค์†Œ ๋ณต์žก
$ perldoc perlreftut
$ perldoc perlref

ํŒจํ‚ค์ง€

  • ๋„ค์ž„์ŠคํŽ˜์ด์Šค/์ด๋ฆ„๊ณต๊ฐ„
  • ๋ชจ๋“ˆ ๋กœ๋”ฉ ๋ฐฉ๋ฒ•
  • ํด๋ž˜์Šค(ํ›„์— ์„ค๋ช…)
package Hoge;
our $PACKAGE_VAL = 10;
# $HOGE::PACKAGE_VAL == 10

sub fuga {
}
# &Hoge::fuga;

1;

๋ชจ๋“ˆ ๋กœ๋”ฉ ๋ฐฉ๋ฒ•

use My::File;
# => My/File.pm ๊ฐ€ ๋กœ๋“œ๋จ
  • @INC(๊ธ€๋กœ๋ฒŒ ๋ณ€์ˆ˜)์— ์„ค์ •๋œ ๊ฒฝ๋กœ๋ฅผ ๊ฒ€์ƒ‰
use lib 'path/to/your/lib';
$ perl -Ipath/to/your/lib;
  • path/to/your/lib/My/File.pm ์„ ์ฐพ์•„์„œ ์žˆ์œผ๋ฉด ๋กœ๋”ฉ

์„œ๋ธŒ๋ฃจํ‹ด

&hello # ์„œ๋ธŒ๋ฃจํ‹ด ์ •์˜๋ถ€๋ถ„ ์ด์ „ ๊ด„ํ˜ธ์—†์ด ํ˜ธ์ถœํ•˜๋ ค๋ฉด &๋ฅผ ๋ถ™์—ฌ์•ผ ํ•œ๋‹ค.
sub hello {
  my ($name) = @_; # ํ˜ธ์ถœ์‹œ ์ธ์ˆ˜๊ฐ€ ์žˆ๋‹ค๋ฉด @_์— ์ž๋™์œผ๋กœ ์ „๋‹ฌ ์ธ์ˆ˜๋“ค์ด ๋“ค์–ด๊ฐ
  return "Hello, $name";
}
hello(); # ๊ด„ํ˜ธ๋ฅผ ๋ถ™์ด๋ฉด ์•ž๋’ค ์ƒ๊ด€์—†์Œ(์ •์„์ ์ธ ๋ฐฉ๋ฒ•)
hello; #์ •์˜ ํ›„ ๋ผ๋ฉด ๊ด„ํ˜ธ ์—†์–ด๋„ ํ˜ธ์ถœ๋จ

์ธ์ˆ˜์ฒ˜๋ฆฌ ๊ด€์šฉ๊ตฌ1

sub func1 {
  my ($arg1, $arg2, %args) = @_;  #ํ•ด์‹œ๋กœ ์ด๋ฆ„์žˆ๋Š” ์ธ์ˆ˜๋ฅผ ํ‰๋‚ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
  my $opt1 = $args{opt1};
  my $opt2 = $args{opt2};
}
func1('hoge', 'fuga', opt1 => 1, opt2 => 2);

์ธ์ˆ˜์ฒ˜๋ฆฌ ๊ด€์šฉ๊ตฌ2

sub func2 {
  my $arg1 = shift; # ๋ช…์‹œ์ ์œผ๋กœ ํ•˜๋ฉด shift @_;์ด๋‚˜ @_๋ฅผ ์ƒ๋žตํ•ด๋„ @_์—์„œ ์ฐจ๋ก€๋กœ ๊ฐ€์ ธ์˜ค๋ฏ€๋กœ ๊ด€๋ก€์ ์œผ๋กœ ์“ฐ๋Š” ํ‘œํ˜„
  my $arg2 = shift;
  my $args = shift; # ์—ฌ๊ธฐ๋Š” ์ต๋ช…ํ•ด์‹œ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๋“ค์–ด์˜จ๋‹ค.
  # ์œ„ 3์ค„์€ my ($arg1, $arg2, $args) = @_; ๋กœ ํ•ด๋„ ๋œ๋‹ค.
  my $opt1 = $args->{opt1};
  my $opt2 = $args->{opt2};
}
func2('hoge', 'fuga', {opt1 => 1, opt2 => 2});

์ธ์ˆ˜์ฒ˜๋ฆฌ ๊ด€์šฉ๊ตฌ3

sub func3 { shift->{arg1} } # shiftํ•œ ์ธ์ˆ˜์— ๋Œ€ํ•ด ๋ฐ”๋กœ ์ ์šฉ, func3({arg1 => 2}) ์ด๋Ÿฐ์‹์œผ๋กœ ํ˜ธ์ถœํ–ˆ์„๋•Œ?
sub func4 { $_[0]->{arg1} } # @_ ์˜ ์ฒซ์งธ ์š”์†Œ๋Š” $_[0](@a์˜ ์ฒซ์งธ์š”์†Œ๋Š” $a[0]์ธ ๊ฒƒ๊ณผ ๊ฐ™์€ ์ด์น˜)

์„œ๋ฒ„๋ฃจํ‹ด์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค

  • ํŒจํ‚ค์ง€๋‚ด์— ์ •์˜
package Greetings;
sub hello { }
1;

# hello ๋Š” &Greetings::hello(); ๋กœ ์ •์˜๋œ๋‹ค.
  • ์„œ๋ฒ„๋ฃจํ‹ด ์ •์˜๋ฅผ ์ค‘์ฒฉํ•ด๋„ ์ƒ์œ„๋„ค์ž„์ŠคํŽ˜์ด์Šค(ํŒจํ‚ค์ง€)์— ์ •์˜๋จ. ์ฃผ์˜
package Greetings;
sub hello { 
  sub make_msg { }
  sub print {}
  print (make_msg() );
}
1;

# &Greetings::hello();
# &Greetings::make_msg();
# &Greetings::print();

Perl์—์„œ ๋””๋ฒ„๊น…

  • use Data::Dumper; ์„ ํ”ํžˆ ์‚ฌ์šฉํ•œ๋‹ค.
use Data::Dumper;
print Dumper($value); # ์Šค์นผ๋ผ๊ฐ’์„ ๋„ฃ๋Š”๊ฒŒ ์ข‹๋‹ค. ๋ฐฐ์—ด์ด๋ฉด \@array ์ด๋Ÿฐ์‹์œผ๋กœ ์Šค์นผ๋ผ๊ฐ’(๋ ˆํผ๋Ÿฐ์Šค)์œผ๋กœ ๋งŒ๋“ค์–ด์„œ
  • ์—๋””ํ„ฐ์˜ ๋งคํฌ๋กœ์— ์ •์˜ํ•ด ๋‘๊ณ  ์“ฐ๋ฉด ์œ ์šฉ

Perl ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์งˆ๋ฌธ

  • ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•œ์ ์ด ์žˆ์Šต๋‹ˆ๊นŒ?
    • Perl์ด์™ธ ์–ธ์–ด ํฌํ•จ

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ถ”์ƒํ™”์˜ ์—ญ์‚ฌ

  • ์ถ”์ƒํ™”๋ž€
๋ณต์žกํ•œ ์ž๋ฃŒ, ๋ชจ๋“ˆ, ์‹œ์Šคํ…œ ๋“ฑ์œผ๋กœ๋ถ€ํ„ฐ ํ•ต์‹ฌ์ ์ธ ๋ถ€๋ถ„์„ ๊ฐ„์ถ”๋ ค ๋‚ด๋Š” ๊ฒƒ (Wikipedia๋ฐœ์ทŒ)
  • ํ•œ๋ฒˆ์— ์ƒ๊ฐํ•˜๊ณ  ๊ณ ๋ คํ•ด์•ผ ๋˜๋Š” ๋ถ€๋ถ„์„ ์ค„์–ด์ค€๋‹ค.
    • ๋ฒ”์œ„๋ฅผ ์ขํ˜€์ค€๋‹ค.
    • ์œ ์ง€๋ณด์ˆ˜์„ฑ/์žฌํ™œ์šฉ์„ฑ์„ ๋†’์ธ๋‹ค.

๋น„๊ตฌ์กฐ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์‹œ๋Œ€

  • gotoํ”„๋กœ๊ทธ๋ž˜๋ฐ
    • ์ œ์–ด์˜ ํ๋ฆ„์ด ์™„์ „ ์ž์œ ๋กœ์›€
  • Perl์—์„œ gotoํ”„๋กœ๊ทธ๋ž˜๋ฐ ์˜ˆ(fizzbuzz)
my $i = 1;
START:
    goto "END" if $i > 35;

    goto "PRINT_FIZZBUZZ" if $i % 15 == 0;
    goto "PRINT_FIZZ"     if $i %  3 == 0;
    goto "PRINT_BUZZ"     if $i %  5 == 0;
    goto "PRINT_NUM";

PRINT_NUM:_
    print $i;
    goto "PRINT_NL";

PRINT_FIZZ:_
    print "fizz";
    goto "PRINT_NL";

PRINT_BUZZ:_
    print "buzz";
    goto "PRINT_NL";

PRINT_FIZZBUZZ:_
    print "fizzbuzz";
    goto "PRINT_NL";

PRINT_NL:_
    print "\n";

    $i++;
    goto "START";

END:

๋น„๊ตฌ์กฐ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๋ฌธ์ œ

  • ์ œ์–ด์˜ ํ๋ฆ„์„ ์ดํ•ดํ•˜๊ธฐ ํž˜๋“ค๋‹ค.
    • ํ”„๋กœ๊ทธ๋žจ ์ „์ฒด๋ฅผ ํ•œ๋ฒˆ์— ์ดํ•ดํ•˜์ง€ ์•Š์œผ๋ฉด ์•ˆ๋œ๋‹ค.
    • ๋Œ€๊ทœ๋ชจ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ํž˜๋“ค๋‹ค.
  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์ด ํž˜๋“ค๋‹ค.

EW Dijkstra(1968). Go to statement considered harmful

๊ตฌ์กฐ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ

  • ์ˆœ์ฐจ, ์„ ํƒ, ๋ฐ˜๋ณตํ‘œํ˜„
  • ์„œ๋ธŒ๋ฃจํ‹ด์— ์˜ํ•ด ํ–‰์œ„๋ฅผ ์ถ”์ƒํ™”
sub fizzbuzz {
    my $i = 1;

    while ($i < 35) {
        if ($i % 15 == 0) {
            print "fizzbuzz";
        }
        elsif ($i % 3 == 0) {
            print "fizz";
        }
        elsif ($i % 5 == 0) {
            print "buzz";
        }
        else {
            print $i;
        }
        print "\n";
        $i++;
    }
}
fizzbuzz();

๊ตฌ์กฐ์  ํ”„๋กœ๊ทธ๋žจ๋ฐ๋งŒ ์ด์šฉํ•  ๋•Œ ๋ฌธ์ œ

  • ํ–‰์œ„์™€ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ด€๊ณ„๊ฐ€ ๋ถ„๋ฆฌ๋จ
open my $fh, '<', $filename;
while (my $line = readline($fh)) {
  print $line;
}
close $fh;
  • $fh์— ๋Œ€ํ•ด ์–ด๋–ค ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
  • open/close/readline ์œผ๋กœ ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?
    • ๋ฐ์ดํ„ฐ, ํ–‰์œ„ ๊ฐ๊ฐ์˜ ๋ฒ”์œ„๊ฐ€ ๋„“๋‹ค.

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

  • ๊ฐ์ฒด์˜ ์ถ”์ƒํ™”

  • ๊ฐ์ฒด๋Š”

    • ํ”„๋กœ๊ทธ๋žจ์˜ ๋Œ€์ƒ์ด ๋˜๋Š” ๋ฌผ๊ฑด
    • ๋ฐ์ดํ„ฐ + ํ–‰์œ„
  • ํ”„๋กœ๊ทธ๋žจ์€ ๊ฐ์ฒด๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ

  • "์–ด๋–ป๊ฒŒ"๋ณด๋‹ค๋Š” "๋ฌด์—‡์ด ์–ด๋–ป๊ฒŒ"์— ์ฃผ๋ชฉ

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ์ข‹์€์ 

  • ์ฒ˜๋ฆฌ์˜ ๋Œ€์ƒ(๋ฐ์ดํ„ฐ)์™€ ์ฒ˜๋ฆฌ๋‚ด์šฉ(ํ–‰์œ„)๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค.
    • ๊ฐ์ฒด๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•œ๋‹ค.
    • ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๊ฐ์ฒด๋ผ๋Š” ๋น„์œ ๊ฐ€ ์ธ๊ฐ„์—๊ฒŒ ์ต์ˆ™ํ•˜๋‹ค.
    • => ๋””์ž์ธํ•˜๊ธฐ ์‰ฝ๋‹ค.

์˜ˆ

use IO::File;
my $file = IO::File->new($filename, 'r');
while (my $line = $file->getline) {
  print $line;
}
$flie->close;
  • $file์— ๋Œ€ํ•œ ๋ชจ๋“  ํ–‰์œ„๊ฐ€ ๋ฉ”์†Œ๋“œ๋กœ ์ •์˜๋˜์–ด ์žˆ์Œ.

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ˜„

  • ๊ฐ์ฒด ๊ฐ„์˜ ์ƒํ˜ธ ์ž‘์šฉ / ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ
  • ๊ฐ์ฒด ๊ฐ„์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ํ‘œํ˜„ํ•˜๊ธฐ ์‰ฝ๋„๋ก ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ์ง€์›
    • ํด๋ž˜์Šค์™€ ์ธ์Šคํ„ด์Šค
    • ์บก์Šํ™”
    • ์ƒ์†
    • ๋‹คํ˜•์„ฑ
    • ๋™์  ๋ฐ”์ธ๋”ฉ

์ฃผ์ œ

Perl ํด๋ž˜์Šค์™€ ์ธ์Šคํ„ด์Šค

      ํด๋ž˜์Šค : [๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์ •์˜ + ํ–‰์œ„ ์ •์˜]
                       โ†“ใ€€์ƒ์„ฑ
์ธ์Šคํ„ด์Šค : [{data} + ํ–‰์œ„์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค(์ฐธ์กฐ)] 
  • ํด๋ž˜์Šค: ํŒจํ‚ค์ง€
  • ๋ฉ”์†Œ๋“œ: ํŒจํ‚ค์ง€์— ์ •์˜ ๋œ ํ•จ์ˆ˜
  • ๊ฐ์ฒด: ํŠน์ • ํŒจํ‚ค์ง€์— bless() ๋œ ๋ ˆํผ๋Ÿฐ์Šค

ํด๋ž˜์Šค ์ •์˜(ํด๋ž˜์Šค ์ด๋ฆ„)

  • ๊ณผ์ œ๋กœ ๋‚˜์˜จ Sorter ํด๋ž˜์Šค(๊ฐ„๋žต ํŒ)

์•„๋ž˜๋ฅผ Sorter.pm ์ด๋ž€ ํŒŒ์ผ๋กœ ๋งŒ๋“ค์ž

# ํŒจํ‚ค์ง€ ์ ˆ์ฐจ๋ฅผ ์ •์˜
package Sorter; # ํด๋ž˜์Šค ์ด๋ฆ„
use strict;
use warnings;

# ์ฝ”๋“œ ๊ณ„์†

ํด๋ž˜์Šค ์ •์˜ (์ƒ์„ฑ์ž / ํ•„๋“œ)

# ์ƒ์„ฑ์ž
# Sorter->new; ์ฒ˜๋Ÿผ ํ˜ธ์ถœ, ์ด๋ ‡๊ฒŒ ํ˜ธ์ถœํ•˜๋ฉด ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ Sorter๊ฐ€ ๋„˜์–ด๊ฐ„๋‹ค.
# Sorter->new;๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ Sorter::new('Sorter') ์ฒ˜๋Ÿผ ํ˜ธ์ถœ๋œ๋‹ค. ์ฒซ๋ฒˆ์žฌ ์ธ์ž๋กœ ํด๋ž˜์Šค ์ด๋ฆ„์ด ๋„˜์–ด๊ฐ€๋Š” ์ด์œ 
sub new {
    my ($class) = @_; # ํด๋ž˜์Šค์ด๋ฆ„(์ด ๊ฒฝ์šฐ์— Sorter)์ด ๋“ค์–ด๊ฐ
    # ๋ฐ์ดํ„ฐ๋ฅผ ์ค€๋น„ํ•œ๋‹ค.
    my $data_structure = {
        values => [],
    };
    # ํ–‰์œ„(= ํŒจํ‚ค์ง€)์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š”
    my $self = bless $data_structure, $class; # $data_structure๋ฅผ $class์ด๋ฆ„(Sorter)๋กœ ํ…Œ๊น…ํ•˜์—ฌ ๊ฐ์ฒดํ™”
    return $self;    # $self๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์จ๋„ ๋˜์ง€๋งŒ python์—์„œ ์ฒ˜๋Ÿผ ๊ด€์šฉ์ ์œผ๋กœ self๋กœ ์“ด๋‹ค.                    
}
# ์œ„์—์„œ bless๋Š” ํด๋ž˜์Šค ์ด๋ฆ„์„ $data_structure์— ํ…Œ๊น…ํ•˜์—ฌ ๊ทธ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ฆฌํ„ดํ•˜๋ฏ€๋กœ
# ๊ฒฐ๊ตญ bless๋œ $data_sturcture์™€ $self๋Š” ๊ฐ™๋‹ค. 
# bless ํ•˜๊ธฐ์ „์— ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์•Œ์•„๋ณด๋Š” ref ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ print ref $data_structure ํ•˜๋ฉด HASH ๋ผ๊ณ  ๋‚˜์˜ค์ง€๋งŒ
# bless ํ•ด์„œ ๊ฐ์ฒดํ™” ํ•œ ํ›„์—๋Š” ์ฐ์–ด๋ณด๋ฉด Sorter๊ฐ€ ๋‚˜์˜จ๋‹ค.
# ์œ„ ์ฝ”๋“œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์จ๋„ ๋˜‘๊ฐ™๋‹ค. ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๋ฉด ์–ด๋–ค ๋ชจ์–‘์ด๋“  ํ˜ผ๋ˆ์•ˆ๋จ

# ๊ฐ€์žฅ ๋„๋ฆฌ ์“ฐ์ด๋Š” ํ˜•ํƒœ
# sub new {
#     my ($class) = @_;
#     my $self = {
#         values => [],
#     };
#     bless $self, $class;
#     return $self;                     
# }

# ๊ทน๋„๋กœ ์ค„์ด๋ฉด?
# sub new {
#     return bless { values => [] }, shift;
# }

# ์ฝ”๋“œ ๊ณ„์†

ํด๋ž˜์Šค ์ •์˜ (๋ฉ”์†Œ๋“œ)

# $sorter->set_values(0,1,2,3) ์™€ ๊ฐ™์ด ํ˜ธ์ถœ
# ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” Sorter::set_values($sorter,0,1,2,3)์ฒ˜๋Ÿผ ํ˜ธ์ถœ๋œ๋‹ค. ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜์— $sorter๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ์ด์œ 
sub set_values {
    my ($self, @values) = @_; # $self์—๋Š” $sorter๊ฐ€ ๋“ค์–ด๊ฐ
    $self->{values} = [@values];
    return $self;
}

sub get_values {
    my ($self) = @_;

    return @{ $self->{values} };
} 

sub sort {
    my ($self) = @_;
   
    $self->{values} = [ sort { $a <=> $b } @{ $self->{values} } ];
}  

1; # ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ํŒจํ‚ค์ง€ ๋ชจ๋“ˆ์„ ๋งŒ๋“ค๊ฒฝ์šฐ ์ž˜ ๋กœ๋”ฉ๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•ด ํŒŒ์ผ ๋์— ์ฐธ(true)๊ฐ’์„ ๋„ฃ์Œ

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ Sorter.pm

ํด๋ž˜์Šค์˜ ์‚ฌ์šฉ

use Sorter;

my $sorter = Sorter->new;
$sorter->set_values(5,4,3,2,1);

ํ•œ ํŒŒ์ผ ์•ˆ์—์„œ ํด๋ž˜์Šค์™€ ๋ฉ”์ธ์ฝ”๋“œ๋ฅผ ๊ฐ™์ด ๋„ฃ์–ด ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋ ค๋ฉด?

package Sorter;
...

# ๋ณ„๋„์˜ .pm ํŒŒ์ผ์ด ์•„๋‹ˆ๋ผ ๋์— 1;์€ ํ•„์š”์—†๊ณ  ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๊ฐ€ ์„ ์–ธ๋˜๋ฉด ํ•ด๋‹นํŒจํ‚ค์ง€ ์˜์—ญ์€ ๋๋‚œ๋‹ค. 
package main;   # ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰์‹œ์ž‘๋˜๋Š” ๊ธฐ๋ณธ ํŒจํ‚ค์ง€๋Š” mainํŒจํ‚ค์ง€
# ์ด๋ฏธ SorterํŒจํ‚ค์ง€๊ฐ€ ํ•œํŒŒ์ผ ์•ˆ์— ์žˆ์–ด ๋กœ๋”ฉ๋œ ์ƒํƒœ์ด๋ฏ€๋กœ ๋”ฐ๋กœ use Sorter;๋ฅผ ํ•ด์ค„ ํ•„์š”๋Š” ์—†๋‹ค.
my $sorter = Sorter->new;
$sorter->set_values(5,4,3,2,1);

ํŒจํ‚ค์ง€์˜์—ญ์€ ํ•ด๋‹น ํŒจํ‚ค์ง€๊ฐ€ ์„ ์–ธ๋œ ๋ ‰์‹œ์ปฌ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ์ข…๋ฃŒ๋˜๋ฏ€๋กœ ๋ธ”๋Ÿญ { }์œผ๋กœ ๋ฌถ์–ด์„œ ์ด๋ ‡๊ฒŒ ํ•ด๋„ ๋œ๋‹ค.

# ์—ฌ๊ธฐ๋Š” ๊ธฐ๋ณธ main ํŒจํ‚ค์ง€ ์˜์—ญ
{
   package Sorter;
   ...
}
# ๋‹ค์‹œ ๊ธฐ๋ณธ main ์˜์—ญ
# { }์— ์˜ํ•ด ์—ฌ๊ธฐ์„œ๋Š” ๋ช…์‹œํ•˜์—ฌ ํŒจํ‚ค์ง€๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š์•„๋„ main์˜์—ญ์ž„
# ๋ธ”๋Ÿญ์œผ๋กœ ๋ฌถ์œผ๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๊ฐ„์˜ ๋ ‰์‹œ์ปฌ์˜์—ญ์„ ํ™•์‹คํžˆ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋‚ด๋ถ€๋ณ€์ˆ˜๋“ฑ์˜ ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ์ด ์ค„์–ด๋“ ๋‹ค. 
my $sorter = Sorter->new;
$sorter->set_values(5,4,3,2,1);

์ƒ์„ฑ์ž

  • ์ƒ์„ฑ์ž๋Š” ์ˆ˜๋™์œผ๋กœ(๊ด€๋ก€์ ์œผ๋กœ new๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ) ์ •์˜
  • ๊ฐ์ฒด๋ฅผ ์Šค์Šค๋กœ ๋งŒ๋“ฆ
  • new()
    • ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ํด๋ž˜์Šค(ํŒจํ‚ค์ง€)์ด๋ฆ„์œผ๋กœ bless๋ฅผ ํ†ตํ•ด ํ…Œ๊น…ํ•˜์—ฌ ๋ฐ˜ํ™˜
  • bless์€ ๋ฐ์ดํ„ฐ์™€ ํ–‰์œ„(๋ฉ”์†Œ๋“œ)๋ฅผ ๋ฌถ๋Š” ์ž‘์—…
  my $self = bless { field => 1 }, "Sorter";

ํด๋ž˜์Šค ๋ฐ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ

  • ๋ฌธ๋ฒ•์ ์ธ ์ฐจ์ด๋Š” ์—†๋‹ค.
  • ์ •์˜์‹œ: ์ œ1์ธ์ˆ˜๋ฅผ $class๋กœ ํ• ์ง€ $self๋กœ ํ• ์ง€
  • ํ˜ธ์ถœ์‹œ: ํด๋ž˜์Šค์—์„œ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ์ธ์Šคํ„ด์Šค๊ฐ์ฒด์—์„œ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜.
Class->method($arg1, $arg2);
&Class::method("Class", $arg1, $arg2);

$object->method($arg1, $arg2);
&Class::method($object, $arg1, $arg2);

ํ•„๋“œ

  • 1์ธ์Šคํ„ด์Šค์— 1๋ฐ์ดํ„ฐ(๋ ˆํผ๋Ÿฐ์Šค)
  • ์—ฌ๋Ÿฌ ํด๋ž˜์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์‹ถ๋‹ค๋ฉด ํ•ด์‹œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ bless ํ•จ.(๋“œ๋ฌผ๊ฒŒ ์“ฐ์ง€๋งŒ ์Šค์นผ๋ผ ๋ ˆํผ๋Ÿฐ์Šค,๋ฐฐ์—ด ๋ ˆํผ๋Ÿฐ์Šค๋„ bless๊ฐ€๋Šฅํ•จ)
my $self = bless {
    filed1 => $obj1,
    field2 => [],
    field3 => {},
}, $class;

์บก์Šํ™”

  • ๊ณต๊ฐœ์—ฌ๋ถ€ ์ง€์ •(public/private๋“ฑ) ์€ ์—†๋‹ค.
    • ๋ชจ๋‘ public
  • ๋ช…๋ช…๊ทœ์น™์œผ๋กœ ๊ด€๋ก€์ ์œผ๋กœ ๊ณต๊ฐœ์—ฌ๋ถ€๋ฅผ ๊ตฌ๋ณ„ํ•œ๋‹ค.(python ์ฒ˜๋Ÿผ)
sub public_method {
  my $self = shift;
}

sub _private_method {
  my $self = shift;
}
  • ํ•„์š”ํ•˜๋‹ค๋ฉด ์™„์ „ํžˆ ์ˆจ๊ธฐ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๊ธดํ•˜๋‹ค.(ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉ)

์ƒ์†

  • use parent; ์‚ฌ์šฉ(์•ฝ๊ฐ„ ๋™์ž‘์ด ๋‹ค๋ฅด๊ธด ํ•˜์ง€๋งŒ use base;๋„ ์”€)
package Me;
use parent 'Father';
1;
  • ๋ถ€๋ชจํด๋ž˜์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ
    • SUPER
sub new {
  my ($class) = @_;
  my $self = $class->SUPER::new();  # ๋ถ€๋ชจํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ
  return $self;
}

๋‹ค์ค‘์ƒ์†

  • Mixin๊ฐ™์€ ๊ฑธ ํ•˜๊ณ ์‹ถ์„๋•Œ ์‚ฌ์šฉ
  • ๋‚จ์šฉํ•˜๋ฉด ์˜คํžˆ๋ ค ์•ˆ์ข‹์Œ
package Me;
use parent qw/Father Mother/; # ํƒ์ƒ‰์ˆœ์„œ ์ขŒ->์šฐ
1;
  • ๋ฉ”์†Œ๋“œ ๊ฒ€์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • Class::C3
    • Next

๊ฐ์ฒด์ง€ํ–ฅ ์ •๋ฆฌ

UNIVERSAL

  • Java์˜ Object ๊ฐ™์€๊ฒƒ
  • UNIVERSAL์— ์ •์˜๋œ ๊ฒƒ์€ ์–ด๋–ค ๊ฐ์ฒด์—์„œ๋„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
  • isa()
my $dog = Dog->new(); 
$dog->isa('Dog');    # true 
$dog->isa('Animal'); # true 
$dog->isa('Man');    # false 
  • can()
my $bark = $dog->can('bark'); 
$man->$bark();

AUTOLOAD

  • ํ˜ธ์ถœํ•œ ๋ฉ”์†Œ๋“œ๊ฐ€ My::Class์— ์—†๋Š” ๊ฒฝ์šฐ

    • My::Class::AUTOLOAD๋ฉ”์†Œ๋“œ ๊ฒ€์ƒ‰
    • ๋ถ€๋ชจํด๋ž˜์Šค์˜ AUTOLOAD๋ฉ”์†Œ๋“œ ๊ฒ€์ƒ‰
    • UNIVERSAL::AUTOLOAD ๊ฒ€์ƒ‰
    • ๋ชป์ฐพ์œผ๋ฉด ์˜ค๋ฅ˜
  • AUTOLOAD๋Š” ์ •์˜ ๋˜์ง€์•Š์€ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ• ์‹œ ํ˜ธ์ถœ๋จ

  • Ruby ์˜ method_missing

AUTOLOAD

  • ํ•„๋“œ๋ฅผ ๋™์ ์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ณ 
  • ์˜ˆ์ธกํ•˜๊ธฐ ํž˜๋“  ํ–‰๋™์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋˜๋„๋ก ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.
    • ์ด๋Ÿฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฑด ์ดํ•ดํ•ด ๋‘์ž
package Foo;

sub new { bless {}, shift }

our $AUTOLOAD;
sub AUTOLOAD {
    my $method = $AUTOLOAD;
    return if $method =~ /DESTROY$/;
    $method =~ s/.*:://;
    {
        no strict 'refs';
        *{$AUTOLOAD} = sub {
            my $self = shift;
            sprintf "%s method was called!", $method;
        };
    }
    goto &$AUTOLOAD;
}

1;

์—ฐ์‚ฐ์ž ์˜ค๋ฒ„๋กœ๋“œ

  • ์˜ˆ์ธกํ•˜๊ธฐ ํž˜๋“  ํ–‰๋™์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋˜๋„๋ก ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.
    • ์ด๋Ÿฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฑด ์ดํ•ดํ•ด ๋‘์ž
  • URI
my $uri = URI->new('http://exapmle.com/');
... do something ...
print "URI is $uri";
  • DateTime
$new_dt = $dt + $duration_obj;
$new_dt = $dt - $duration_obj;
$duration_obj = $dt - $new_dt;
for my $dt (sort @dts) {          # sort๋‚ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” <=> ์—ฐ์‚ฐ์ž๊ฐ€ ์˜ค๋ฒ„๋กœ๋“œ ๋˜์–ด์žˆ์Œ
    ...
}

ํด๋ž˜์Šค ๋นŒ๋“œ

  • Perl์˜ ๊ฐ์ฒด์ง€ํ–ฅ์€ ์ˆ˜๋™์œผ๋กœ ๋งŒ๋“œ๋Š” ๋Š๋‚Œ์ด ๊ฐ•ํ•˜๋‹ค.

    • new๋„ ์Šค์Šค๋กœ ๋งŒ๋“ ๋‹ค.
    • ํ•„๋“œ ์ ‘๊ทผ์ž๋„ ์Šค์Šค๋กœ ์ •์˜
  • ๋ฒˆ๊ฑฐ๋กญ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™ํ™”์‹œ์ผœ์ฃผ๋Š” ๋ชจ๋“ˆ๋“ค์ด ์กด์žฌํ•œ๋‹ค.

Class::Accessor::Fast

  • ์ƒ์„ฑ์ž/์ ‘๊ทผ์ž๋ฅผ ์ž๋™์œผ๋กœ ์ •์˜ํ•ด์ฃผ๋Š” ๋ชจ๋“ˆ
  • ์š”์ฆ˜์€ Moose, Moo, Mouse๋ผ๋Š” ๋ชจ๋“ˆ๋•Œ๋ฌธ์— ์ž˜ ์“ฐ์ง€ ์•Š์œผ๋‚˜, ๊ฐ„๋‹จํ•œ ์šฉ๋„๋กœ ๋งŽ์ด ์“ฐ์˜€์Œ.

before

package Foo;

sub new {
    bless {
        foo => undef,
        bar => undef,
        baz => undef,
    }, shift
}

sub foo {
    my $self = shift;
    $self->{foo} = $_[0] if defined $_[0];
    $self->{foo};
}

sub bar {
    my $self = shift;
    $self->{bar} = $_[0] if defined $_[0];
    $self->{bar};
}

sub baz{
    my $self = shift;
    $self->{baz} = $_[0] if defined $_[0];
    $self->{baz};
}

1;

after

์œ„ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

package Foo;

use parent qw/Class::Accessor::Fast/;
__PACKAGE__->mk_accessors(qw/foo bar baz/);  # Ruby์˜ attr_accessor์™€ ๋น„์Šท?

1;

Class::Data::Inheritable

  • ์ƒ์†๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค๋•Œ
use parent qw/Class::Data::Inheritable/;
__PACKAGE__->mk_classdata(dsn => 'dbi:mysql:dbname=foo');
1;

ํ•ฉ์ณ์„œ ์“ฐ์ด๋Š” ํ˜•ํƒœ ์˜ˆ

package UsualClass;
use parent qw/Class::Accessor::Fast Class::Data::Inheritable/;
__PACKAGE__->mk_classdata(hoge => "classdata");
__PACKAGE__->mk_accessors(qw(foo bar baz));

# ๋ฉ”์†Œ๋“œ ๋“ฑ ์ •์˜

1;

๋‹ค๋ฅธ ํด๋ž˜์Šค ๋นŒ๋“œ ๋ชจ๋“ˆ๋“ค.

  • ํ˜„๋Œ€์ ์ธ ๊ฐ์ฒด์ง€ํ–ฅ์„ ์‹คํ˜„ํ•˜๋Š” ๋ชจ๋“ˆ

  • ์œ ์—ฐํ•˜๊ณ  ์•ˆ์ „ํ•œ ์ ‘๊ทผ์ž๋ฅผ ์ƒ์„ฑ

  • ํƒ€์ž…์‹œ์Šคํ…œ ๋„์ž…

  • Role์— ์˜ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ง€ํ–ฅ ์„ค๊ณ„

  • ์†Œ๊ทœ๋ชจ์— ์“ฐ๊ธฐ์—” ๋‹ค์†Œ ๋ฉ์น˜๊ฐ€ ํฌ๊ณ  ๋ณต์žกํ•˜๋‹ค.

  • Moose์˜ ๊ฒฝ๋Ÿ‰๋ฒ„์ ผ
    • Moose์˜ ์ดˆ๊ธฐ๋กœ๋”ฉ ์‹œ๊ฐ„์— ์ข€ ๊ฑธ๋ฆฌ๋Š”๊ฒƒ์— ๋น„ํ•ด ๊ฐ€๋ฒผ์›€
    • Moose์— ๋น„ํ•ด ๊ธฐ๋Šฅ์€ ์ผ๋ถ€ ์ œํ•œ์ 
  • Moose์˜ ๊ฒฝ๋Ÿ‰๋ฒ„์ ผ
    • ๊ฐ€๋ฒผ์šด Moose๋ฅผ ์›ํ•  ๊ฒฝ์šฐ ์š”์ฆ˜ Moose๋Œ€์‹ ์— ๋งŽ์ด ์“ด๋‹ค.
    • Mouse๋งŒํผ ๊ฐ€๋ณ๋‹ค.
    • Moose์™€ ๊ฐ™์ด ์‚ฌ์šฉ์‹œ ํ•„์š”์‹œ Moose๊ฐ์ฒด๋กœ ์ž๋™ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•ด์คŒ.

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋žจ์˜ ์ž‘์„ฑ์š”๋ น

  • ๋“ฑ์žฅ์ธ๋ฌผ์„ ์ƒ๊ฐ = ๊ฐ์ฒด
  • ๋“ฑ์žฅ์ธ๋ฌผ์ด ๊ฐ๊ฐ ์–ด๋– ํ•œ ์ฑ…์ž„(responsibility)์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š”์ง€ ์ƒ๊ฐํ•œ๋‹ค.
  • ์ฑ…์ž„์— ๋งž์ถ”์–ด ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•˜๋„๋ก ํ•˜๊ธฐ
    • "์บก์Šํ™”์—์„œ ์ƒ์†์—์„œ ๋‹คํ˜•์„ฑ์ด...."๋“ฑ๋“ฑ ๋„ˆ๋ฌด ๋ณต์žกํ•˜๊ฒŒ ์ƒ๊ฐํ•  ํ•„์š”๋Š” ์—†๋‹ค.
    • ๋ณด๋‹ค ์ข‹์€, ์‰ฝ๊ฒŒ ๋ฌธ์ œ๋ฅผ ๋ชจ๋ธ๋ง ํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ

์ฑ…์ž„(Responsibility)์ด๋ž€๏ผŸ

  • ๊ฐ์ฒด์˜ ์ด์šฉ์ž, ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ณณ๊ณผ์˜ ์•ฝ์†
    • ์ฑ…์ž„์ด ์—†๋Š” ๊ฒƒ์€ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค
    • ์ฑ…์ž„์ด ์—†๋Š” ๊ฒƒ์€ ํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค
  • ์ฑ…์ž„์„ ๊น”๋”ํ•˜๊ฒŒ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์œผ๋กœ ๊น”๋”ํ•˜๊ฒŒ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ์ฒด์ง€ํ–ฅ ์ •๋ฆฌ

  • ์ง์ ‘ ๋งŒ๋“  ๋Š๋‚Œ์ด ๋ฌผ์”ฌ ๋‚˜๋Š” ๊ฐ์ฒด์ง€ํ–ฅ
    • package ์— ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜
    • bless ๋กœ ๋ฐ์ดํ„ฐ(๋ ˆํผ๋Ÿฐ์Šค)๋ฅผ ๋ฌถ๋Š”๋‹ค
    • ์ƒ์„ฑ์ž๋Š” ์Šค์Šค๋กœ ๋งŒ๋“ ๋‹ค
    • ๊ฐ์ฒด์ง€ํ–ฅ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๊ธฐ ์šฉ์ดํ•˜๋„๋ก ํฌ์žฅ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์“ฐ์ž

ํ…Œ์ŠคํŠธ๋Š” ์ค‘์š”ํ•˜๋‹ค

  • ํ”„๋กœ๊ทธ๋žจ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ• [๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ ๊ฐœ์„ ๊ฐ€์ด๋“œ๋กœ๋ถ€ํ„ฐ]
    • ๊ณ ์น˜๊ณ  ๊ธฐ๋„ํ•œ๋‹ค
    • ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ์จ์„œ ๋ณดํ˜ธํ•˜๊ณ  ๋ณ€๊ฒฝํ•œ๋‹ค

์™œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ์“ฐ๋Š” ๊ฑด๊ฐ€?

  • ํ…Œ์ŠคํŠธ๊ฐ€ ์—†์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ์ œ๋Œ€๋กœ ์›€์ง์ธ๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์—†๋‹ค

  • ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์น˜๋ช…์ 

    • ์˜›๋‚ ์— ์“ด ์ฝ”๋“œ๋Š” ์ง€๊ธˆ๋„ ์›€์ง์ด๊ณ  ์žˆ๋Š”๊ฐ€?
    • ์ƒˆ๋กœ์šด ์ฝ”๋“œ์™€ ์˜› ์ฝ”๋“œ์˜ ์ •ํ•ฉ์„ฑ์€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๊ฐ€?
    • ์ œ๋Œ€๋กœ๋œ ์‚ฌ์–‘/์˜๋„๊ฐ€ ๋ฌด์—‡์ด์—ˆ๋Š”์ง€ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ๋Š”๊ฐ€?
  • Perl ์ฒ˜๋Ÿผ ํƒ€์ž…์ด ์—†๋Š” ๋™์ ์ธ ์–ธ์–ด์—์„œ๋Š” ํŠนํžˆ ์ค‘์š”

  • ๊ธฐ๋„ํ•˜์ง€ ๋ง๊ณ  ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ์“ฐ์ž

๋ฌด์—‡์„ ํ…Œ์ŠคํŠธํ•  ๊ฒƒ์ธ๊ฐ€

  • ์ •์ƒ์ ์ธ ์ฒ˜๋ฆฌ

  • ๋น„์ •์ƒ์ ์ธ ์ฒ˜๋ฆฌ

  • ๊ทธ ๊ฒฝ๊ณ„

  • 100% ์ปค๋ฒ„ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๋‹ค

    • ๋ช…๋ น๋ฌธ ๋ง๋ผ(C0)/๋ถ„๊ธฐ๋ง๋ผ(C1)/์กฐ๊ฑด๋ง๋ผ(C2)
    • C2 ๋Š” ์ •๋ง ํฐ์ผ
  • ํ•„์š”/์œ„ํ—˜ํ•˜๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋Š” ๊ณณ๋ถ€ํ„ฐ ์“ฐ๊ณ  ์กฐ๊ธˆ์”ฉ ๋ณด์™„ํ•ด๋‚˜๊ฐ„๋‹ค.

Perl ๋กœ Test

  • Test::More
  • Test::Fatal
  • Test::Class

Test::More

use Test::More;

subtest 'topic' => sub {
  use_ok    'Foo::Bar';
  isa_ok    Foo::Bar->new, 'Foo::Bar';
	ok        $something_to_be_bool;
	is        $something_to_be_count, 5;
	is_deeply $something_to_be_complicated, {
	    foo => 'foo',
	    bar => [qw(bar baz)],
	};
};

done_testing;

Test::Fatal

use Test::Fatal;

ok( exception{ $foo->method }, '์˜ˆ์™ธ๋ฅผ ๋˜์ง„๋‹ค');
like( exception { $foo->method },  qr/division by zero/, '0 ๋‚˜๋ˆ—์…ˆ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค');
isa_ok( exception { $foo->method }, 'Some::Exception::Class', '์˜ˆ์™ธ ํด๋ž˜์Šค๊ฐ€ ๋˜์ ธ์ง„๋‹ค');

Test::Class

  • ๋ฉ”์†Œ๋“œ๋กœ ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ๋‚˜๋ˆˆ๋‹ค

  • xUnit๊ณ„์—ด

  • Sorter ์˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋ด!

๊ทธ ์™ธ

Test::Name::FromLine

  • ์ด๋ฆ„์ด ๋ถ™์ง€ ์•Š์€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ณด๊ธฐ ์ข‹๊ฒŒ ํ‘œ์‹œํ•ด์ค€๋‹ค

Test::Most

  • ํŽธ๋ฆฌํ•œ ํ…Œ์ŠคํŠธ ๋ชจ๋“ˆ์„ ํ•œ๊บผ๋ฒˆ์— use ํ•ด์ค€๋‹ค

ํ…Œ์ŠคํŠธ ์‹คํ–‰

  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” t ๋””๋ ‰ํ† ๋ฆฌ์— .t ํ™•์žฅ์ž๋ฅผ ๋ถ™์—ฌ์„œ ์ €์žฅํ•œ๋‹ค
    • t/hoge.t
  • prove ์ปค๋งจ๋“œ(Test::More์— ์ฒจ๋ถ€)๋กœ ์‹คํ–‰ํ•œ๋‹ค
$ prove -lvr t
t/hoge.t .. 
ok 1 - L8: is Hoge::hey(10), 100;
1..1
ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.02 usr  0.01 sys +  0.03 cusr  0.01 csys =  0.07 CPU)
Result: PASS

ํ…Œ์ŠคํŠธ๋ฅผ ์“ฐ๋Š” ๊ธฐ์ˆ 

  • ์šฐ์„ , ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ํ–‰๋™ํ•ด์•ผ ๋œ๋‹ค๋ผ๋Š” ๊ฒƒ์„ ํ…Œ์ŠคํŠธ๋กœ ์“ด๋‹ค
is_deeply( [numsort(2,3,4,0,1)], [0,1,2,3,4], '๋žœ๋คํ•œ ์ˆ˜์—ด์„ sort ํ•˜๋ฉด ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ๋‹ค' );
  • ๋‹ค์Œ์œผ๋กœ ๊ฒฝ๊ณ„์กฐ๊ฑด์œผ๋กœ ํ–‰๋™์„ ๊ฒ€์ฆํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์“ด๋‹ค
is_deeply( [numsort()], [], '๋นˆ ๋ฐฐ์—ด์„ sort ํ•˜๋ฉด ๋นˆ๊ฐ’์ด ๋œ๋‹ค' );
is_deeply( [numsort(100)], [100], 'ํ•œ ์š”์†Œ ๋ฟ์ด๋ผ๋ฉด ๊ทธ๋Œ€๋กœ' );
  • ์˜ˆ์™ธ ์กฐ๊ฑด์— ๋Œ€ํ•ด์„œ๋„ ํ™•์ธํ•œ๋‹ค
ok( exception { [numsort('hoge')] },'๋ฌธ์ž๋ฅผ ๋„˜๊ธฐ๋ฉด ์˜ˆ์™ธ๋ฐœ์ƒ' );

Test::Hatena

  • ํ•˜ํ…Œ๋‚˜ ์‚ฌ๋‚ด์—์„œ ํ‘œ์ค€ํ™” ์ค‘์ธ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ
  • Test::More/Test::Exception ๋“ฑ์˜ ํŽธ๋ฆฌํ•œ ํ•จ์ˆ˜
  • ์œ ๋‹›ํ…Œ์ŠคํŠธ/๊ฒฐํ•ฉํ…Œ์ŠคํŠธ/๋ถ€์ž‘์šฉ์ด ์žˆ๋Š” ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด์„œ ์ง€์›

๋ฆฌํŒฉํ† ๋ง

  • ๋ฆฌํŒฉํ† ๋ง์ด๋ž€?

    • ํ”„๋กœ๊ทธ๋žจ์˜ ํ–‰๋™์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๊ตฌํ˜„์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ
  • ํ…Œ์ŠคํŠธ๊ฐ€ ์—†์œผ๋ฉด ์™ธ๋ถ€๊ธฐ๋Šฅ์˜ ๋ณ€๊ฒฝ์ด ์—†๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์—†๋‹ค

    • ํ…Œ์ŠคํŠธ๊ฐ€ ์—†์œผ๋ฉด ๋ฆฌํŒฉํ† ๋ง์ด ์•„๋‹ˆ๋‹ค
  • ๋ ˆ๊ฑฐ์‹œํ•œ ์ฝ”๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ์–ด๋–ป๊ฒŒ ํ•˜๋Š”๊ฐ€?

    • ์šฐ์„ ์€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์“ธ ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๋กœ ๋งŒ๋“ ๋‹ค.
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์จ์„œ ๋ฆฌํŒฉํ† ๋งํ•ด์„œ ํ•ญ์ƒ ๊น”๋”ํ•˜๊ฒŒ ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ์“ฐ์ž

ํžŒํŠธ

๋ฌธ์„œ๋ฅผ ์ฐพ์•„๋ณด์ž

  • perldoc perltoc ์ด ํŽธ๋ฆฌ๏ผ
    • ๋ฏธ๋ฆฌ ์ •์˜๋œ ๋ณ€์ˆ˜ใ€€$_ @_ $@
      • perldoc perlvars ๋ฅผ ๋ณธ๋‹ค
  • ํ•จ์ˆ˜
  • CPAN ๋ชจ๋“ˆ

์ข‹์€ ์ฑ…์„ ์ฝ์ž

  • Programming Perl
  • Beginning Perl
  • Perl Best Practice
    • Perl::Critic
  • ๋ชจ๋˜ Perl ์ž…๋ฌธ

ํ”„๋กœ์ ํŠธ ์ฝ”๋“œ๋ฅผ ์“ธ ๋•Œ์˜ ๋งˆ์Œ๊ฐ€์ง

  • ์ฝ”๋“œ๋Š” ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ฝ์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜์‹ํ•œ๋‹ค
    • ๋‚˜์ค‘์— ๋ˆ„๊ตฐ๊ฐ€ ์ฝ์–ด๋„ ์•Œ๊ธฐ ์‰ฝ๊ฒŒ ์“ด๋‹ค
    • ์•”๋ฌต์ ์ธ ๋ฃฐ์„ ์•ˆ๋‹ค => ์ฝ”๋“œ๋ฅผ ์‰ฝ๊ฒŒ ์ดํ•ดํ•œ๋‹ค
  • ํ…Œ์ŠคํŠธ๋ฅผ ์จ์„œ ์˜๋„๋ฅผ ์ „๋‹ฌํ•œ๋‹ค

์ •๋ฆฌ

  • Perl ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ์ดˆ

  • Perl ์— ์˜ํ•œ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

  • ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ์“ฐ์ž

  • ํžŒํŠธ

  • ์˜ค๋Š˜ ์จ์„œ ์˜ค๋Š˜ ํ—ค๋งค์ž

    • ๋ผ๊ณ  ๋งํ•ด๋„ ์‹œ๊ฐ„์ด ๊ทธ๋‹ค์ง€ ์—†๊ธฐ๋•Œ๋ฌธ์— ๋ฌด๋ฆฌ๋Š” ํ•˜์ง€ ๋ง๊ณ 

๊ณผ์ œ

๊ณผ์ œ1

์ด ๊ฐ•์˜๋ฅผ ๋งˆ์น˜๊ณ , ์‚ฌ์ „๊ณผ์ œ๋กœ ์ž‘์„ฑํ•œ Sorter ํด๋ž˜์Šค๋ฅผ ๊ฐœ๋Ÿ‰/์™„์„ฑํ•ด์ฃผ์„ธ์š”.

์ดํ•˜ ์žฌ๊ฒŒ์‹œ

์•„๋ž˜์ฒ˜๋Ÿผ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ , ์ •์ˆ˜๊ฐ’์„ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๋Š” ์ •๋ ฌํด๋ž˜์Šค๋ฅผ Perl ์„ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”. ์—ฌ์œ ๊ฐ€ ์žˆ๋Š” ์‚ฌ๋žŒ์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณ„๋กœ Sorter ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”.

my $sorter = Sorter->new;
$sorter->set_values(5,4,3,2,1);
$sorter->sort;
$sorter->get_values # (1,2,3,4,5) ์ด ๋ฐ˜ํ™˜๋œ๋‹ค

๊ตฌํ˜„์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜์˜ ์กฐ๊ฑด์„ ์ง€์ผœ์ฃผ์„ธ์š”.

  • Perl ๋‚ด์žฅ sort ํ•จ์ˆ˜๋‚˜ ์ •๋ ฌ์„ ํ•˜๋Š” CPAN ๋ชจ๋“ˆ์„ ์ด์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ€ต์†ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

๊ณผ์ œ2

๊ฐ์ฒด์ง€ํ–ฅ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ My::List ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.(C์–ธ์–ด์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ฒด์ง€ํ–ฅ Perl ๋กœ ๋งŒ๋“  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด์ฃผ์„ธ์š”)

๋ฆฌ์ŠคํŠธ์˜ ๊ฐ ์š”์†Œ์—๋Š” ์ž„์˜์˜ ๋ฐ์ดํ„ฐ(์Šค์นผ๋ผ, ๊ฐ์ฒด, ๋ ˆํผ๋Ÿฐ์Šค ๋“ฑ) ์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ์˜ ์š”์†Œ๋ฅผ ๋จผ์ € ๋”๋“ฌ์–ด๊ฐ€๋ฉด์„œ Iterator ๋ฅผ ์ค€๋น„ํ•ด์ฃผ์„ธ์š”.

My::List ์˜ ํ”„๋กœ๊ทธ๋žจ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ๋  ๊ฒ๋‹ˆ๋‹ค. ์•„๋ž˜์˜ ์˜ˆ์ œ๋Š” ๋ฆฌ์ŠคํŠธ์— "Hello" "World" "2008" ๋ผ๋Š” ์„ธ๊ฐ€์ง€ ๋ฌธ์ž์—ด์„ ์ €์žฅํ•˜๊ณ , Iterator ๋กœ ๊ทธ๊ฒƒ๋“ค์„ ๋ฝ‘์•„์„œ ์ถœ๋ ฅํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

my $list = My::List->new;

$list->append("Hello");
$list->append("World");
$list->append(2008);

my $iter = $list->iterator;
while ($iter->has_next) {
    print $iter->next->value;
}

๋ฆฌ์ŠคํŠธ์˜ ๊ฐ ์š”์†Œ๋Š” My::List ์•ˆ์— ๋ฐฐ์—ด๋กœ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•ด์‰ฌ๊ธฐ๋ฐ˜์˜ ๋ฆฌ์ŠคํŠธ ์š”์†Œ์˜ ๊ฐ์ฒด๋ฅผ ๋ฆฌํผ๋Ÿฐ์Šค๋กœ ์—ฐ๊ฒฐํ•œ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋กœ ๊ฐ€์ง„๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•ด์ฃผ์„ธ์š”.

  • ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๊ฐ€ ์–ด๋–ค ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ธ์ง€ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋Š” ใ€Žๅฎšๆœฌ Cํ”„๋กœ๊ทธ๋ž˜๋จธ๋ฅผ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ(SOFTBANK BOOKS)ใ€ P.50 - 66 ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. (๊ทธ๋ฆฌ๊ณ , ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๋“ฑ์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ๊ธฐ์ดˆ์ด๊ธฐ์—, ๊ด€๋ จ์ง€์‹์ด ์—†๋Š” ๊ฒฝ์šฐ๋Š” ์ด ์ฑ…์„ ํ†ต๋…ํ•˜๊ธฐ๋ฅผ ๊ถŒํ•ฉ๋‹ˆ๋‹ค.)

  • Iterator ์— ๋Œ€ํ•ด์„œ๋Š” ใ€Ž์ฆ๋ณด๊ฐœ์ •ํŒ Java์–ธ์–ด๋กœ ๋ฐฐ์šฐ๋Š” ๋””์ž์ธํŒจํ„ด ์ž…๋ฌธใ€์˜ ์ฒซ๋ฒˆ์งธ์žฅ์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

์œ„ ๋‘ ์„œ์ ๋ชจ๋‘ ํšŒ์‚ฌ์˜ ์ฑ…์žฅ์— ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณผ์ œ3(์˜ต์…˜)

twitter์™€ ๋น„์Šทํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด๋ณด์ž.

๋‹ค์Œ ๋‚ด์šฉ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์งน์งน์ด ๊ฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”.

  • ์งน์งน์ด๋Š” ํŠธ์œ—ํ•  ์ˆ˜ ์žˆ๋‹ค
  • ์งน์งน์ด๋Š” ๋‹ค๋ฅธ ์งน์งน์ด๋ฅผ follow ํ•  ์ˆ˜ ์žˆ๋‹ค
  • ์งน์งน์ด๋Š” follow ํ•˜๊ณ  ์žˆ๋Š” ์งน์งน์ด์˜ ํŠธ์œ—์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค

์—ฌ๋Ÿฌ๊ฐ€์ง€ ์„ค๊ณ„๋ฐฉ๋ฒ•์ด ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค๋งŒ, ๊น”๋”ํ•˜๊ณ  ๋ฉ‹๋“ค์–ด์ง„ ๊ฒƒ์„ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค. ์—ฌ์œ ๊ฐ€ ์žˆ๋‹ค๋ฉด, mentions(@๊ธฐ๋ฒ•)์ด๋‚˜ unfollow ๋‚˜ block, lists ๋“ฑ์˜ ๊ธฐ๋Šฅ๋„ ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”.

ํ”„๋กœ๊ทธ๋žจ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ž์œ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์˜ ์˜ˆ์ œ์—์„œ๋Š” SmallBird ํด๋ž˜์Šค๋ฐ–์— ์—†์ง€๋งŒ, ํŠธ์œ—์ด๋‚˜ ์ „์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์žˆ์–ด๋„ ์ข‹๊ฒ ๋„ค์š”. Observer ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

use Bird;
my $b1 = Bird->new( name => 'jkondo');
my $b2 = Bird->new( name => 'reikon');
my $b3 = Bird->new( name => 'onishi');

$b1->follow($b2);
$b1->follow($b3);

$b3->follow($b1);

$b1->tweet('์˜ค๋Š˜์€ ๋ฅ๋„ค์š”๏ผ');
$b2->tweet('์ปคํ”ผ๋งˆ์‹œ๋Ÿฌ ๋‚˜์™”์Šต๋‹ˆ๋‹ค');
$b3->tweet('์ง€๊ธˆ ์—ฌ์˜๋„๏ผ');

my $b1_timelines = $b1->friends_timeline;
print $b1_timelines->[0]->message; # onishi: ์ง€๊ธˆ ์—ฌ์˜๋„!
print $b1_timelines->[1]->message; # reikon: ์ปคํ”ผ๋งˆ์‹œ๋Ÿฌ ๋‚˜์™”์Šต๋‹ˆ๋‹ค

my $b3_timelines = $b3->friends_timeline;
print $b3_timelines->[0]->message; # jkondo: ์˜ค๋Š˜์€ ๋ฅ๋„ค์š”!

๊ณผ์ œ์— ๋“ค์–ด๊ฐˆ ๋•Œ์˜ ์ฃผ์˜์ 

  • ๊ฐ€๋Šฅํ•œํ•œ ํ…Œ์ŠคํŠธ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์“ด๋‹ค
    • ์ ์–ด๋„ ๋Œ๋ ค์„œ ์‹œํ—˜ํ•ด๋ณผ ์ˆ˜ ์—†๋‹ค๋ฉด ์ฑ„์ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    • ๊ณผ์ œ์˜ ๋ณธ์งˆ์ ์ธ ๋ถ€๋ถ„๋งŒ ๊ตฌํ˜„ํ•˜๋ฉด CPAN ๋ชจ๋“ˆ๋กœ ์‰ฝ๊ฒŒ ํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.
    • ๋ฌด์—‡์ด ๋ณธ์งˆ์ ์ธ๊ฐ€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ๋„ ๊ณผ์ œ ์ค‘ ํ•˜๋‚˜
  • ์—ฌ์œ ๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ธฐ๋Šฅ ์ถ”๊ฐ€ํ•ด๋ณด์„ธ์š”.
  • ๊ณผ์ œ์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ด์„œ ์ปค๋ฐ‹ํ•ด์ฃผ์„ธ์š”.
    • push ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋ง๊ณ !
intern/username/100802/exercise1
                      /exercise2
                      /exercise3
               /100803/exercise1
                      /exercise2
                      /  ...
                      /  ...

Perl์˜ ์Šต๊ด€์œผ๋กœ์จ, ์•„๋ž˜์™€ ๊ฐ™์€ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์„ฑ์œผ๋กœ ์ปค๋ฐ‹ํ•˜๋ฉด ์—ฌ๋Ÿฌ๋ชจ๋กœ ์ข‹์Šต๋‹ˆ๋‹ค.

.
|-- lib
|   `-- MyClass
|       `-- Foo.pm
`-- t
    `-- 00_base.t
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋†“๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋Š” lib
  • ํ…Œ์ŠคํŠธ ํŒŒ์ผ์„ ๋†“๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋Š” t
  • ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ๋Š” prove -Ilib t ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค
  • ๋˜๋Š” ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ ํ•˜๋‚˜๋ฅผ perl -Ilib t/00_base.t ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๊ณผ์ œ์˜ ์ฑ„์ ๊ธฐ์ค€

๊ฐ ๊ณผ์ œ์˜ ๋งŒ์  = ๊ณผ์ œ1: 4์  + ๊ณผ์ œ2: 4์  + ๊ณผ์ œ3: 2์  = 10์ 

  • ๊ฐ•์˜ ๋˜๋Š” ๊ต๊ณผ์„œ์˜ ์ดํ•ด๋„๊ฐ€ ๊ณผ์ œ์˜ ๊ตฌํ˜„์— ๋ฐ˜์˜๋˜์—ˆ๋Š”๊ฐ€

  • ํ…Œ์ŠคํŠธ์šฉ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฐ€

  • ์„ค๊ณ„/์ฝ”๋“œ๊ฐ€ ์ œ๋Œ€๋กœ ๋˜์–ด ์žˆ๋Š”๊ฐ€

  • ๋…์ž์ ์œผ๋กœ ๊ธฐ๋Šฅ์ถ”๊ฐ€๊ฐ€ ๋˜์–ด์žˆ๋Š”๊ฐ€

  • ๊ณผ์ œ1๊ณผ ๊ณผ์ œ2๋ฅผ ์ œ๋Œ€๋กœ ํ•œ ๋‹ค์Œ์— ๊ณผ์ œ3์— ๋„์ „ํ•ด์ฃผ์„ธ์š”.

๊ณผ์ œ์˜ ํ•ด๋‹ต

  • ์Šค์Šค๋กœ ํ’€์–ด๋ณด๋ ค๊ณ  ๋…ธ๋ ฅํ•ด๋ณด์„ธ์š”~
  • https://github.com/limitusus/Hatena-Textbook ์— ํ•ด๋‹ต ์˜ˆ์‹œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด์•ผํ•  ์ผ

  • git clone
  • ๊ณผ์ œ

ใ‚ฏใƒชใ‚จใ‚คใƒ†ใ‚ฃใƒ–ใƒปใ‚ณใƒขใƒณใ‚บใƒปใƒฉใ‚คใ‚ปใƒณใ‚น
์ด ์ž‘ํ’ˆ์€ ํฌ๋ฆฌ์—์ดํ‹ฐ๋ธŒ ์ปค๋จผ์ฆˆ ํ‘œ์‹œ - ๋น„์˜๋ฆฌ - ์ƒ์† 2.1 ์ผ๋ณธ ๋ผ์ด์„ผ์Šค์˜ ์•„๋ž˜์—์„œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.