Perl Language
변수
수색…
통사론
- 내 # 어휘 선언
- 우리 # 전역 선언
- $ foo # Scalar
- @foo # Array
- $ # foo # 배열 마지막 색인
- % foo # Hash
- $ {$ foo} # 스칼라 참조 해제
- @ {$ foo} # 배열 참조 해제
- $ # {$ foo} # Array-DeRef 마지막 색인
- % {$ foo} # 해시 참조 해제
- $ foo [$ index] # 배열의 색인이 생성됩니다.
- $ {$ foo} [$ index] # 배열 참조 해제 및 색인 생성.
- $ foo -> [$ index] # 배열 참조 해제 및 색인 생성 (단순화)
- $ foo {$ key} # 키에 해시 값 가져 오기
- $ {$ foo} {$ key} # 해시를 참조 해제하고 키 값 가져 오기
- $ foo -> {$ key} # 해시를 역 참조하고 키 값 가져 오기 (간체)
- \ $ x # Scalar에 대한 참조
- \ @x # 배열 참조
- \ % x # 해시 참조
- = [] # 익명 배열 참조 (인라인)
- = {} # 익명 해시 (인라인)에 대한 참조
스칼라
스칼라는 펄의 가장 기본적인 데이터 유형입니다. 그것들은 sigil $
로 표시되어 있으며 세 가지 유형 중 하나의 단일 값을 가지고 있습니다.
- 숫자 (
3
,42
,3.141
등) - 문자열 (
'hi'
,"abc"
등) - 변수에 대한 참조 (다른 예 참조).
my $integer = 3; # number
my $string = "Hello World"; # string
my $reference = \$string; # reference to $string
Perl 은 특정 연산자가 기대하는 것을 기반으로 즉석 에서 숫자와 문자열을 변환 합니다.
my $number = '41'; # string '41'
my $meaning = $number + 1; # number 42
my $sadness = '20 apples'; # string '20 apples'
my $danger = $sadness * 2; # number '40', raises warning
문자열을 숫자로 변환 할 때 Perl은 가능한 한 많은 문자열을 문자열의 앞부분에서 취합니다. 따라서 마지막 줄에서 20 apples
가 20
개로 변환됩니다.
스칼라의 내용을 문자열 또는 숫자로 처리할지 여부에 따라 다른 연산자를 사용해야합니다. 그들을 섞지 마십시오.
# String comparison # Number comparison
'Potato' eq 'Potato'; 42 == 42;
'Potato' ne 'Pomato'; 42 != 24;
'Camel' lt 'Potato'; 41 < 42;
'Zombie' gt 'Potato'; 43 > 42;
# String concatenation # Number summation
'Banana' . 'phone'; 23 + 19;
# String repetition # Number multiplication
'nan' x 3; 6 * 7;
숫자에 문자열 연산을 사용하려고해도 경고가 발생하지 않습니다. 숫자가 아닌 문자열에 숫자 연산을 사용하려고하면됩니다. 'inf'
, 'nan'
, '0 but true'
와 같은 일부 숫자가 아닌 문자열은 숫자로 간주된다는 점에 유의하십시오.
배열
배열은 순서가 지정된 값 시퀀스를 저장합니다. 색인을 사용하여 내용에 액세스하거나 내용을 반복 할 수 있습니다. 값은 입력 한 순서대로 유지됩니다.
my @numbers_to_ten = (1,2,3,4,5,6,7,8,9,10); # More conveniently: (1..10)
my @chars_of_hello = ('h','e','l','l','o');
my @word_list = ('Hello','World');
# Note the sigil: access an @array item with $array[index]
my $second_char_of_hello = $chars_of_hello[1]; # 'e'
# Use negative indices to count from the end (with -1 being last)
my $last_char_of_hello = $chars_of_hello[-1];
# Assign an array to a scalar to get the length of the array
my $length_of_array = @chars_of_hello; # 5
# You can use $# to get the last index of an array, and confuse Stack Overflow
my $last_index_of_array = $#chars_of_hello; # 4
# You can also access multiple elements of an array at the same time
# This is called "array slice"
# Since this returns multiple values, the sigil to use here on the RHS is @
my @some_chars_of_hello = @chars_of_hello[1..3]; # ('H', 'e', 'l')
my @out_of_order_chars = @chars_of_hello[1,4,2]; # ('e', 'o', 'l')
# In Python you can say array[1:-1] to get all elements but first and last
# Not so in Perl: (1..-1) is an empty list. Use $# instead
my @empty_list = @chars_of_hello[1..-1]; # ()
my @inner_chars_of_hello = @chars_of_hello[1..$#chars_of_hello-1]; # ('e','l','l')
# Access beyond the end of the array yields undef, not an error
my $undef = $chars_of_hello[6]; # undef
배열은 변경할 수 있습니다.
use utf8; # necessary because this snippet is utf-8
$chars_of_hello[1] = 'u'; # ('h','u','l','l','o')
push @chars_of_hello, ('!', '!'); # ('h','u','l','l','o','!','!')
pop @chars_of_hello; # ('h','u','l','l','o','!')
shift @chars_of_hello; # ('u','l','l','o','!')
unshift @chars_of_hello, ('¡', 'H'); # ('¡','H','u','l','l','o','!')
@chars_of_hello[2..5] = ('O','L','A'); # ('¡','H','O','L','A',undef,'!') whoops!
delete $chars_of_hello[-2]; # ('¡','H','O','L','A', '!')
# Setting elements beyond the end of an array does not result in an error
# The array is extended with undef's as necessary. This is "autovivification."
my @array; # ()
my @array[3] = 'x'; # (undef, undef, undef, 'x')
마지막으로 배열의 내용을 반복 할 수 있습니다.
use v5.10; # necessary for 'say'
for my $number (@numbers_to_ten) {
say $number ** 2;
}
boolean으로 사용할 때, 배열은 비어 있지 않은 경우 true입니다.
해시
해시는 조회 테이블로 이해할 수 있습니다. 각각의 키를 지정하여 해당 내용에 액세스 할 수 있습니다. 키는 문자열이어야합니다. 그렇지 않은 경우 문자열로 변환됩니다.
해시를 단순히 알려진 키로 지정하면 키 값을 제공합니다.
# Elements are in (key, value, key, value) sequence
my %inhabitants_of = ("London", 8674000, "Paris", 2244000);
# You can save some typing and gain in clarity by using the "fat comma"
# syntactical sugar. It behaves like a comma and quotes what's on the left.
my %translations_of_hello = (spanish => 'Hola', german => 'Hallo', swedish => 'Hej');
다음 예제에서 괄호와 sigil을주의하십시오. 원하는 값 이 스칼라이기 때문에 $hash{key}
사용하여 %hash
의 요소에 액세스합니다. 어떤 사람들은 열쇠를 인용하는 것이 좋은 습관이라고 생각하는 반면 다른 사람들은이 스타일을 시각적으로 시끄러운 것으로 생각합니다. quoting은 $hash{'some-key'}
와 같은 표현식으로 착각 될 수있는 키에만 필요합니다
my $greeting = $translations_of_hello{'spanish'};
Perl은 기본적으로 barewords를 문자열로 사용하려고 시도하지만, +
수정자는 Perl에 키가 보간되어서는 안되지만 실행 결과가 키로 사용되도록 표시하는 데 사용될 수 있습니다.
my %employee = ( name => 'John Doe', shift => 'night' );
# this example will print 'night'
print $employee{shift};
# but this one will execute [shift][1], extracting first element from @_,
# and use result as a key
print $employee{+shift};
배열과 마찬가지로 여러 해시 요소에 동시에 액세스 할 수 있습니다. 이를 해시 슬라이스 라고합니다. 결과 값은 목록이므로 @
sigil을 사용하십시오.
my @words = @translations_of_hello{'spanish', 'german'}; # ('Hola', 'Hallo')
과 해시의 키 반복 keys
keys
무작위 순서로 항목을 반환합니다. 원하는 경우 sort
과 결합하십시오.
for my $lang (sort keys %translations_of_hello) {
say $translations_of_hello{$lang};
}
앞의 예제 에서처럼 실제로 키가 필요하지 않은 경우 values
는 해시의 값을 직접 반환합니다.
for my $translation (values %translations_of_hello) {
say $translation;
}
each
의 while 루프를 사용하여 해시를 반복 할 수도 있습니다. 이렇게하면 별도의 값 조회없이 키와 값을 동시에 얻을 수 있습니다. 그러나 each
방법을 잘못 이해할 수 있으므로 사용법은 권장하지 않습니다 .
# DISCOURAGED
while (my ($lang, $translation) = each %translations_of_hello) {
say $translation;
}
unset 요소에 대한 액세스는 오류가 아닌 undef를 반환합니다.
my $italian = $translations_of_hello{'italian'}; # undef
map
및 목록 병합을 사용하여 배열에서 해시를 만들 수 있습니다. 이는 값이 @elems
있는지 빠르게 확인하는 것과 같이 '값'집합을 만드는 인기있는 방법입니다. 이 작업은 대개 O (n) 시간 (요소 수에 비례)을 필요로하지만 목록을 해시로 변환하여 일정 시간 (O (1))에 수행 할 수 있습니다.
@elems = qw(x y x z t);
my %set = map { $_ => 1 } @elems; # (x, 1, y, 1, t, 1)
my $y_membership = $set{'y'}; # 1
my $w_membership = $set{'w'}; # undef
이것은 약간의 설명이 필요합니다. @elems
의 내용은 map
으로 처리되는 목록으로 읽습니다. map
은 입력 목록의 각 값에 대해 호출되는 코드 블록을 허용합니다. 요소의 값은 $_
에서 사용할 수 있습니다. 우리의 코드 블록은 각 입력 요소에 대한 두 개의 목록 요소, 즉 $_
, 입력 요소 및 1
반환합니다. 일단리스트 평탄화를 설명하면 결과는 다음과 같습니다. map { $_ => 1 } @elems
(x => 1, y => 1, x => 1, z => 1, t => 1)
qw(xyxzt)
(x => 1, y => 1, x => 1, z => 1, t => 1)
.
이러한 요소가 해시에 할당되면 홀수 요소가 해시 키가되고 심지어 요소가 해시 값이됩니다. 키가 목록에서 해시에 할당되도록 여러 번 지정되면 마지막 값이 우선합니다. 이렇게하면 중복을 효과적으로 파기합니다.
목록을 해시로 변환하는 더 빠른 방법은 해시 조각에 할당을 사용합니다. x
연산자를 사용하여 단일 요소 목록 (1)
에 @elems
의 크기를 @elems
때문에 슬라이스의 각 키에 대해 왼쪽에 1
값이 있습니다.
@elems = qw(x y x z t);
my %set;
@set{@elems} = (1) x @elems;
다음 해시 응용 프로그램은 해시 및 목록을 종종 상호 교환 적으로 사용하여 명명 된 함수 args를 구현할 수 있다는 사실을 이용합니다.
sub hash_args {
my %args = @_;
my %defaults = (foo => 1, bar => 0);
my %overrides = (__unsafe => 0);
my %settings = (%defaults, %args, %overrides);
}
# This function can then be called like this:
hash_args(foo => 5, bar => 3); # (foo => 5, bar => 3, __unsafe ==> 0)
hash_args(); # (foo => 1, bar => 0, __unsafe ==> 0)
hash_args(__unsafe => 1) # (foo => 1, bar => 0, __unsafe ==> 0)
부울로 사용할 때 해시는 비어 있지 않은 경우 true입니다.
스칼라 참조
참조 는 다른 데이터를 "참조"하는 스칼라 변수 ( $
앞에 붙는 변수)입니다.
my $value = "Hello";
my $reference = \$value;
print $value; # => Hello
print $reference; # => SCALAR(0x2683310)
참조 된 데이터를 가져 오려면 참조를 해제 하십시오.
say ${$reference}; # Explicit prefix syntax
say $$reference; # The braces can be left out (confusing)
새로운 postfix 역 참조 구문, v5.24에서 기본적으로 사용 가능
use v5.24;
say $reference->$*; # New postfix notation
이 "참조 해제 된 값"은 원래 변수와 같이 변경할 수 있습니다.
${$reference} =~ s/Hello/World/;
print ${$reference}; # => World
print $value; # => World
참조는 항상 거짓입니다 ( 0
또는 ""
처럼).
스칼라 참조를 원할 수도 있습니다.
함수에 문자열을 전달하고 반환 값없이 문자열을 수정해야합니다.
Perl이 함수 전달의 어떤 지점에서 큰 문자열의 내용을 암시 적으로 복사하는 것을 명시 적으로 피하기를 원합니다 (특히 Copy-On-Write 문자열이없는 이전 Perl과 관련 있음)
내용을 전달하는 문자열에서 특정 의미로 문자열과 같은 값을 구별하려고합니다. 예를 들면 다음과 같습니다.
- 파일 내용에서 파일 이름 모호성 제거
- 반환 된 오류 문자열에서 반환 된 내용을 명확히합니다.
호출 코드로 전달 된 객체가 사용자에게 표시되는 메타 데이터를 전달하지 않는 경량의 내부 객체 모델을 구현하고자합니다.
our %objects; my $next_id = 0; sub new { my $object_id = $next_id++; $objects{ $object_id } = { ... }; # Assign data for object my $ref = \$object_id; return bless( $ref, "MyClass" ); }
배열 참조
배열 참조는 배열을 참조하는 스칼라 ( $
)입니다.
my @array = ("Hello"); # Creating array, assigning value from a list
my $array_reference = \@array;
이것들은 다음과 같이 더 짧게 만들 수 있습니다 :
my $other_array_reference = ["Hello"];
배열 참조를 수정 / 사용하려면 우선 참조 해제가 필요합니다.
my @contents = @{ $array_reference }; # Prefix notation
my @contents = @$array_reference; # Braces can be left out
새로운 postfix 역 참조 구문, v5.24에서 기본적으로 사용 가능
use v5.24;
my @contents = $array_reference->@*; # New postfix notation
index에 의해 arrayref의 내용에 접근 할 때, ->
syntax sugar를 사용할 수있다.
my @array = qw(one two three); my $arrayref = [ qw(one two three) ]
my $one = $array[0]; my $one = $arrayref->[0];
배열과 달리 arrayrefs는 중첩 될 수 있습니다.
my @array = ( (1, 0), (0, 1) ) # ONE array of FOUR elements: (1, 0, 0, 1)
my @matrix = ( [1, 0], [0, 1] ) # an array of two arrayrefs
my $matrix = [ [0, 1], [1, 0] ] # an arrayref of arrayrefs
# There is no namespace conflict between scalars, arrays and hashes
# so @matrix and $matrix _both_ exist at this point and hold different values.
my @diagonal_1 = ($matrix[0]->[1], $matrix[1]->[0]) # uses @matrix
my @diagonal_2 = ($matrix->[0]->[1], $matrix->[1]->[0]) # uses $matrix
# Since chained []- and {}-access can only happen on references, you can
# omit some of those arrows.
my $corner_1 = $matrix[0][1]; # uses @matrix;
my $corner_2 = $matrix->[0][1]; # uses $matrix;
부울로 사용되는 경우 참조는 항상 true입니다.
해시 참조
해시 참조는 해시 데이터가 포함 된 메모리 위치에 대한 포인터를 포함하는 스칼라입니다. 스칼라는 해시 자체를 직접 가리키기 때문에 서브 루틴으로 전달 될 때 해시에 대한 변경 사항은 일반 해시와 마찬가지로 서브 루틴에 국한되지 않고 대신 글로벌입니다.
먼저 서브 루틴에 일반 해시를 전달하고 거기에서 수정할 때 어떤 일이 일어나는지 살펴 보겠습니다.
use strict;
use warnings;
use Data::Dumper;
sub modify
{
my %hash = @_;
$hash{new_value} = 2;
print Dumper("Within the subroutine");
print Dumper(\%hash);
return;
}
my %example_hash = (
old_value => 1,
);
modify(%example_hash);
print Dumper("After exiting the subroutine");
print Dumper(\%example_hash);
어떤 결과 :
$VAR1 = 'Within the subroutine';
$VAR1 = {
'new_value' => 2,
'old_value' => 1
};
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
'old_value' => 1
};
서브 루틴을 종료 한 후에도 해시는 변경되지 않습니다. 해시 자체가 아닌 해쉬의 복사본을 전달했기 때문에 모든 변경 사항은 modify 서브 루틴에 국한되었습니다.
비교해 보면 해시 참조를 전달하면 주소가 원래 해시로 전달되므로 서브 루틴 내에서 변경된 내용은 원래 해시로 변경됩니다.
use strict;
use warnings;
use Data::Dumper;
sub modify
{
my $hashref = shift;
# De-reference the hash to add a new value
$hashref->{new_value} = 2;
print Dumper("Within the subroutine");
print Dumper($hashref);
return;
}
# Create a hashref
my $example_ref = {
old_value => 1,
};
# Pass a hashref to a subroutine
modify($example_ref);
print Dumper("After exiting the subroutine");
print Dumper($example_ref);
결과는 다음과 같습니다.
$VAR1 = 'Within the subroutine';
$VAR1 = {
'new_value' => 2,
'old_value' => 1
};
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
'new_value' => 2,
'old_value' => 1
};
타입 글롭, 타입 글로브 심판, 파일 핸들 및 상수
typeglob *foo
는 $foo
, @foo
, $foo
, &foo
등 전역 변수의 내용에 대한 참조를 저장합니다. 해시처럼 액세스하여 심볼 테이블을 직접 조작 할 수 있습니다 (악마).
use v5.10; # necessary for say
our $foo = "foo";
our $bar;
say ref *foo{SCALAR}; # SCALAR
say ${ *foo{SCALAR} }; # bar
*bar = *foo;
say $bar; # bar
$bar = 'egg';
say $foo; # egg
Typeglob은 파일을 다룰 때보다 일반적으로 처리됩니다. 예를 들어, open
은 비 전역 파일 핸들을 생성하라는 메시지가 표시 될 때 typeglob에 대한 참조를 생성합니다.
use v5.10; # necessary for say
open(my $log, '> utf-8', '/tmp/log') or die $!; # open for writing with encoding
say $log 'Log opened';
# You can dereference this globref, but it's not very useful.
say ref $log; # GLOB
say (*{$log}->{IO} // 'undef'); # undef
close $log or die $!;
use constant
가 더 널리 사용되지만 Typeglob을 사용하여 전역 읽기 전용 변수를 만들 수도 있습니다.
# Global constant creation
*TRUE = \('1');
our $TRUE;
say $TRUE; # 1
$TRUE = ''; # dies, "Modification of a read-only value attempted"
# use constant instead defines a parameterless function, therefore it's not global,
# can be used without sigils, can be imported, but does not interpolate easily.
use constant (FALSE => 0);
say FALSE; # 0
say &FALSE; # 0
say "${\FALSE}"; # 0 (ugh)
say *FALSE{CODE}; # CODE(0xMA1DBABE)
# Of course, neither is truly constant when you can manipulate the symbol table...
*TRUE = \('');
use constant (EVIL => 1);
*FALSE = *EVIL;
시길즈
Perl에는 많은 수의 sigils가 있습니다.
$scalar = 1; # individual value
@array = ( 1, 2, 3, 4, 5 ); # sequence of values
%hash = ('it', 'ciao', 'en', 'hello', 'fr', 'salut'); # unordered key-value pairs
&function('arguments'); # subroutine
*typeglob; # symbol table entry
이들은 sigils처럼 보이지만 그렇지 않습니다.
\@array; # \ returns the reference of what's on the right (so, a reference to @array)
$#array; # this is the index of the last element of @array
그렇게 기울여야한다면 sigil 다음에 중괄호를 사용할 수 있습니다. 간혹 가독성이 향상됩니다.
say ${value} = 5;
서로 다른 유형의 변수를 정의하는 데 다른 sigils를 사용하는 반면, 동일한 변수는 사용하는 sigils를 기반으로 다양한 방식으로 액세스 할 수 있습니다.
%hash; # we use % because we are looking at an entire hash
$hash{it}; # we want a single value, however, that's singular, so we use $
$array[0]; # likewise for an array. notice the change in brackets.
@array[0,3]; # we want multiple values of an array, so we instead use @
@hash{'it','en'}; # similarly for hashes (this gives the values: 'ciao', 'hello')
%hash{'it','fr'}; # we want an hash with just some of the keys, so we use %
# (this gives key-value pairs: 'it', 'ciao', 'fr', 'salut')
이것은 특히 참조에 해당됩니다. 참조 된 값을 사용하기 위해 함께 sigils를 결합 할 수 있습니다.
my @array = 1..5; # This is an array
my $reference_to_an_array = \@array; # A reference to an array is a singular value
push @array, 6; # push expects an array
push @$reference_to_an_array, 7; # the @ sigil means what's on the right is an array
# and what's on the right is $reference_to_an_array
# hence: first a @, then a $
여기에 대해 생각하는 것이 덜 혼란 스럽습니다. 이전에 보았 듯이 중괄호를 사용하여 sigil의 오른쪽에있는 것을 감쌀 수 있습니다. 따라서 @{}
을 배열 참조를 취하여 참조 된 배열로 생각할 수 있습니다.
# pop does not like array references
pop $reference_to_an_array; # ERROR in Perl 5.20+
# but if we use @{}, then...
pop @{ $reference_to_an_array }; # this works!
사실, @{}
실제로 표현식을 허용합니다.
my $values = undef;
say pop @{ $values }; # ERROR: can't use undef as an array reference
say pop @{ $values // [5] } # undef // [5] gives [5], so this prints 5
... 그리고 같은 속임수가 다른 sigils에도 적용됩니다.
# This is not an example of good Perl. It is merely a demonstration of this language feature
my $hashref = undef;
for my $key ( %{ $hashref // {} } ) {
"This doesn't crash";
}
...하지만 sigil에 대한 "인수"가 단순하면 중괄호를 멀리 둘 수 있습니다.
say $$scalar_reference;
say pop @$array_reference;
for keys (%$hash_reference) { ... };
과도하게 사치스럽게됩니다. 이것은 효과가 있지만 Perl에게 책임감을주십시오.
my %hash = (it => 'ciao', en => 'hi', fr => 'salut');
my $reference = \%hash;
my $reference_to_a_reference = \$reference;
my $italian = $hash{it}; # Direct access
my @greets = @$reference{'it', 'en'}; # Dereference, then access as array
my %subhash = %$$reference_to_a_reference{'en', 'fr'} # Dereference ×2 then access as hash
대부분의 정상적인 사용을 위해, 당신은 sigil없이 서브 루틴 이름을 사용할 수 있습니다. (sigil이없는 변수는 일반적으로 "barewords"라고합니다.) &
sigil은 제한된 경우에만 유용합니다.
서브 루틴에 대한 참조 만들기 :
sub many_bars { 'bar' x $_[0] } my $reference = \&many_bars; say $reference->(3); # barbarbar
프로토 타입을 무시하고 함수를 호출합니다.
goto와 결합하여, 현재 호출 프레임이 호출자로 대체 된 약간 이상한 함수 호출입니다. 리눅스
exec()
API 호출을 생각해보십시오.