BLOG main image
분류 전체보기 (28)
루비 (3)
glassfish (1)
건아 (1)
RFC 한글 (0)
TIP (5)
VCS(Version Control System) (3)
perl (4)
java (2)
android (0)
javascript&Jquery (2)
기술문서 번역 (0)
사이베이스(ASE) (3)
용어 (2)
GAE&GCP (0)
사는 이야기 (1)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
2011. 6. 24. 16:10

1.

레퍼런스(참조) 값을 얻으려면 「\」 를 붙인다. 

스칼라


[코드-1] 보통의 스칼라 변수($value)

#!/usr/bin/perl

my $value= 'test';



print "$value\n"; # test


[코드-2] 스칼라의 레퍼런스($value_ref)

#!/usr/bin/perl

my $value = 'test';



print "$value\n"; # test



my $value_ref = \$value;



print "$value_ref\n"; # SCALAR(0x8065ab4)


리스트

[코드-3] 보통의 리스트ト(@foo)

#!/usr/bin/perl

my @foo = ('John', 'Mike', 'Mary');



print "@foo\n"; # John Mike Mary


[코드-4] 리스트의 레퍼런스($foo_ref)

#!/usr/bin/perl

my @foo = ('John', 'Mike', 'Mary');



print "@foo\n"; # John Mike Mary



my $foo_ref = \@foo;



print "$foo_ref\n"; # ARRAY(0x8065aec)


레퍼런스의 대상이 리스트여도 “
레퍼런스 자체는 스칼라이다.


해시

[코드-5] 보통의 해시(%bar)

#!/usr/bin/perl

my %bar = (

   
'John' => 15,

   
'Mike' => 17,

   
'Mary' => 19,

);



print %bar; # John15Mary19Mike17

print "\n";


[코드-6] 해시의 레퍼런스($bar_ref)

#!/usr/bin/perl

my %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/perl

my @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/perl

my @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/perl

my $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/perl

my $value = 'test'; # 스칼라에 값을 대입



my $value_ref = \$value; # 스칼라의 레퍼런스



my $ref_value_ref = \$value_ref; # 레퍼런스의 레퍼런스



print ref $ref_value_ref; # 결과는?


SCALAR 가 아닌 REF 가 반환됩니다. 

무명레퍼런스


무명스칼라

#!/usr/bin/perl

my $value = \'test'; # 포인트는 \



print "$value\n";  # SCALAR(0x8065ad8) 레퍼런스



print "$$value\n"; # test


$value는 레퍼런스. 값( 'test' ) 을 참조하기 위해서는 디레퍼런스할 필요가 있다.


무명リスト

#!/usr/bin/perl

my $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/perl

use 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"; # park



print "$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 의 경우 리스트안에 해시가 있고 그 안에 다시 리스트가 있는 구조다. 
무명리스트와 무명해시에 의해 이러한 표현이 가능하다. 

복잡한 데이타의 경우,  Data::Dumper 를 이용하면 편리하다. 
#!/usr/bin/perl

use 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' 카테고리의 다른 글

perl 처리 시간 구하기  (0) 2011.07.14
Perl 의 NULL  (52) 2011.06.24
펄의 참과 거짓  (0) 2011.06.24