다음과 같은 형식의 설정파일 내용을 읽을 수 있는 프로그램을 만들기를 원했다. 꽤 일반적인 형식이고, 아마도 관련 perl 모듈을 찾을 수 있을거라 생각되었지만, Perl을 이용한 자료구조다루는 법도 익힐겸해서 직접 만들어 보기로 했다.
[section]
name1=value
name2=value1,value2
아마 C++을 이용했다면, 분명히 STL(:12)을 이용해서 vector(:12)의 map(:12)혹은 map의 map 형식으로 구현했을 것이다. 일반적인 자료구조로 하자면 배열의 hash, hash 의 hash일 것이다. 예전에 C++로 간단히 구현해본게 있는데, 아마 이 코드의 Perl 버젼이 되지 않을까 싶다.
key, value 순으로 나열이 된다. 배열과 전혀차이가 없음을 알 수 있다. n번째 원소는 key n+1번째 원소는 value로 해석이 될 뿐이다.
이러한 hash의 성질을 이용해서, perl에서 구조체를 구현할 수 있다. 참고로 perl은 C(:12)에서의 구조체를 지원하지 않는다. 예를 들어서 사용자 정보를 위한 userInfo 구조체가 필요하다면, 다음과 같을 것이다.
STL의 map을 사용해본 경험이 있다면, perl의 hash of hash 자료구조가 헷갈릴 수 있을 것 같다. 왜냐하면 STL이라면 다음과 같이 구현될 것이기 때문이다. perl과는 다르다는 것을 알 수 있을 것이다. 나도 처음엔 이것 때문에 꽤나 어리둥절 했었던 기억이 있다.
위의 getCfg 서브루틴을 이용해서 hash of hash의 aceess방법에 대해서 알아보겠다. 기본적으로 두번의 루프를 돌려야 원하는 값을 얻어올 수 있다.
my $cfg = getCfg("config.cfg");
for my $section (keys %$cfg)
{
print "Section $section\n";
for my $name (keys %{$cfg->{$section}})
{
print "$name = $cfg->{$section}->{$name}\n";
}
}
getCfg가 레퍼런스를 리턴했기 때문에,->연산자를 써서 값에 접근했다는 것외에는 별 특이사항이 없다.
관련글
aero님이 작성한 Perl에 Hash는 없다? 내가 작성한 문서에서는 편의상 hash와 array가 같은 것이라고 했는데, 이 문서에 hash와 array의 차이점에 대해서 자세히 설명하고 있다. 암튼 perl은 복잡해..
소개
hash 초기화
키와 값 추가 하기
$hash{'key'} = 'value'; $hash{$key} = $value;$href->{'key'} = 'value'; $href->{$key} = $value;한번에 여러개의 키,값 추가하기
%hash = ('key1', 'value1', 'key2', 'value2', 'key3', 'value3');#!/usr/bin/perl %userInfo = ( 'name', '', 'address', '', 'age', '', 'tel', '' ); $userInfo{'name'} = 'yundream'; $userInfo{'address'} = 'seoul seo-cho dong'; $userInfo{'age'} = 19; $userInfo{'tel'} = '11-111-1111'; for $name(keys %userInfo) { print $name,"=>", $userInfo{$name},"\n"; } # 해쉬가 배열이라는 것을 확인하기 위해서. foreach(%userInfo) { print $_,"\n"; }hash의 hash
sub getCfg { my ($cfgfile) = @_; open(FD, "<$cfgfile"); $rSection = ""; %cfgmap=(); while($line = <FD>) { # 읽어들인 라인이 section 인지를 확인한다. if($line =~ /\[[a-zA-Z0-9]+\]/) { $line =~ s/\n|\[|\]//g; push(@cfgSection, $cfgValue); $Section = $line; $rSection = $Section; next; } # 설정값이라면 '='를 기준으로 key와 value를 구분해낸다음 # 현재 section 이름을 key로 하는 hash에 집어 넣는다. if($line =~ /[a-zA-Z0-9]+=/) { $line =~ s/\s//g; ($key, $value) = split '=', $line; $cfgmap{$Section}{$key} = $value; } } close(FD); return \%cfgmap; }map.sub{key1} = value1; map.sub{key2} = value2; map.main{key} = map.subhash의 hash access
my $cfg = getCfg("config.cfg"); for my $section (keys %$cfg) { print "Section $section\n"; for my $name (keys %{$cfg->{$section}}) { print "$name = $cfg->{$section}->{$name}\n"; } }관련글
Recent Posts
Archive Posts
Tags