FOR 반복문
#!/usr/bin/perl
foreach $rock (qw/ bedrock slate lava /) {
print "one rock is $rock.\n";
}
-
펄에서는 반복문을 위와 같이 사용한다.
-
특이한 점은
$rock
에 들어가는 값이 복사본이 아니라, 리스트의 원본이 들어간다는 점이다. -
만약에
$rocks
를 변경하면 원본 리스트가 변경된다.
#!/usr/bin/perl
@rocks = qw/ bedrock slate lava /;
foreach $rock (@rocks) {
$rock = "\t$rock";
$rock .= "\n";
}
print "The rocks are:\n", @rocks;
-
따라서 이렇게 작성한다면, 원본 배열과 다른 결과가 나올 것이다.
-
또 한가지 특이한 점은, 어떤 값이 들어있는 변수를 반복문의 컨트롤 변수 (리스트의 값이 들어가는 변수)로 사용한다면 반복문에서는 리스트의 값이 하나씩 대입되고 반복문이 끝나면 반복문이 시작하기 전의 값으로 복원되어 있다.
#!/usr/bin/perl
$rock = 'shale';
@rocks = qw" bedrock slate lava ";
foreach $rock (@rocks) {
print "$rock\n";
}
print "rock is still $rock\n"; # 'rocks is still shale'
- 따라서, 반복문에서 사용하는 컨트롤 변수를 위에서 사용하고 있는지 걱정할 필요가 없다.
$_ 변수
foreach
문에서, 컨트롤 변수를 생략했다면, 자동으로$_
라는 공간에 들어가게 된다.
#!/usr/bin/perl
foreach (1..10) {
print "I can count to $_ !\n";
}
- 그리고
$_
변수에 값을 대입하고 나서,print
를 하게 되면 이전에 대입한 값이 들어가게 된다.
#!/usr/bin/perl
foreach (1..10) {
print "I can count to $_ !\n";
}
$_ = "Yabba dabba doo\n";
print; # 'Yadda badda doo'
reverse 연산자
#!/usr/bin/perl
@fred = 6..10;
print "@fred\n";
@barney = reverse(@fred);
print "@fred\n";
@wilma = reverse 6..10;
print "@wilma\n";
@fred = reverse @fred;
print "@fred\n";
-
reverse
연산자는 리스트의 값을 거꾸로 변환해서 반환한다. -
주의할 점은 그저 거꾸로 뒤집은 값을 반환할 뿐이지, 원본 값을 변경하지는 않는다는 점이다.
sort 연산자
#!/usr/bin/perl
@rocks = qw/ bedrock slate rubble granite /;
print "@rocks\n"; # bedrock slate rubble granite
@sorted = sort(@rocks);
print "@sorted\n"; # bedrock granite rubble slate
@back = reverse sort @rocks;
print "@back\n"; # slate rubble granite bedrock
@rocks = sort @rocks;
print "@rocks\n"; # bedrock granite rubble slate
@numbers = sort 97..102; # 100 101 102 97 98 99
print "@numbers\n";
-
이를 실행해보면 마지막 결과가 예상과 다르게 나오는데 그 이유는 문자열로 취급하기 때문이다.
-
그리고
reverse
연산자와 마찬가지로, 정렬한 리스트를 반환하기 때문에 원본은 변경되지 않는다.
each 연산자
#!/usr/bin/perl
@rocks = qw/ bedrock slate rubble granite /;
while (($index, $value) = each @rocks) {
print "$index: $value\n";
}
# 결과
0: bedrock
1: slate
2: rubble
3: granite
-
each
연산자는 인덱스와 리스트의 값을 동시에 반환한다. -
만약 파이썬을 알고 있다면,
enumerate
를 사용한 것과 같은 결과를 얻을 수 있다.
스칼라 값과 리스트 값은 문맥에 따라서 달라진다
-
펄은 특이하게 문맥에 따라서 값이 다르게 처리 된다.
-
이것은 마치 자연어와 같은데, 자연어도 문맥에 따라서 같은 단어임에도 불구하고 다르게 사용될 수 있다. 펄도 그렇다.
@people = qw (fred barney betty);
@sorted = sort @people; # list context: barney, betty, fred
$number = 42 + @people; # 42 + 3 = 45
-
따라서 리스트를 생산하는 연산의 경우 리스트에서만 사용될 것으로 예상이 되며, 스칼라 값에 사용할 경우에는 예상하기 힘든 값이 나올 수도 있다.
-
리스트를 만드는 연산을 스칼라 문맥에서 사용할 경우에는 문서를 참조하는 것이 낫다.
/usr/bin/perl
@backwards = reverse qw/ yadda dabba doo/;
print "@backwards\n";
$backwards = reverse qw/ yabba dabba doo /;
print "$backwards\n";
== result ==
doo dabba yadda
oodabbadabbay
- 일반적인 경우 아래와 같이 생각하면 된다.
$fred = something; # 스칼라
@pebbles = something; # 리스트
($wilma, $betty) = something; # 리스트
($dino) = something # 리스트
-
마지막의 경우 스칼라라고 생각 할 수도 있지만, 리스트인 것을 주의해서 봐야한다.
-
괄호가 리스트라는 것을 명확하게 나타내고 있다.
-
리스트에 스칼라를 대입해도 리스트이고, 리스트 값을 대입해도 리스트이다.
-
리스트 값에 스칼라 변수를 대입하면 자동으로 리스트 값으로 변환된다.
@fred = 6 * 7 # list (42)
@barney = "hello" . ' ' . "world";
@wilma = undef # list (undef)
@betty = ( ); # empty array
-
또한,
undef
값은 스칼라 갑이며 빈 리스트를 만들고 싶다면, 빈 괄호를 사용하여 만드는 것이 더 올바른 것을 확인할 수 있다. -
만약 강제로 스칼라 값을 취하고 싶다면
scalar
라는 함수를 사용하면 된다.
!/usr/bin/perl
@rocks = qw( talc quartz jade obsidian );
print "How many rocks do you have?\n";
print "I have ", @rocks, " rocks!\n";
print "I hvae ", scalar @rocks, " rocks!\n";
=== result ===
How many rocks do you have?
I have talcquartzjadeobsidian rocks!
I hvae 4 rocks!
-
대표적으로 스칼라 값과 리스트 값에 따라서 동작이 달라지는 연산이 바로
<STDIN>
이다. -
스칼라 값으로
<STDIN>
을 입력받으면 한 단어만 입력받게 된다. -
리스트 값에
<STDIN>
으로 사용자 입력값을 받으면, 더 이상 남아있는 값이 없을 때까지 입력을 받는다. 모두 입력 받았다는 것을 나타내려면 CTRL + D를 누르면 모두 입력 했다는 것을 나타낸다. -
보통 개행 문자 (\n)를
chomp()
를 사용하여 제거한 값을 받는다.
@lines = <STDIN>;
chomp(@lines);