1.
레퍼런스(참조) 값을 얻으려면 「\」 를 붙인다.
레퍼런스(참조) 값을 얻으려면 「\」 를 붙인다.
[코드-1] 보통의 스칼라 변수($value)
#!/usr/bin/perlmy $value= 'test';
print "$value\n"; # test
[코드-2] 스칼라의 레퍼런스($value_ref)
#!/usr/bin/perlmy $value = 'test';
print "$value\n"; # test
my $value_ref = \$value;
print "$value_ref\n"; # SCALAR(0x8065ab4)
[코드-3] 보통의 리스트ト(@foo)
#!/usr/bin/perlmy @foo = ('John', 'Mike', 'Mary');
print "@foo\n"; # John Mike Mary
[코드-4] 리스트의 레퍼런스($foo_ref)
#!/usr/bin/perlmy @foo = ('John', 'Mike', 'Mary');
print "@foo\n"; # John Mike Mary
my $foo_ref = \@foo;
print "$foo_ref\n"; # ARRAY(0x8065aec)
레퍼런스의 대상이 리스트여도 “레퍼런스 자체는 스칼라이다.”
[코드-5] 보통의 해시(%bar)
#!/usr/bin/perlmy %bar = (
'John' => 15,
'Mike' => 17,
'Mary' => 19,
);print %bar; # John15Mary19Mike17
print "\n";
[코드-6] 해시의 레퍼런스($bar_ref)
#!/usr/bin/perlmy %bar = (
'John' => 15,
'Mike' => 17,
'Mary' => 19,
);print %bar; # John15Mary19Mike17
print "\n";my $bar_ref = \%bar;
print "$bar_ref\n"; # HASH(0x8065b3c)
마찬가지로 레퍼런스의 대상이 해시여도 “레퍼런스 자체는 스칼라이다.”
간단히 정리하면 아래와 같다.
| 변수 | ref | 값---------+-------+--------+------------------- 스칼라 | $value| \$value| SCALAR(0x8065ab4)---------+-------+--------+------------------- 리스트 | @foo | \@foo | ARRAY(0x8065aec)---------+-------+--------+------------------- 해시 | %bar | \%bar | HASH(0x8065b3c)---------+-------+--------+-------------------
레퍼런스하기 전의 값을 참조하고 싶을 경우 그것을 디레퍼런스라고 한다.
[코드-2] 의 $value_ref (스칼라 레퍼런스) 라면 $$value_ref 처럼 처음에 $ 을 붙이면 레퍼런스하기 전의 값을 참조할 수 있다.
print "$$value_ref\n"; # test ← 레퍼런스하기 전의 값
리스트의 경우는 @, 해시의 경우는 % 를 붙여서 디레퍼런스한다. (참조의 원래값을 찾아감)
print "@$foo_ref\n"; # John Mike Mary
print %$bar_ref; # John15Mary19Mike17
추가로 레퍼런스를 반환하는 함수를 디레퍼런스할 경우에는 { } 로 감싼다.
@{ hoge_func->fuga('test') }
스칼라는 디레퍼런스하면 원래의 값을 참조할 수 있지만 리스트와 해시는 원래의 값을 개별적으로 참조할 때 어떻게 해야 할까?
리스트의 경우
#!/usr/bin/perlmy @foo = ('John', 'Mike', 'Mary'); # 리스트
print "$foo[1]\n"; # Mike
my $foo_ref = \@foo; # 리스트의 레퍼런스
print "$foo_ref->[1]\n"; # Mike
리스트의 레퍼런스에서 개별값을 참조하는 경우의 화살표 연산자가 알기 쉽다.
덧붙이면 아래는 모두 같다.
print "$foo_ref->[1]\n";
print "$$foo_ref[1]\n";
print "${$foo_ref}[1]\n";
해시의 경우
#!/usr/bin/perl# 해시
my %bar = (
'John' => 15,
'Mike' => 17,
'Mary' => 19,
);print "$bar{Mike}\n"; # 17
my $bar_ref = \%bar; # 해시의 레퍼런스
print "$bar_ref->{Mike}\n"; # 17
리스트와 마찬가지로 화살표 연산자로 참조하지만 ( -> ) { } 로 감싼다.
레퍼런스 / 디레퍼런스를 사용시 주의해야 할 점은 바로 변수형을 잘못 지정하는 경우다(리스트 레퍼런스를 스칼라 레퍼런스처럼 사용한다던가 하는 경우)
예를 들면 아래와 같은 경우
#!/usr/bin/perlmy @foo = ('John', 'Mike', 'Mary'); # 리스트
my $foo_ref = \@foo; # $foo_ref 는 리스트의 레퍼런스
print "$$foo_ref\n"; # 에러!
「Not a SCALAR reference」 라는 에러 메시지가 표시된다.
디레퍼런스할 때 변수형이 맞지 않으면 에러가 된다.
print "@$foo_ref\n"; # OK
많은 수의 변수를 처리하거나 리스트인데 단 하나의 변수만 처리하거나 할 경우 변수형태를 쉽게 혼동하거나 한다.
그런 경우는 레퍼런스의 형태를 확인하는 함수가 있다. 바로 ref
#!/usr/bin/perlmy $value = 'test';
my $value_ref = \$hoge;
print ref $value_ref; # SCALAR
아래처럼 할 수 있다.
if ( ref $value_ref eq 'SCALAR' ) {
print "스칼라입니다.\n";
}
else {
print "스칼라가 아닙니다.\n";
}
레퍼런스이외의 경우 ref 는 아무 값도 반환하지 않는다.
그리고 레퍼런스는 스칼라, 리스트, 해시뿐만 아니라 코드 레퍼런스와 글로브 레퍼런스 따위도 있다.
아래의 코드를 확인해 보자.
#!/usr/bin/perlmy $value = 'test'; # 스칼라에 값을 대입
my $value_ref = \$value; # 스칼라의 레퍼런스
my $ref_value_ref = \$value_ref; # 레퍼런스의 레퍼런스
print ref $ref_value_ref; # 결과는?
SCALAR 가 아닌 REF 가 반환됩니다.
무명스칼라
#!/usr/bin/perlmy $value = \'test'; # 포인트는 \
print "$value\n"; # SCALAR(0x8065ad8) 레퍼런스
print "$$value\n"; # test
$value는 레퍼런스. 값( 'test' ) 을 참조하기 위해서는 디레퍼런스할 필요가 있다.
무명リスト
#!/usr/bin/perlmy $foo = ['John', 'Mike', 'Mary']; # 포인트는 [ ]、( )가아님
print "$foo\n"; # ARRAY(0x804cd40) 레퍼런스
print "@$foo\n"; # John Mike Mary
print "$foo->[1]\n"; # Mike
$foo 는 무명리스트이기 때문에 값을 참조하기 위해서는 디레퍼런스할 필 필요가 있다.
무명리스트를 작성(취득)하기 위해서는 [ ] 를 사용한다.
무명해시
#!/usr/bin/perl# 포인트는 { }
my $bar = {
'John' => 15,
'Mike' => 17,
'Mary' => 19,
};print "$bar\n"; # HASH(0x804cd40)
print %$bar; # John15Mary19Mike17
print "\n";print "$bar->{Mike}\n"; # 17
$bar 는 무명해시이기 때문에 값을 참조하기 위해서는 디레퍼런스할 필요가 있다.
무명해시를 참조(취득)하기 위해서는 { }를 사용한다.
복잡한 구조의 예
예
#!/usr/bin/perluse strict;
use warnings;my $persons = [
{
name => 'kim',
sex => 'male',
age => 32,
hobby => ['music', 'movie', 'jogging'],
},
{
name => 'park',
sex => 'female',
age => 35,
hobby => ['movie', 'shopping'],
}
];# 개별참조
print "$persons->[0]->{name}\n"; # kim
print "$persons->[1]->{name}\n"; # parkprint "$persons->[0]->{hobby}->[1]\n"; # movie
print "$persons->[1]->{hobby}->[1]\n"; # shopping# 루프
for my $person (@$persons) {
print "$person->{name} = $person->{sex}\n";
}
# kim= male
# park = female
$persons 의 경우 리스트안에 해시가 있고 그 안에 다시 리스트가 있는 구조다.
무명리스트와 무명해시에 의해 이러한 표현이 가능하다.
#!/usr/bin/perluse strict;
use warnings;use XML::Feed;
use Data::Dumper;my $feed = XML::Feed->parse( URI->new('http://dailynews.yahoo.com/today/rss.xml') )
or die XML::Feed->errstr;print Dumper $feed;
perl 처리 시간 구하기 (0) | 2011.07.14 |
---|---|
Perl 의 NULL (52) | 2011.06.24 |
펄의 참과 거짓 (0) | 2011.06.24 |