이것은 Ubuntu Online, Fedora Online, Windows 온라인 에뮬레이터 또는 MAC OS 온라인 에뮬레이터와 같은 여러 무료 온라인 워크스테이션 중 하나를 사용하여 OnWorks 무료 호스팅 공급자에서 실행할 수 있는 명령 perlref입니다.
프로그램:
이름
perlref - Perl 참조 및 중첩 데이터 구조
주의사항
이것은 참조의 모든 측면에 대한 완전한 문서입니다. 더 짧은 튜토리얼
필수 기능에 대한 소개는 perlrefut을 참조하십시오.
기술
Perl 릴리스 5 이전에는 복잡한 데이터 구조를 표현하는 것이 어려웠습니다.
모든 참조는 상징적이어야 했습니다. 그리고 그때도 변수를 참조하는 것은 어려웠습니다.
기호 테이블 항목 대신. Perl은 이제 심볼릭을 더 쉽게 사용할 수 있게 해줍니다.
변수에 대한 참조뿐 아니라 모든 데이터 또는
암호. 모든 스칼라는 하드 참조를 보유할 수 있습니다. 배열과 해시에는 스칼라가 포함되어 있기 때문에
이제 배열의 배열, 해시의 배열, 배열의 해시, 배열의 배열을 쉽게 구축할 수 있습니다.
함수의 해시 등.
하드 참조는 스마트합니다. 자동으로 참조 횟수를 추적합니다.
참조 횟수가 XNUMX이 될 때 참조되는 것을 해제합니다. (참조 횟수
자체 참조 또는 순환 데이터 구조의 값은 다음 없이는 XNUMX이 될 수 없습니다.
약간의 도움; 자세한 설명은 "순환 참조"를 참조하십시오.) 그런 일이 발생하면
객체가 되려면 객체가 파괴됩니다. 객체에 대한 자세한 내용은 perlobj를 참조하세요. (안에
의미, Perl의 모든 것은 객체이지만 일반적으로 참조용으로 단어를 예약합니다.
클래스 패키지에 공식적으로 "축복된" 개체.)
기호 참조는 변수 또는 기타 객체의 이름입니다.
Unix 파일 시스템에는 파일 이름만 포함됩니다. *glob 표기법은
상징적 참조. (기호 참조는 "소프트 참조"라고도 하지만
그렇게 부르지 마세요. 참조는 쓸모없는 동의어 없이 충분히 혼란스럽습니다.)
대조적으로 하드 참조는 Unix 파일 시스템의 하드 링크와 비슷합니다.
(다른) 이름이 무엇인지 걱정하지 않고 기본 개체에 액세스합니다. 때
"참조"라는 단어는 다음 단락에서와 같이 형용사 없이 사용됩니다.
일반적으로 하드 참조에 대해 이야기합니다.
참조는 Perl에서 사용하기 쉽습니다. 우선 원칙은 단 하나입니다. 일반적으로,
Perl은 암시적 참조 또는 역참조를 하지 않습니다. 스칼라가 참조를 들고 있을 때,
항상 단순 스칼라처럼 작동합니다. 마술처럼 배열이나 해시가 되기 시작하지 않습니다.
또는 서브루틴; 역참조를 통해 명시적으로 그렇게 하도록 지시해야 합니다.
즉, Perl 버전 5.14에서는 규칙에 대한 예외가 도입되었습니다.
구문상의 편리함. 실험적 배열 및 해시 컨테이너 기능 동작은
배열 및 해시 참조가 명시적으로 처리된 것처럼 Perl에서 처리됩니다.
구문적으로 역참조됨. perl5140delta 및 perlfunc의 "구문 향상"을 참조하십시오.
를 참조하세요
유튜브 영상을 만드는 것은 참고자료
참조는 여러 가지 방법으로 만들 수 있습니다.
1. 변수, 서브루틴 또는 값에 백슬래시 연산자를 사용합니다. (이것은 많이 작동합니다
C의 &(address-of) 연산자와 같습니다.) 이것은 일반적으로 다음을 생성합니다. 다른 에 대한 참조
변수에 대한 참조가 이미 기호 테이블에 있기 때문입니다.
그러나 기호 테이블 참조가 사라질 수 있으며 여전히
백슬래시가 반환되었습니다. 여기 몇 가지 예가 있어요.
$scalarref = \$foo;
$arrayref = \@ARGV;
$hashref = \%ENV;
$coderef = \&핸들러;
$globref = \*foo;
IO 핸들(filehandle 또는 dirhandle)에 대한 진정한 참조를 생성하는 것은 불가능합니다.
백슬래시 연산자를 사용합니다. 가장 많이 얻을 수 있는 것은 typeglob에 대한 참조입니다.
이것은 실제로 완전한 기호 테이블 항목입니다. 하지만 의 설명을 참조하십시오
*foo{THING} 구문은 아래에 있습니다. 그러나 여전히 유형 globs 및 globrefs를 다음과 같이 사용할 수 있습니다.
비록 그들이 IO 핸들이었지만.
2. 대괄호를 사용하여 익명 배열에 대한 참조를 만들 수 있습니다.
$arrayref = [1, 2, ['a', 'b', 'c']];
여기서 우리는 최종적으로
요소 자체는 세 요소의 다른 익명 배열에 대한 참조입니다. (그만큼
나중에 설명하는 다차원 구문을 사용하여 이에 액세스할 수 있습니다. 예를 들어,
위의 이후에 "$arrayref->[2][1]"은 "b" 값을 갖습니다.)
열거된 목록을 참조하는 것은 정사각형을 사용하는 것과 동일하지 않습니다.
대괄호 -- 대신 참조 목록을 만드는 것과 동일합니다!
@목록 = (\$a, \@b, \%c);
@목록 = \($a, @b, %c); # 같은 것!
특별한 경우로 "\(@foo)"는 @foo의 내용에 대한 참조 목록을 반환합니다.
@foo 자체에 대한 참조. 키 참조가
복사본(키는 완전한 스칼라가 아니라 문자열일 뿐이기 때문에).
3. 중괄호를 사용하여 익명 해시에 대한 참조를 만들 수 있습니다.
$hashref = {
'아담' => '이브',
'클라이드' => '보니',
};
이와 같은 익명 해시 및 배열 작성기를 자유롭게 혼합하여 다음과 같이 생성할 수 있습니다.
원하는대로 복잡한 구조. 아래에 설명된 다차원 구문
이들에게도 작동합니다. 위의 값은 리터럴이지만 변수 및 표현식
Perl의 할당 연산자(심지어 현지의() or
나의())는 컴파일 타임 선언이 아니라 실행 가능한 명령문입니다.
중괄호(중괄호)는 BLOCK을 비롯한 여러 가지 용도로 사용되기 때문에,
때때로 다음과 같이 명령문의 시작 부분에서 중괄호를 명확하게 해야 할 수도 있습니다.
Perl이 여는 중괄호가 아니라는 것을 깨닫도록 "+" 또는 "return"을 앞에 두십시오.
블록을 시작합니다. 컬리 사용의 경제성과 니모닉 가치는 가치가 있는 것으로 간주됩니다.
이 가끔 추가 번거로움.
예를 들어, 함수가 새로운 해시를 만들고 이에 대한 참조를 반환하도록 하려면,
다음과 같은 옵션이 있습니다.
sub hashhem { { @_ } } # 조용히 잘못된
하위 해시 { +{ @_ } } # 확인
하위 해시 { return { @_ } } # 확인
반면에 다른 의미를 원하면 다음과 같이 할 수 있습니다.
sub showem { { @_ } } # 모호함(현재 ok,
# 변경될 수 있음)
하위 showem { {; @_ } } # 확인
sub showem { { 반환 @_ } } # 확인
선행 "+{" 및 "{;" 항상 다음 중 하나를 의미하는 표현을 명확하게 하는 역할을 합니다.
HASH 참조 또는 BLOCK.
4. 익명 서브루틴에 대한 참조는 "sub"를 사용하여 생성할 수 있습니다.
하위 이름:
$coderef = sub { print "Boink!\n" };
세미콜론에 유의하십시오. 내부의 코드가 즉시 실행되지 않는 것을 제외하고는 "sub
{}"는 선언이라기 보다는 "do{}" 또는 "eval{}"과 같은 연산자입니다.
(그러나 그 특정 줄을 몇 번이나 실행하든 상관없이
"eval("...")"), $coderef는 여전히 같은 익명
서브루틴.)
익명 서브루틴은 다음과 관련하여 클로저 역할을 합니다. 나의() 변수, 즉,
현재 범위 내에서 어휘적으로 볼 수 있는 변수. 폐쇄는 외부의 개념입니다.
특정 어휘에 익명 함수를 정의하면 리스프 세계
컨텍스트, 컨텍스트 외부에서 호출되는 경우에도 해당 컨텍스트에서 실행되는 척합니다.
인간의 관점에서 정의할 때 서브루틴에 인수를 전달하는 재미있는 방법입니다.
당신이 그것을 부를 때뿐만 아니라. 실행할 약간의 코드를 설정하는 데 유용합니다.
나중에, 예를 들어 콜백. Perl을 사용하여 객체 지향 작업을 수행할 수도 있습니다.
이미 다른 메커니즘을 제공하고 있습니다. perlobj를 참조하세요.
클로저를 사용하지 않고 서브루틴 템플릿을 작성하는 방법으로 생각할 수도 있습니다.
eval (). 다음은 클로저 작동 방식에 대한 작은 예입니다.
하위 신간 {
내 $x = 시프트;
return sub { 내 $y = shift; 인쇄 "$x, $y!\n"; };
}
$h = newprint("안녕하세요");
$g = newprint("인사드립니다");
# 시간이 흘러...
&$h("세계");
&$g("지구인");
이것은 인쇄
안녕, 세상!
안녕, 지구인들이여!
특히 $x는 다음으로 전달된 값을 계속 참조합니다. 새 인쇄()
에도 불구하고 "my $x"는 익명 서브루틴이 실행될 때 범위를 벗어났습니다.
그것이 바로 클로저의 전부입니다.
그건 그렇고, 이것은 어휘 변수에만 적용됩니다. 동적 변수는 계속
그들이 항상 일했던 것처럼 일하십시오. 클로저는 대부분의 Perl 프로그래머가
처음부터 문제가 필요합니다.
5. 참조는 종종 생성자라고 하는 특별한 서브루틴에 의해 반환됩니다. 펄
객체는 우연히 알게 된 특별한 유형의 객체에 대한 참조일 뿐입니다.
관련된 패키지입니다. 생성자는 방법을 알고 있는 특별한 서브루틴일 뿐입니다.
그 협회를 만들기 위해. 그들은 일반적인 참조로 시작하여 그렇게 하며,
객체이기도 한 동안에도 일반 참조로 유지됩니다. 생성자는
종종 "new()"로 명명됩니다. 너 간접적으로 호출:
$objref = new Doggie( 꼬리 => '짧은', 귀 => '긴' );
그러나 특정 경우에 모호한 구문을 생성할 수 있으므로 종종 다음을 사용하는 것이 좋습니다.
직접 메서드 호출 방식:
$objref = 강아지->new(꼬리 => '짧은', 귀 => '긴');
용어 사용::캡;
$terminal = Term::Cap->Tgetent({ OSPEED => 9600 });
사용 Tk;
$main = MainWindow->new();
$menubar = $main->Frame(-relief => "올려진",
-테두리 너비 => 2)
6. 역참조하면 적절한 유형의 참조가 생겨날 수 있습니다.
존재한다고 가정하는 맥락에서. 우리는 역참조에 대해 이야기하지 않았기 때문에
아직, 우리는 당신에게 어떤 예도 보여줄 수 없습니다.
7. 참조는 다음과 같이 잘 알려진 특수 구문을 사용하여 만들 수 있습니다.
*foo{THING} 구문. *foo{THING}은 *foo의 THING 슬롯에 대한 참조를 반환합니다(
foo로 알려진 모든 것을 보유하는 기호 테이블 항목입니다.
$scalarref = *foo{SCALAR};
$arrayref = *ARGV{ARRAY};
$hashref = *ENV{해시};
$coderef = *핸들러{CODE};
$ioref = *STDIN{IO};
$globref = *foo{GLOB};
$formatref = *foo{포맷};
$globname = *foo{이름}; # "푸"
$pkgname = *foo{패키지}; # "기본"
대부분은 자명하지만 *foo{IO}는 특별한 주의를 기울일 필요가 있습니다. 그것
파일 핸들(perlfunc의 "열기"), 소켓("소켓")에 사용되는 IO 핸들을 반환합니다.
perlfunc의 "socketpair" 및 perlfunc의 경우 디렉토리 핸들("opendir"의 경우)
펄펑). 이전 버전의 Perl과의 호환성을 위해 *foo{FILEHANDLE}은
*foo{IO}의 동의어이지만 5.8.0부터 더 이상 사용되지 않습니다. 지원 중단 경고가 있는 경우
효력이 발생하면 그 사용에 대해 경고할 것입니다.
*foo{THING}은 특정 THING이 아직 사용되지 않은 경우 undef를 반환합니다.
스칼라의 경우. *foo{SCALAR}는 $foo인 경우 익명 스칼라에 대한 참조를 반환합니다.
아직 사용되지 않았습니다. 이는 향후 릴리스에서 변경될 수 있습니다.
*foo{NAME} 및 *foo{PACKAGE}는 문자열을 반환한다는 점에서 예외입니다.
참조보다. 이들은 typeglob 자체의 패키지와 이름을 반환합니다.
할당된 것보다. 따라서 "*foo=*Foo::bar" 뒤에 *foo는
"*Foo::bar"는 문자열로 사용되지만 *foo{PACKAGE} 및 *foo{NAME}은 계속
각각 "main"과 "foo"를 생성합니다.
*foo{IO}는 "Typeglobs 및
파일 핸들을 서브루틴 안팎으로 전달하기 위한 perldata의 "파일 핸들", 또는
더 큰 데이터 구조에 저장합니다. 그것의 단점은 새로운 것을 만들지 않는다는 것입니다.
당신을 위한 파일 핸들. 그것의 장점은 당신이보다 더 clobbering의 위험이 적다는 것입니다.
당신은 typeglob 할당을 원합니다. (여전히 파일과 디렉토리를 병합합니다.
처리합니다.) 그러나 들어오는 값을 대신 스칼라에 할당하면
아래 예에서와 같이 typeglob을 사용하면 그런 일이 발생할 위험이 없습니다.
스플러터(*STDOUT); # 전체 글로브 전달
스플러터(*STDOUT{IO}); # 파일 및 디렉토리 핸들을 모두 전달합니다.
서브 스플러터 {
내 $fh = 시프트;
print $fh "음 음 음 음\n";
}
$rec = get_rec(*STDIN); # 전체 글로브 전달
$rec = get_rec(*STDIN{IO}); # 파일 및 디렉토리 핸들을 모두 전달합니다.
하위 get_rec {
내 $fh = 시프트;
반환 스칼라 <$fh>;
}
사용 참고자료
참조를 생성하기 위한 것입니다. 지금쯤이면 사용 방법을 알고 싶어 죽을 것입니다.
오래 전에 잃어버린 데이터로 돌아가기 위한 참조. 몇 가지 기본 방법이 있습니다.
1. 식별자(또는 식별자 체인)를 변수의 일부로 배치하거나
서브루틴 이름, 식별자를 간단한 스칼라 변수로 바꿀 수 있습니다.
올바른 유형의 참조 포함:
$bar = $$scalarref;
푸시(@$arrayref, $파일명);
$$arrayref[0] = "XNUMX월";
$$hashref{"KEY"} = "값";
&$coderef(1,2,3);
print $globref "출력\n";
우리가 구체적으로 지원 $arrayref[0] 역참조
또는 $hashref{"KEY"}가 있습니다. 스칼라 변수의 역참조가 발생합니다. 전에 it
모든 키 조회를 수행합니다. 단순한 스칼라 변수보다 더 복잡한 것은 반드시
아래 방법 2 또는 3을 사용하십시오. 그러나 "단순 스칼라"에는 다음과 같은 식별자가 포함됩니다.
자체적으로 방법 1을 재귀적으로 사용합니다. 따라서 다음은 "howdy"를 인쇄합니다.
$refrefref = \\"안녕하세요";
$$$$refrefref 인쇄;
2. 식별자(또는 식별자 체인)를 변수의 일부로 배치하거나
서브루틴 이름에서 식별자를 참조를 반환하는 BLOCK으로 바꿀 수 있습니다.
올바른 유형. 즉, 이전 예제는 다음과 같이 작성할 수 있습니다.
$bar = ${$scalarref};
푸시(@{$arrayref}, $파일명);
${$arrayref}[0] = "XNUMX월";
${$hashref}{"KEY"} = "값";
&{$coderef}(1,2,3);
$globref->print("출력\n"); # IO::핸들이 로드된 경우
물론 이 경우에 곱슬머리를 사용하는 것은 약간 어리석은 일이지만 BLOCK은
임의의 표현식, 특히 아래 첨자 표현식을 포함합니다.
&{ $디스패치{$인덱스} }(1,2,3); # 올바른 루틴 호출
$$x의 간단한 경우에 중괄호를 생략할 수 있기 때문에 사람들은 종종
역참조 기호를 적절한 연산자로 보는 실수를 하고
그들의 우선 순위에 대해. 그러나 그렇다면 대신 괄호를 사용할 수 있습니다.
바지 멜빵. 그렇지 않습니다. 아래의 차이점을 고려하십시오. 사례 0은 약식입니다.
사례 1의 버전, 지원 2의 경우 :
$$hashref{"KEY"} = "값"; # 사례 0
${$hashref}{"KEY"} = "값"; # 사례 1
${$hashref{"KEY"}} = "값"; # 사례 2
${$hashref->{"KEY"}} = "값"; # 사례 3
사례 2는 또한 %hashref라는 변수에 액세스한다는 점에서 기만적입니다.
$hashref를 통해 참조하는 해시에 대한 역참조. 그럴거야
사례 3.
3. 개별 배열 요소의 서브루틴 호출 및 조회가 충분히 자주 발생합니다.
방법 2를 사용하기가 번거로워집니다. 구문 설탕의 한 형태로,
방법 2는 다음과 같이 작성할 수 있습니다.
$arrayref->[0] = "XNUMX월"; # 배열 요소
$hashref->{"KEY"} = "값"; # 해시 요소
$coderef->(1,2,3); # 서브루틴 호출
화살표의 왼쪽은 다음을 포함하여 참조를 반환하는 표현식일 수 있습니다.
이전 역참조. $array[$x]는 지원 "$array->[$x]"와 동일
이벤트 예약 링크:
$array[$x]->{"foo"}->[0] = "XNUMX월";
이것은 참조가 다음과 같이 나타날 수 있는 앞에서 언급한 경우 중 하나입니다.
lvalue 컨텍스트에 있을 때 존재합니다. 이 명령문 이전에는 $array[$x]가
찾으시는 주소가 없습니다. 그렇다면 해시 참조로 자동 정의되므로
"{"foo"}"를 찾아보세요. 마찬가지로 "$array[$x]->{"foo"}"는 자동으로
배열 참조로 정의되어 "[0]"을 찾을 수 있습니다. 이 과정은
라는 자가생존.
여기서 한 가지 더. 화살표는 선택 사항입니다 사이에 대괄호 아래 첨자를 사용하여
위를 아래로 축소
$array[$x]{"foo"}[0] = "XNUMX월";
일반 배열만 사용하는 퇴화한 경우에는 다음을 제공합니다.
C와 같은 다차원 배열:
$점수[$x][$y][$z] += 42;
글쎄요. 사실 C의 배열과 완전히 같지는 않습니다. C는 성장하는 방법을 모릅니다.
주문형 어레이. 펄이 그렇습니다.
4. 참조가 개체에 대한 참조인 경우 다음과 같은 메서드가 있을 수 있습니다.
참조된 항목에 액세스하려면 해당 방법을 고수해야 합니다.
개체의 메서드를 정의하는 클래스 패키지에 있지 않는 한. 다시 말해,
좋은 이유 없이 객체의 캡슐화를 위반하지 마십시오.
Perl은 캡슐화를 시행하지 않습니다. 우리는 여기에서 전체주의자가 아닙니다. 우리는 기대한다
그래도 기본적인 예의.
문자열이나 숫자를 참조로 사용하면 위에서 설명한 대로 기호 참조가 생성됩니다.
참조를 숫자로 사용하면 저장 위치를 나타내는 정수가 생성됩니다.
메모리. 이것으로 수행할 수 있는 유일한 유용한 것은 두 참조를 비교하는 것입니다.
동일한 위치를 참조하는지 여부를 숫자로 확인합니다.
if ($ref1 == $ref2) { # 참조의 저렴한 수치 비교
print "refs 1과 2는 같은 것을 참조합니다\n";
}
참조를 문자열로 사용하면 모든 패키지를 포함하여 참조 대상의 유형이 모두 생성됩니다.
perlobj에 설명된 축복과 XNUMX진수로 표현된 숫자 주소. 그만큼
참조() 연산자는 참조가 가리키는 유형만 반환합니다.
주소. 자세한 내용과 사용 예는 perlfunc의 "ref"를 참조하십시오.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 신을 하다() 연산자는 참조 지점을 대상과 연결하는 데 사용할 수 있습니다.
패키지는 객체 클래스로 작동합니다. perlobj를 참조하십시오.
typeglob은 참조와 같은 방식으로 역참조될 수 있습니다.
구문은 항상 원하는 참조 유형을 나타냅니다. 따라서 "${*foo}" 및 "${\$foo}" 둘 다
동일한 스칼라 변수를 나타냅니다.
다음은 서브루틴 호출을 문자열로 보간하는 트릭입니다.
print "내 서브는 그 때 @{[mysub(1,2,3)]}을 반환했습니다.\n";
작동 방식은 "@{...}"가 큰따옴표 문자열에 표시되면
블록으로 평가됩니다. 블록은 다음을 포함하는 익명 배열에 대한 참조를 생성합니다.
"mysub(1,2,3)" 호출 결과. 따라서 전체 블록은
그런 다음 "@{...}"에 의해 역참조되고 큰따옴표로 묶인 문자열에 고정됩니다.
이 속임수는 임의의 표현에도 유용합니다.
print "@{[$n + 5]} 위젯을 생성합니다\n";
유사하게, 스칼라에 대한 참조를 반환하는 표현식은 다음을 통해 역참조될 수 있습니다.
"${...}". 따라서 위의 식은 다음과 같이 쓸 수 있습니다.
print "${\($n + 5)} 위젯을 생성\n";
원형의 참고자료
Perl에서 "순환 참조"를 만드는 것이 가능하여 메모리 누수가 발생할 수 있습니다. ㅏ
순환 참조는 다음과 같이 두 참조가 서로에 대한 참조를 포함할 때 발생합니다.
이:
내 $foo = {};
내 $bar = { foo => $foo };
$foo->{bar} = $bar;
단일 변수로 순환 참조를 만들 수도 있습니다.
내 $foo;
$foo = \$foo;
이 경우 변수에 대한 참조 카운트는 0에 도달하지 않으며 참조는
절대 가비지 수집되지 않습니다. 이로 인해 메모리 누수가 발생할 수 있습니다.
Perl의 객체는 참조로 구현되기 때문에 순환
개체에 대한 참조도 포함됩니다. 각 노드가 해당 노드를 참조하는 TreeNode 클래스를 상상해보십시오.
부모 노드와 자식 노드. 부모가 있는 모든 노드는 순환 참조의 일부가 됩니다.
"약한 참조"를 만들어 순환 참조를 끊을 수 있습니다. 약한 참조는
변수에 대한 참조 횟수를 증가시키지 않습니다. 이는 개체가 나갈 수 있음을 의미합니다.
범위 및 파괴. 내보낸 "weak" 기능으로 참조를 약화시킬 수 있습니다.
Scalar::Util 모듈에 의해.
첫 번째 예를 더 안전하게 만드는 방법은 다음과 같습니다.
Scalar::Util 'weaken' 사용;
내 $foo = {};
내 $bar = { foo => $foo };
$foo->{bar} = $bar;
약화 $foo->{bar};
$foo에서 $bar로의 참조가 약화되었습니다. $bar 변수가
범위, 가비지 수집됩니다. 다음에 가치를 볼 때
"$foo->{bar}" 키, "undef"가 됩니다.
원거리에서의 이 동작은 혼란스러울 수 있으므로 사용에 주의해야 합니다.
묽게 하다. 범위를 벗어날 변수의 참조를 약화시켜야 합니다. 먼저.
그렇게 하면 수명이 더 긴 변수는 종료될 때까지 예상 참조를 포함합니다.
범위의.
상징적 인 참조
참조가 정의되지 않은 경우 필요에 따라 참조가 생성된다고 했지만,
참조로 사용되는 값이 이미 정의되어 있으면 어떻게 되는지 말하지 않았지만 아니다 a
하드 참조. 참조로 사용하면 기호 참조로 처리됩니다.
즉, 스칼라 값은 다음과 같이 간주됩니다. name 변수보다는
(아마도) 익명 값에 대한 직접 링크.
사람들은 종종 이런 식으로 작동하기를 기대합니다. 그래서 그렇습니다.
$name = "후";
$$이름 = 1; # $foo 설정
${$이름} = 2; # $foo 설정
${$이름 x 2} = 3; # $fofoo 설정
$이름->[0] = 4; # $foo[0] 설정
@$이름 = (); # @foo를 지웁니다.
&$이름(); # &foo() 호출
$pack = "그";
${"${팩}::$이름"} = 5; # eval 없이 $THAT::foo를 설정합니다.
이것은 의도할 수 있다는 점에서 강력하고 약간 위험합니다(최대한
성실) 하드 참조를 사용하고 실수로 대신 기호 참조를 사용합니다. 에게
그것에 대해 보호, 당신은 말할 수 있습니다
엄격한 '참조'를 사용하십시오.
그러면 나머지 엔클로징 블록에 대해 하드 참조만 허용됩니다. 안
내부 블록은 다음과 같이 대응할 수 있습니다.
엄격한 '참조'가 없습니다.
기호 참조에는 패키지 변수(지역화된 경우에도 전역)만 표시됩니다.
어휘 변수(로 선언 나의())은 기호 테이블에 없으므로 볼 수 없습니다.
이 메커니즘. 예를 들어:
지역 $값 = 10;
$ref = "값";
{
내 $ 값 = 20;
$$ref 인쇄;
}
이것은 여전히 10이 아닌 20을 인쇄합니다. 현지의() 패키지 변수에 영향을 미치며,
패키지에 대해 모두 "전역적"입니다.
그다지 상징적이지 않은 참조
기호 참조 주위의 대괄호는 단순히 식별자 또는 변수를 분리하는 역할을 할 수 있습니다.
문자열 내에서 항상 있는 것처럼 표현식의 나머지 부분에서 이름을 가져옵니다. 을위한
예,
$push = "팝업";
"${푸시}오버" 인쇄;
push가 예약어임에도 불구하고 항상 "pop on over"를 인쇄하는 것을 의미했습니다. 이것은
큰 따옴표를 묶지 않고 동일하게 작동하도록 일반화하여
인쇄 ${푸시} . "위에";
심지어
인쇄 ${ 푸시 } . "위에";
같은 효과가 있을 것입니다. 이 구성은 지원 상징적 인 참조로 간주
엄격한 참조를 사용할 때:
엄격한 '참조'를 사용하십시오.
${ 베어워드 }; # 좋아요, $bareword를 의미합니다.
${ "베어워드" }; # 오류, 기호 참조.
마찬가지로, 단일 단어를 사용하여 수행되는 모든 첨자 때문에 동일한 규칙
해시를 첨자화하는 데 사용되는 모든 베어워드에 적용됩니다. 그래서 이제 글을 쓰는 대신
$array{ "aaa" }{ "bbb" }{ "ccc" }
그냥 쓸 수 있습니다
$array{ aaa }{ bbb }{ 참조 }
그리고 아래 첨자가 예약어인지 걱정하지 마십시오. 당신이 드문 경우에
같은 일을 하고 싶어
$array{ 시프트 }
그 이상으로 만드는 모든 것을 추가하여 예약어로 해석을 강제할 수 있습니다.
베어워드:
$배열{시프트()}
$배열{ +시프트 }
$배열{ 시프트 @_ }
"경고 사용" 프라그마 또는 -w 스위치는 예약어를 해석하면 경고합니다.
문자열로. 그러나 더 이상 소문자 단어 사용에 대해 경고하지 않습니다.
문자열은 효과적으로 인용됩니다.
의사 해시: 사용 an 정렬 as a 해시
의사 해시가 Perl에서 제거되었습니다. 'fields' pragma는 계속 사용할 수 있습니다.
함수 템플릿
위에서 설명한 대로 어휘 변수에 액세스할 수 있는 익명 함수가 표시됩니다.
해당 함수가 컴파일되면 클로저를 생성합니다. 해당 변수에 대한 액세스를 유지합니다.
신호 처리기 또는 Tk 콜백과 같이 나중에 실행될 때까지 실행되지 않더라도.
클로저를 함수 템플릿으로 사용하면 작동하는 많은 함수를 생성할 수 있습니다.
비슷하게. HTML 글꼴을 생성한 색상의 이름을 따서 명명된 함수를 원한다고 가정합니다.
다양한 색상 변경:
print "Be ", red("careful"), "with that ", green("light");
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 빨간색() and 초록() 기능은 비슷할 것입니다. 이를 만들기 위해 클로저를 할당합니다.
빌드하려는 함수 이름의 typeglob으로.
@colors = qw(빨강 파랑 초록 노랑 주황 보라색 보라색);
내 $name(@colors) {
엄격한 '참조'가 없습니다. # 기호 테이블 조작 허용
*$이름 = *{uc $이름} = 서브 { " @_ " };
}
이제 모든 다른 기능이 독립적으로 존재하는 것처럼 보입니다. 전화해도됩니다 빨간색(),
빨간색(), 푸른(), 푸른(), 초록()등. 이 기술은 컴파일 시간과 메모리를 모두 절약합니다.
구문 검사가 컴파일 시간에 발생하기 때문에 사용하고 오류가 발생하기 쉽습니다. 그것은
익명 서브루틴의 모든 변수는 다음을 생성하기 위해 어휘여야 합니다.
적절한 폐쇄. 이것이 루프 반복 변수에 "my"가 있는 이유입니다.
이것은 클로저에 프로토타입을 제공하는 것이 의미가 있는 유일한 장소 중 하나입니다. 만약에
이 함수의 인수에 스칼라 컨텍스트를 적용하고 싶었습니다(아마도
이 특정 예에 대한 현명한 아이디어) 대신 다음과 같이 작성할 수 있습니다.
*$이름 = 서브($) { " $_[0] " };
그러나 프로토타입 검사는 컴파일 시간에 발생하므로 위의 할당이 발생합니다.
많이 사용하기에는 너무 늦었습니다. 전체 루프를 넣어 이 문제를 해결할 수 있습니다.
BEGIN 블록 내에서 할당을 수행하여 컴파일 중에 강제로 발생합니다.
기본적으로 위의 "for" 루프와 같이 시간이 지남에 따라 변하는 어휘에 대한 액세스
주변 어휘 범위의 요소에 대한 별칭 -- 익명의 하위 항목에서만 작동합니다.
명명된 서브루틴이 아닙니다. 일반적으로 명명된 서브루틴은 적절하게 중첩되지 않으며
기본 패키지 범위에서만 선언해야 합니다.
이는 명명된 서브루틴이 컴파일 시간에 생성되어 어휘 변수가
부모 블록의 첫 번째 실행에서 부모 어휘에 할당됩니다. 만약
상위 범위가 두 번째로 입력되면 해당 어휘가 다시 생성되고 중첩된
서브는 여전히 이전 것을 참조합니다.
익명 서브루틴은 "sub" 연산자를 실행할 때마다 캡처됩니다.
즉석에서 생성. 다른 프로그래밍에서 중첩된 서브루틴을 사용하는 데 익숙한 경우
자체 개인 변수가 있는 언어를 사용하려면 Perl에서 약간 작업해야 합니다. 그만큼
이러한 유형의 직관적인 코딩은 "남지 않을 것"에 대한 신비한 경고를 발생시킵니다.
공유"는 위에서 설명한 이유로 인해 발생합니다. 예를 들어 다음은 작동하지 않습니다.
하위 외부 {
내 $x = $_[0] + 35;
하위 내부 { 반환 $x * 19 } # 잘못된
반환 $x + inner();
}
해결 방법은 다음과 같습니다.
하위 외부 {
내 $x = $_[0] + 35;
지역 * 내부 = sub { $x * 19 반환 };
반환 $x + inner();
}
현재 안의() 내부에서만 호출할 수 있습니다. 밖의(), 임시 할당 때문에
익명 서브루틴의 그러나 그럴 때 어휘에 정상적으로 액세스할 수 있습니다.
범위에서 변수 $x 밖의() 외부가 호출될 때.
이것은 다른 함수에 로컬인 함수를 생성하는 흥미로운 효과가 있습니다.
Perl에서 일반적으로 지원되지 않는 것.
경고
해시에 대한 키로 참조를 (유용하게) 사용할 수 없습니다. 로 전환됩니다.
끈:
$x{ \$a } = $a;
키를 역참조하려고 하면 하드 역참조가 수행되지 않으며
당신이 시도하는 것을 성취하십시오. 다음과 같은 것을 더 원할 수도 있습니다.
$r = \@a;
$x{ $r } = $r;
그리고 적어도 당신은 사용할 수 있습니다 값 (), 대신 실제 심판이 될 것입니다.
키 (), 그렇지 않습니다.
표준 Tie::RefHash 모듈은 이에 대한 편리한 해결 방법을 제공합니다.
후위 역참조 통사론
v5.20.0부터 참조를 사용하기 위한 접미사 구문을 사용할 수 있습니다. 그것은 다음과 같이 행동합니다
"참조 사용"에 설명되어 있지만 접두사가 붙은 sigil 대신에 접미사가 붙은 sigil-and-
별이 사용됩니다.
예 :
$r = \@a;
@b = $r->@*; # @$r 또는 @{ $r }과 동일
$r = [ 1, [ 2, 3 ], 4 ];
$r->[1]->@*; # @{ $r->[1] }과 동일
이 구문은 "'postderef' 기능 사용"으로 활성화해야 합니다. 실험적이며 앞으로
"no warnings 'experimental::postderef'"가 적용되지 않는 한 기본적으로 경고합니다.
접미사 역참조는 블록(접미어) 역참조가 있는 모든 상황에서 작동해야 합니다.
작동하며 완전히 동일해야 합니다. 이 구문을 사용하면 역참조를 작성할 수 있습니다.
그리고 완전히 왼쪽에서 오른쪽으로 읽습니다. 다음 동등성이 정의됩니다.
$sref->$*; # ${ $sref }와 동일
$aref->@*; # @{ $aref }와 동일
$aref->$#*; # $#{ $aref }와 동일
$href->%*; # %{ $href }와 동일
$cref->&*; # &{ $cref }와 동일
$gref->**; # *{ $gref }와 동일
특히 "$cref->&*"는 지원 "$cref->()"와 동일하며 다른 서비스를 제공할 수 있습니다.
목적.
Glob 요소는 후위 역참조 기능을 통해 추출할 수 있습니다.
$gref->*{스칼라}; # *{ $gref }{SCALAR}과 동일
접미사 배열 및 스칼라 역참조 문자열을 보간하는 데 사용됩니다(큰따옴표
또는 "qq" 연산자), 추가 "postderef_qq" 기능이 활성화된 경우에만 가능합니다.
후위 참조 슬라이스
배열 및 해시의 값 조각은 접미사 역참조 표기법을 사용할 수도 있습니다.
다음 동등성:
$aref->@[ ... ]; # @$aref[ ... ]와 동일
$href->@{ ... }; # @$href{ ... }와 동일
접미사 키/값 쌍 슬라이싱, 5.20.0에 추가되고 키/값 해시에 문서화됨
perldata의 Slices 섹션도 예상대로 작동합니다.
$aref->%[ ... ]; # %$aref[ ... ]와 동일
$href->%{ ... }; # %$href{ ... }와 동일
후위 배열과 마찬가지로 후위 값 슬라이스 역참조 보간에 사용
문자열(큰따옴표 또는 "qq" 연산자), 그러나 추가 "postderef_qq"인 경우에만
기능이 활성화되었습니다.
할당 에 참고자료
v5.22.0부터 참조 연산자를 할당할 수 있습니다. 그것은 수행
왼쪽에서 참조하는 변수 이름이 가 되도록 앨리어싱 작업
오른쪽에 참조된 사물의 별칭:
\$a = \$b; # $a와 $b는 이제 같은 스칼라를 가리킵니다.
\&foo = \&bar; # foo()는 이제 bar()를 의미합니다.
이 구문은 "'realiasing' 기능 사용"으로 활성화해야 합니다. 실험적이며,
"'experimental::refaliasing' 경고 없음"이 적용되지 않는 한 기본적으로 경고합니다.
이러한 형식은 에 할당될 수 있으며 오른쪽이 스칼라로 평가되도록 합니다.
문맥:
\$스칼라
\@정렬
\%해시시
\&보결
\내 $스칼라
\내 @배열
\내 %해시
\state $scalar # 또는 @array 등
\우리의 $scalar # 등
\local $scalar # 등
\local 우리의 $scalar # 등
\$some_array[$인덱스]
\$some_hash{$키}
\local $some_array[$index]
\local $some_hash{$key}
질환 ? \$this : \$that[0] # 등
슬라이싱 작업과 괄호로 인해 오른쪽이 목록에서 평가됩니다.
문맥:
\@배열[5..7]
(\@배열[5..7])
\(@배열[5..7])
\@hash{'foo','bar'}
(\@hash{'foo','bar'})
\(@hash{'foo','bar'})
(\$스칼라)
\($스칼라)
\(내 $스칼라)
\my($스칼라)
(\@정렬)
(\%해시시)
(\&보결)
\(&보결)
\($foo, @bar, %baz)
(\$foo, \@bar, \%baz)
오른쪽에 있는 각 요소는 올바른 유형의 데이텀에 대한 참조여야 합니다.
배열을 바로 둘러싸는 괄호(및 아마도
"my"/"state"/"our"/"local") 배열의 각 요소를 별칭으로 만듭니다.
오른쪽에서 참조되는 해당 스칼라:
\(@a) = \(@b); # @a와 @b는 이제 동일한 요소를 갖습니다.
\my(@a) = \(@b); # 비슷하게
\(내 @a) = \(@b); # 비슷하게
푸시 @a, 3; # 하지만 이제 @a에는 @b에 없는 추가 요소가 있습니다.
\(@a) = (\$a, \$b, \$c); # @a는 이제 $a, $b, $c를 포함합니다.
해당 양식을 "local"과 결합하고 해시 바로 주위에 괄호를 두는 것은
금지됨(무엇을 해야 하는지 명확하지 않기 때문에):
\local(@array) = foo(); # 잘못된
\(% 해시) = 바(); # 잘못된
참조 및 비참조에 대한 할당은 목록 및 조건부에서 결합될 수 있습니다.
삼항 표현식, 오른쪽의 값이 올바른 유형인 한
왼쪽의 각 요소는 난독화된 코드를 만들 수 있습니다.
(내 $tom, \my $dick, \my @harry) = (\1, \2, [1..3]);
# $tom은 이제 \1입니다.
# $dick은 이제 2입니다(읽기 전용).
# @해리는 (1,2,3)
내 $type = 참조 $thingy;
($type ? $type == 'ARRAY' ? \@foo : \$bar : $baz) = $thingy;
"foreach" 루프는 루프 변수에 대한 참조 생성자를 사용할 수도 있습니다.
구문은 다음 중 하나로 제한되며 뒤에 "my", "state" 또는 "our"가 선택적으로 포함됩니다.
백슬래시:
\$s
\@ㅏ
\%시간
\&씨
괄호는 허용되지 않습니다. 이 기능은 배열 배열에 특히 유용합니다.
또는 해시 배열:
foreach \my @a (@array_of_arrays) {
약탈($a[0], $a[-1]);
}
foreach \my %h(@array_of_hashes) {
$h{젤라스틱}++ if $h{유형} == '재미';
}
경고: 앨리어싱은 클로저에서 올바르게 작동하지 않습니다. 어휘의 별칭을 지정하려고 하면
내부 서브루틴 또는 "eval"의 변수, 앨리어싱은 다음 내에서만 볼 수 있습니다.
그 내부 서브, 그리고 변수가 선언된 외부 서브루틴에는 영향을 미치지 않습니다.
이 이상한 행동은 변경될 수 있습니다.
onworks.net 서비스를 사용하여 온라인으로 perlref 사용