펄의 숨겨진 기능?


143

실제로 유용한 작업을 수행하기 위해 실제로 사용할 수 있었지만 Perl에서 실제로 유용하지만 난해한 언어 기능은 무엇입니까?

지침 :

  • CPAN이 아닌 Perl 코어에 대한 답변을 제한하십시오.
  • 예와 간단한 설명을 입력하십시오

숨겨진 기능은 다른 언어의 숨겨진 기능에서도 찾을 수 있습니다.

(이것들은 모두 Corion의 답변 에서 온 것입니다 )

    • 더프의 장치
    • 휴대 성과 표준 성
  • 씨#
    • 공백으로 구분 된 목록 및 문자열에 대한 따옴표
    • 별칭 네임 스페이스
  • 자바
    • 정적 이니셜 라이저
  • 자바 스크립트
    • 기능은 일등 시민입니다
    • 블록 범위 및 폐쇄
    • 변수를 통해 간접적으로 메소드 및 접근자를 호출
  • 루비
    • 코드를 통한 메소드 정의
  • PHP
    • 광범위한 온라인 문서
    • 마술 방법
    • 상징적 참조
  • 파이썬
    • 한 줄 값 교환
    • 핵심 기능조차도 자신의 기능으로 대체하는 기능

다른 숨겨진 기능 :

연산자 :

인용 구조 :

구문과 이름 :

모듈, Pragma 및 명령 줄 옵션 :

변수:

루프 및 흐름 제어 :

정규식 :

다른 기능들:

다른 속임수와 메타 답변 :


또한보십시오:


이러한 기능의 대부분은 일상적으로 사용되며 일부는 대부분의 Perl 스크립트에서 발생하며 "기타"아래에 나열된 대부분은 여전히 ​​다른 언어에서 유래하여 이러한 "숨겨진"변경을 질문의 의도로 부릅니다.
reinierpost

답변:


54

flip-flop 연산자는 플래그 변수를 사용하지 않고 파일 핸들이 반환 한 레코드 (일반적으로 행)를 반복 할 때 첫 번째 반복을 건너 뛰는 데 유용합니다.

while(<$fh>)
{
  next if 1..1; # skip first record
  ...
}

perldoc perlop자세한 정보와 예제를 보려면 "플립 플롭"을 실행 하고 검색 하십시오 .


실제로 Awk에서 가져온 것입니다. 여기서 pattern1, pattern2를 작성하여 두 패턴 사이에서 플립 플롭을 수행 할 수 있습니다.
Bruno De Fraine

15
명확히하기 위해 "숨겨진"측면은 스칼라 '..'에 대한 피연산자가 상수 인 경우 값이 입력 라인 번호 ($.)와 암시 적으로 비교된다는 것입니다.
Michael Carman

47

Perl에는 많은 명백한 기능이 있습니다.

예를 들어,시길 뒤에 공백이있을 수 있다는 것을 알고 있습니까?

 $ perl -wle 'my $x = 3; print $ x'
 3

또는 기호 참조를 사용하는 경우 하위 번호를 지정할 수 있습니까?

$ perl -lwe '*4 = sub { print "yes" }; 4->()' 
yes

"bool"유사 연산자도 있습니다.이 연산자는 실제 표현식에 대해서는 1을 반환하고 false에 대해서는 빈 문자열을 반환합니다.

$ perl -wle 'print !!4'
1
$ perl -wle 'print !!"0 but true"'
1
$ perl -wle 'print !!0'
(empty line)

다른 흥미로운 것들 : use overload문자열 리터럴과 숫자를 오버로드 할 수 있습니다 (예 : BigInts 또는 무엇이든 만들 수 있습니다).

이러한 것 중 많은 부분이 실제로 어딘가에 문서화되거나 문서화 된 기능을 논리적으로 따릅니다. 그럼에도 불구하고 일부는 잘 알려져 있지 않습니다.

업데이트 : 또 다른 좋은 것. q{...}인용 구조 아래 에 언급되었지만 문자를 구분 기호로 사용할 수 있다는 것을 알고 있습니까?

$ perl -Mstrict  -wle 'print q bJet another perl hacker.b'
Jet another perl hacker.

마찬가지로 정규 표현식을 작성할 수 있습니다.

m xabcx
# same as m/abc/

2
"시길 다음에 공간이있을 수 있다는 것을 알고 있습니까?" 나는 완전히 흐트러졌다. 와.
Aristotle Pagaltzis

1
멋있는! !! $ undef_var는 경고를 생성하지 않습니다.
Axeman

4
나는를 단락 문자열에 문자를 사용하여 예 "해야한다고 생각 그냥 "제트 다른 펄 해커 "= P보다는 다른 펄 해커"
크리스 루츠

최악의 부분은 다른 것을 구분자로 사용할 수 있다는 것입니다. 닫는 괄호. 유효한 것은 다음과 같습니다. s} regex} replacement} xsmg; q] 문자열 리터럴];
Ryan C. Thompson

46

magic ARGV 를 통해 압축 파일에 대한 지원 추가 :

s{ 
    ^            # make sure to get whole filename
    ( 
      [^'] +     # at least one non-quote
      \.         # extension dot
      (?:        # now either suffix
          gz
        | Z 
       )
    )
    \z           # through the end
}{gzcat '$1' |}xs for @ARGV;

(셸 메타 문자가있는 파일 이름을 처리하는 데 필요한 $ _ 주위 인용)

이제이 <>기능은 @ARGV".gz"또는 ".Z"로 끝나는 파일을 압축 해제합니다 .

while (<>) {
    print;
}

2
나는 당신 |이 교체에서 탈출해야한다고 생각하지 않습니다 .
Chris Lutz

나는 이것을 쳐다보고 그것이 어떻게 작동하는지 알 수 없다. 어떤 지점 zcat |에서 파이프를 통과하라는 명령으로 구문 분석됩니까?
Ether

1
@Ether => 파이프 감지는 두 개의 인수 열기의 특징이며, 다이아몬드 연산자는 각 파일을 열 때 사용합니다@ARGV
Eric Strom

40

Perl에서 가장 좋아하는 기능 중 하나는 부울 ||연산자를 사용하여 선택 세트를 선택하는 것입니다.

 $x = $a || $b;

 # $x = $a, if $a is true.
 # $x = $b, otherwise

이것은 다음과 같이 쓸 수 있음을 의미합니다.

 $x = $a || $b || $c || 0;

에서 최초의 진정한 값을합니다 $a, $b그리고 $c, 또는 디폴트의0 그렇지.

Perl 5.10에는 //정의 된 경우 왼쪽을 반환하고 그렇지 않으면 오른쪽을 반환 하는 연산자 도 있습니다 . 다음 선택하는 제 정의 된 값에서 $a, $b, $c, 또는 0그렇지

$ x = $ a // $ b // $ c // 0;

또한 짧은 형식과 함께 사용할 수 있으며 기본값을 제공하는 데 매우 유용합니다.

$ x || = 0; # $ x가 false이면 이제 값이 0입니다.

$ x // = 0; # $ x가 정의되지 않은 경우 이제 값이 0입니다.

안녕,


4
이것은 "숨겨진"기능으로는 거의 인정되지 않는 일반적인 관용구입니다.
Michael Carman

3
예쁜 프린터가 생각 수치는 // 주석입니다 :)
존 퍼거슨

2
질문 :이 새로운 연산자를 사용할 수있는 "사용 기능"이 있습니까, 아니면 기본적으로 활성화되어 있습니까? 나는 여전히 Perl 5.10의 기능을 기대하고 있습니다.
JJ

6
// 기본적으로 거기에 특별한 조정이 필요하지 않습니다. dor-patch를 사용하여 5.8.x로 백 포트 할 수도 있습니다. CPAN 미러의 authors / id / H / HM / HMBRAND / 디렉토리를 참조하십시오. FreeBSD 6.x 이상은 펄 패키지로 제공합니다.
08 년

2
언제 || 또는 // do {}와 결합되면보다 복잡한 할당을 캡슐화 할 수 있습니다. 즉 $ x = $ a || {내 $ z; 3 또는 4 줄의 유도; $ z};
RET

39

++와 단항 연산자는 숫자뿐만 아니라 문자열에서도 작동합니다.

my $_ = "a"
print -$_

인쇄 -a

print ++$_

인쇄 b

$_ = 'z'
print ++$_

인쇄의 AA


3
perlvar를 인용하자면 : "자동 감소 연산자는 마법이 아닙니다." 따라서 --문자열에서 작동하지 않습니다.
moritz

"aa"는 "z"다음의 자연 요소가 아닌 것 같습니다. 다음으로 높은 ASCII 값인 "{"을 기대합니다.
Ether

4
프로그래머에게 "z"뒤에 오는 것을 묻지 마십시오. 인간에게 물어보십시오. 이 기능은 긴 목록의 항목 번호를 매길 때 유용합니다.
Barry Brown

17
Perl을 처음 접했을 때이 기능을 행동에 대한 정확한 z를 사용하여 직접 구현 한 다음, 웃고 나와 "뭔가 보여줘"라고 말하는 동료에게 보여주었습니다. 나는 조금 울었지만 무언가를 배웠다.
Copas

2
@Ether-원하는 경우을 사용하여 숫자를 사용하고 ASCII로 자동 변환하십시오 ord(). 또는 작은 클래스를 작성하고 연산자를 오버로드하여 수행하십시오.
Chris Lutz

36

펄은 다른리스트에서 거의 모든 "비평"적인 부분을 가지고 있기 때문에 펄이 할 수없는 한 가지를 말씀 드리겠습니다.

Perl이 할 수없는 것은 //연산자가 정규식에 사용 되기 때문에 코드에 임의의 URL이없는 것입니다 .

Perl이 제공하는 기능이 확실하지 않은 경우를 대비하여 다음과 같은 항목이 명확하지 않을 수 있습니다.

더프의 장치 -

양도 및 Standardness은 - C 컴파일러보다 펄 가능성이 더 컴퓨터가 있습니다

파일 / 경로 조작 클래스 - 파일 :: 닷넷보다 더 많은 운영 체제에서 작품을 찾기

공백으로 구분 된 목록 시세 및 문자열 - 펄은 당신이 당신의 목록 및 문자열 구분 기호 거의 임의의 따옴표를 선택할 수 있습니다

별칭 네임 스페이스-Perl 은 glob 할당을 통해 다음과 같은 기능을 제공합니다.

*My::Namespace:: = \%Your::Namespace

정적 이니셜 라이저 -Perl은 BEGIN(코드 구문 분석) 에서 (코드 구문 분석 CHECK후)까지 import(모듈 가져 오기에서)까지 new(객체 인스턴스화)에서 DESTROY(객체 파괴)에서 END(프로그램 종료) 까지 거의 모든 컴파일 및 객체 인스턴스화 단계에서 코드를 실행할 수 있습니다.

함수는 퍼스트 클래스 시민 -펄처럼

블록 범위 및 클로저 -Perl

변수를 통해 간접적으로 메소드 및 접근자를 호출-Perl 도 다음을 수행합니다.

my $method = 'foo';
my $obj = My::Class->new();
$obj->$method( 'baz' ); # calls $obj->foo( 'baz' )

코드를 통해 방법을 정의 - 펄 그것도 할 수 있습니다 :

*foo = sub { print "Hello world" };

퍼베이시브 온라인 설명서 - 펄 문서도 시스템에 온라인 및 가능성

"존재하지 않는"함수를 호출 할 때마다 호출되는 매직 메소드 -Perl은 AUTOLOAD 함수에서이를 구현합니다.

상징적 참조 -이것들로부터 멀리 떨어져있는 것이 좋습니다. 그들은 당신의 아이들을 먹을 것입니다. 물론 펄은 아이들에게 피에 목 마른 악마를 제공 할 수 있습니다.

한 줄의 값 교환 -Perl은 목록 할당을 허용합니다

핵심 기능조차도 자신의 기능으로 대체하는 기능

use subs 'unlink'; 
sub unlink { print 'No.' }

또는

BEGIN{
    *CORE::GLOBAL::unlink = sub {print 'no'}
};

unlink($_) for @ARGV

나는 다른 언어에 비해 Perl의 문서를 좋아하지만 여전히 Regexes와 reference에 대해서는 합리화 될 수 있다고 생각합니다. 예를 들어 정규 표현식에 대한 최선의 프라이머는 Perlre 아니라, Perlop
존 퍼거슨

9
"Perl이 할 수없는 한 가지는 // 연산자가 정규 표현식에 사용되기 때문에 코드에 임의의 URL이없는 것입니다." -이건 말도 안돼

소스 필터를 사용하지 않고 펄 코드에 http : // URL을 노출시키는 방법을 찾았지만 방법을 찾지 못했습니다. 어떻게 가능한지 보여줄 수 있습니까? // Perl 버전에서 5.8.x까지의 정규 표현식에 사용됩니다. 5.10에서는 정의 또는 할당을 위해 용도가 변경되었습니다.
Corion

8
코드에서 왜 URL 을 하십니까? 나는 예를 생각할 수 없다.
castaway

18
아무도 그것을 원하지 않을 것입니다. 그것은 단지 Java meme입니다. " foo.com "은 http : 레이블이며 주석에는 "foo.com"입니다. 어떤 사람들은 이것이 멍청하기 때문에 흥미 롭습니다.
jrockway

35

자생 . AFAIK 다른 언어는 없습니다 .


나는 파이썬 등이 이것을 지원하지 않았다는 것을 몰랐다.
skiphoppy

@davidnicol : 정말요? 당신은 링크를 제공 할 수 있습니까? Google에서 빠른 검색으로 아무것도 반환되지 않았습니다. ECMAscript를 모르는 사람들은 Javascript의 올바른 이름입니다. en.wikipedia.org/wiki/ECMAScript
JJ

1
그리고 해제 autovivication에 모듈이있다
알렉산드르 Ciornii

1
@Gregg Lind-파이썬은 변수를 처음 할당 할 때마다 자동으로 변수를 생성한다고 가정 할 때 자동 활성화는 단일 오타에서 엄청난 문제를 야기합니다.
Chris Lutz

3
@tchrist-a = [[xrange (1,11)에서 y에 대한
xxy

31

Perl에서 거의 모든 종류의 이상한 문자열을 인용하는 것은 간단합니다.

my $url = q{http://my.url.com/any/arbitrary/path/in/the/url.html};

실제로 Perl의 다양한 인용 메커니즘은 매우 흥미 롭습니다. Perl 정규식 인용 메커니즘을 사용하면 구분자를 지정하여 모든 것을 인용 할 수 있습니다. #, / 또는 (), [] 또는 {}와 같은 열기 / 닫기 문자와 같은 거의 모든 특수 문자를 사용할 수 있습니다. 예 :

my $var  = q#some string where the pound is the final escape.#;
my $var2 = q{A more pleasant way of escaping.};
my $var3 = q(Others prefer parens as the quote mechanism.);

인용 메커니즘 :

q : 리터럴 따옴표; 이스케이프해야하는 문자는 끝 문자입니다. qq : 해석 된 견적; 변수를 처리하고 이스케이프 문자를 처리합니다. 인용해야 할 문자열에 적합합니다.

my $var4 = qq{This "$mechanism" is broken.  Please inform "$user" at "$email" about it.};

qx : qq처럼 작동하지만 대화식이 아닌 시스템 명령으로 실행합니다. 표준 출력에서 ​​생성 된 모든 텍스트를 반환합니다. (OS에서 지원되는 경우 리디렉션도 나옵니다) 백 따옴표 (`문자)로도 수행됩니다.

my $output  = qx{type "$path"};      # get just the output
my $moreout = qx{type "$path" 2>&1}; # get stuff on stderr too

qr : qq와 같이 해석하지만 정규식으로 컴파일합니다. 정규식의 다양한 옵션과 함께 작동합니다. 이제 정규식을 변수로 전달할 수 있습니다.

sub MyRegexCheck {
    my ($string, $regex) = @_;
    if ($string)
    {
       return ($string =~ $regex);
    }
    return; # returns 'null' or 'empty' in every context
}

my $regex = qr{http://[\w]\.com/([\w]+/)+};
@results = MyRegexCheck(q{http://myurl.com/subpath1/subpath2/}, $regex);

qw : 매우 유용한 따옴표 연산자입니다. 따옴표로 묶은 공백으로 구분 된 단어 집합을 목록으로 바꿉니다. 단위 테스트에서 데이터를 채우는 데 좋습니다.


   my @allowed = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z { });
   my @badwords = qw(WORD1 word2 word3 word4);
   my @numbers = qw(one two three four 5 six seven); # works with numbers too
   my @list = ('string with space', qw(eight nine), "a $var"); # works in other lists
   my $arrayref = [ qw(and it works in arrays too) ]; 

일이 더 명확해질 때마다 사용하는 것이 좋습니다. qx, qq 및 q의 경우 대부분 {} 연산자를 사용합니다. qw를 사용하는 사람들의 가장 일반적인 습관은 일반적으로 () 연산자이지만 때로는 qw //도 표시됩니다.


1
구문 강조 표시가 올바르게 강조 표시되도록 qw ""를 사용하는 경우가 있습니다.
브래드 길버트

SlickEdit에서 저에게 효과적입니다. :)
Robert P

1
@ fengshaun, 내가 일반적으로 사용하는 편집기 이것을 올바르게 강조 표시합니다. 부분적으로 StackOverflow의 구문 형광펜을 언급하고있었습니다.
브래드 길버트

@ 브래드 길버트 : 스택 오버플로 할 수 없습니다 (물론, (안) 펄 가치가 구문 분석 diddly 쪼그리고 수행 ☹.
tchrist

my $moreout = qx{type "$path" 2>&1};... 당신이 할 수있는 줄 몰랐어요! [TM]
dland

27

실제로 숨기는 것은 아니지만 매일 많은 Perl 프로그래머들은 CPAN 에 대해 모른다 . 이는 특히 풀 타임 프로그래머가 아니거나 Perl 풀 타임으로 프로그래밍하지 않은 사람들에게 적용됩니다.


27

"for"문은 Pascal에서 "with"가 사용되는 것과 같은 방식으로 사용될 수 있습니다.

for ($item)
{
    s/&‎nbsp;/ /g;
    s/<.*?>/ /g;
    $_ = join(" ", split(" ", $_));
}

변수 이름을 반복하지 않고도 일련의 s /// 연산 등을 동일한 변수에 적용 할 수 있습니다.

참고 : 마크 다운을 우회하기 위해 위의 비 공백 공간 (& nbsp;)에 숨겨진 유니 코드가 있습니다. 붙여 넣지 마십시오 :)


"map"도 마찬가지입니다. map {....} $ item; "map"보다 "for"를 사용하는 것의 한 가지 장점은 다음을 사용하여 나눌 수 있다는 것입니다.
draegtun

2
또한 조작하기 전에 코드를 조작하기 전에 항목을 조작해야하기 때문에 가독성이 향상됩니다.
Robert P

@RobertP : 맞습니다. 화제는 담화에 유용합니다.
tchrist

26

따옴표 연산자는 내가 가장 좋아하는 것 중 하나입니다. 비교:

my @list = ('abc', 'def', 'ghi', 'jkl');

my @list = qw(abc def ghi jkl);

소음이 적고 눈에 더 쉽습니다. Perl에 대한 또 다른 좋은 점은 SQL을 작성할 때 실제로 놓치게되는 후행 쉼표가 합법적이라는 것입니다.

print 1, 2, 3, ;

이상한 것처럼 보이지만 다른 방법으로 코드를 들여 쓰면 안됩니다.

print
    results_of_foo(),
    results_of_xyzzy(),
    results_of_quux(),
    ;

함수 호출에 추가 인수를 추가해도 이전 또는 후행에서 쉼표를 사용하지 않아도됩니다. 단일 회선 변경은 주변 회선에 영향을 미치지 않습니다.

이것은 가변 기능으로 작업하는 것이 매우 즐겁습니다. 이것은 아마도 Perl의 가장 저평가 된 기능 중 하나 일 것입니다.


2
Perl 문법의 흥미로운 코너 사례는 다음과 같다는 것입니다 : for $ _ qw (물건 목록) {...}
ephemient

1
*?와 같은 특수 문자를 사용하지 않는 한 단어를 인용하기 위해 glob 구문을 남용 할 수도 있습니다. 그래서 당신은 쓸 수 있습니다for (<a list of stuff>) { ... }
moritz

1
@ephemient : 거의. 그것은 lexicals에서만 작동합니다 : 내 $ x qw (abc) {...}의 경우 : $ _ qw (abc) {print} #
for

펄이 가장 좋아하는 기본값을 즐길 수있을 때 왜 어휘를 더 추가해야합니까? (qw / abcd /) {인쇄; }
fengshaun

2
@ephemient, @fengshaun, @moritz, @dland :의은에 "고정"고 blead ; 이 p5p 스레드를 참조하십시오 .
tchrist

26

DATA 블록에 직접 붙여 넣은 데이터를 구문 분석하는 기능 프로그램에서 열거 나 유사한 테스트 파일로 저장할 필요가 없습니다. 예를 들면 다음과 같습니다.

my @lines = <DATA>;
for (@lines) {
    print if /bad/;
}

__DATA__
some good data
some bad data
more good data 
more good data 

작은 테스트에서 매우 유용합니다!
fengshaun

@ peter mortensen 어떻게 여러 블록을 가지겠습니까? 그리고 어떻게 블록을 끝내나요?
Toad

@Toad : allan의 답변입니다 (개정판 참조). 해당 사용자를 해결하는 것이 좋습니다. 또는 해당 사용자가 스택 오버플로를 떠났을 때 특히 아무도 다루지 않을 수 있습니다 (따라서 실제 Perl 전문가가 나중에 바로 잡을 수 있습니다).
Peter Mortensen

3
@Hai : 아니요 추한 것은 아닙니다 . 사실, 추한 것과 정반대입니다. 깨끗하고, 날렵하고, 최소이며, 아름답습니다. 한마디로, 그것은 훌륭하고 그것이없는 언어는 PITA입니다. @peter mortensen, @toad : 동일한 프로그램에서 여러 데이터 블록을 만드는 방법에 대한 한 가지 대답은 CPAN 에서 Inline :: Files 모듈 을 사용하는 것 입니다.
tchrist

인라인 :: 파일 은 소스 필터를 사용하여 구현됩니다. 여러 인라인 블록을 제공하고 소스 필터를 사용하지 않는 Data :: Section 도 있습니다.
Prakash K

24

새로운 블록 작업

의사 블록 작업을 만드는 언어를 확장하는 기능은 하나라고 말하고 싶습니다.

  1. 코드 참조가 먼저 필요하다는 것을 나타내는 서브의 프로토 타입을 선언합니다.

    sub do_stuff_with_a_hash (&\%) {
        my ( $block_of_code, $hash_ref ) = @_;
        while ( my ( $k, $v ) = each %$hash_ref ) { 
            $block_of_code->( $k, $v );
        }
    }
  2. 그런 다음 몸에 그것을 이렇게 부를 수 있습니다

    use Data::Dumper;
    
    do_stuff_with_a_hash {
        local $Data::Dumper::Terse = 1;
        my ( $k, $v ) = @_;
        say qq(Hey, the key   is "$k"!);
        say sprintf qq(Hey, the value is "%v"!), Dumper( $v );
    
    } %stuff_for
    ;

( Data::Dumper::Dumper다른 반 숨김 보석입니다.) sub블록 앞에 키워드가 필요하지 않거나 해시 전에 쉼표 가 어떻게 필요하지 않은지 확인 하십시오. 다음과 같이 많이 보입니다.map { } @list

소스 필터

또한 소스 필터가 있습니다. Perl이 코드를 전달할 수 있도록 코드를 조작 할 수 있습니다. 이 작업과 블록 작업은 가정에서 사용하지 않는 유형입니다.

소스 필터를 사용하여 시간을 확인하는 매우 간단한 언어를 생성하고 의사 결정을 위해 짧은 Perl one-liner를 허용하는 등 깔끔한 작업을 수행했습니다.

perl -MLib::DB -MLib::TL -e 'run_expensive_database_delete() if $hour_of_day < AM_7';

Lib::TL "변수"와 상수를 모두 스캔하고 생성하고 필요에 따라 대체합니다.

다시 말하지만 소스 필터는 지저분하지만 강력합니다. 그러나 그들은 디버거를 엉망으로 만들 수 있으며 심지어 잘못된 줄 번호로 경고를 인쇄 할 수도 있습니다. Damian 's Switch 사용을 중단했습니다디버거가 실제로 어디에 있는지 알려주는 모든 기능을 잃어 버렸기 때문에 . 그러나 작은 코드 섹션을 수정하여 동일한 줄에 유지함으로써 손상을 최소화 할 수 있음을 발견했습니다.

신호 후크

종종 충분하지만 그다지 명백하지는 않습니다. 다음은 이전 처리기를 다시 사용하는 다이 처리기입니다.

my $old_die_handler = $SIG{__DIE__};
$SIG{__DIE__}       
    = sub { say q(Hey! I'm DYIN' over here!); goto &$old_die_handler; }
    ;

즉, 코드의 다른 모듈이 죽기를 원할 때마다 다른 사람이 파괴적으로 덮어 쓰지 않는 한 당신에게 와야합니다. $SIG{__DIE__} . 그리고 누군가 무언가가 잘못되었다는 알림을받을 수 있습니다.

물론, END { }당신이하고 싶은 모든 것이 정리된다면, 충분한 일을 위해 블록을 사용할 수 있습니다 .

overload::constant

모듈이 포함 된 패키지에서 특정 유형의 리터럴을 검사 할 수 있습니다. 예를 들어, 이것을 import서브 에서 사용하는 경우 :

overload::constant 
    integer => sub { 
        my $lit = shift;
        return $lit > 2_000_000_000 ? Math::BigInt->new( $lit ) : $lit 
    };

이는 호출 패키지에서 20 억을 초과하는 모든 정수가 Math::BigInt객체로 변경됨을 의미 합니다. ( overload :: constant 참조 ).

그룹화 된 정수 리터럴

우리가있는 동안 Perl을 사용하면 큰 숫자를 세 자리 그룹으로 나누고 여전히 파싱 가능한 정수를 얻을 수 있습니다. 2_000_000_000위의 20 억을 참고하십시오 .


5
$ SIG { DIE } 처리기를 사용할 때는 $ ^ S를 검사하여 프로그램이 실제로 죽어 가거나 예외가 발생하는지 확인하는 것이 좋습니다. 일반적으로 후자를 방해하고 싶지 않습니다.
pjf

새로운 블록은 매우 유익합니다! 나는 그것이 언어 의미론이라고 생각했다! 많은 감사합니다.
ZeroCool

소스 필터의 유용한 사용법은 pdl의 NiceSlice ( pdl.perl.org/?docs=NiceSlice&title=PDL::NiceSlice )이므로 ->slice슬라이스가 필요할 때마다를 메소드 로 사용할 필요가 없습니다 .
Joel Berger

24

이항 "x"는 반복 연산자입니다 .

print '-' x 80;     # print row of dashes

또한 목록과 함께 작동합니다.

print for (1, 4, 9) x 3; # print 149149149

이것이 Perl이 해커들에게 인기를 얻은 이유 중 하나입니다. perl -e '인쇄 0x000 x 25';
JJ

4
내가 가장 좋아하는 사용법은 SQL INSERT 문의 마지막 부분에 대한 자리 표시자를 생성하는 것입니다. @p = ( '?') x $ n; $ p = join ( ",", @p); $ sql = "INSERT ... VALUES ($ p)";
skiphoppy

24

오염 검사. 오염 검사가 활성화 -t된 상태에서 오염 된 데이터 (대략 말하기, 프로그램 외부의 데이터)를 안전하지 않은 기능 (파일 열기, 외부 명령 실행 등)으로 전달하려고하면 perl은 죽거나 경고를 받습니다. setuid 스크립트 또는 CGI 또는 스크립트가 데이터를 제공하는 사람보다 권한이 큰 스크립트를 작성할 때 매우 유용합니다.

매직 고토 goto &sub최적화 된 테일 콜을 수행합니다.

디버거

use strict그리고 use warnings. 이것들은 많은 오타로부터 당신을 구할 수 있습니다.


1
다른 언어에이 기능이없는 이유는 무엇입니까? 이 기능을 사용하면 perl 웹 스크립트가 훨씬 안전합니다.
Matthew Lock

22

Perl 5에서 "-n""-p"스위치가 구현 되는 방식에 따라 다음 과 같은 겉보기에 잘못된 프로그램을 작성할 수 있습니다 }{.

ls |perl -lne 'print $_; }{ print "$. Files"'

내부적으로이 코드로 변환됩니다.

LINE: while (defined($_ = <ARGV>)) {
    print $_; }{ print "$. Files";
}

@ 마틴 클레이튼 : 왜 그렇게 불리는가?
tchrist

@tchrist-아마도 두 사람이 코를 문지르는 것처럼 보입니다. 프로필에서 내가 무슨 뜻인지 알면
martin clayton

18

우주선 연산자로 쉽게 시작합시다 .

$a = 5 <=> 7;  # $a is set to -1
$a = 7 <=> 5;  # $a is set to 1
$a = 6 <=> 6;  # $a is set to 0

1
@Leon : C / C ++는 숫자에 대해 3 개의 값을 반환하지 않습니다. 메모리가 문자열 comapre 기능을 제공하는 경우 전체 STL 언어에서 아는 유일한 3 값 반환입니다. AFAIK Python에는 3 반환 숫자 비교가 없습니다. Java에는 숫자 특정 3 리턴 비교가 없습니다.
JJ

7
-1/0/1 비교 연산자에 대해 무엇이 유용한 지 언급 할 가치가 있습니다. 모든 사람이 알 수는 없기 때문에 : 연산자를 연산자와 함께 연결하여 기본 / 보조 / 등을 수행 할 수 있습니다. 정렬합니다. 따라서 ($a->lname cmp $b->lname) || ($a->fname cmp $b->fname)사람들을 성을 기준으로 정렬하지만 두 사람이 같은 성을 가지면 이름을 기준으로 정렬됩니다.
hobbs

@JJ Python은 3 가지 값을 비교합니다 : cmp () >>> print (cmp (5,7), cmp (6,6), cmp (7,5)) (-1, 0, 1)
bukzor

18

이것은 메타 답변이지만 Perl Tips 아카이브에는 Perl로 할 수있는 모든 종류의 흥미로운 트릭이 포함되어 있습니다. 이전 팁의 아카이브는 온라인으로 찾아 볼 수 있으며 메일 링리스트 또는 아톰 피드를 통해 구독 할 수 있습니다.

내가 좋아하는 팁 중 일부는 PAR으로 실행 파일을 작성하고 , autodie를 사용하여 자동으로 예외를 발생 시키고, Perl 5.10에서 스위치스마트 일치 구문을 사용하는 것입니다 .

공개 : 저는 Perl Tips의 저자이자 유지 관리자 중 한 명이므로 분명히 매우 높게 생각합니다. ;)


2
아마도 가장 훌륭한 문서화 된 언어 중 하나 일 것이며 문서를 검색하는 도구의 패턴을 설정했을 것입니다. 이 질문의 목록은 아마도 다른 언어만큼 필요하지 않을 것입니다.
Axeman

1
autodie는 매우 멋져 보인다.
j_random_hacker

18

map- 코드를보다 표현력있게 만들뿐 아니라이 "기능적 프로그래밍"에 대해 조금 더 읽어야한다는 충동을 주었기 때문입니다.


15

루프에서 continue 절. 모든 루프의 맨 아래에서 실행되며 다음 루프에서도 실행됩니다.

while( <> ){
  print "top of loop\n";
  chomp;

  next if /next/i;
  last if /last/i;

  print "bottom of loop\n";
}continue{
  print "continue\n";
}

15

내 투표는 Perl의 정규 표현식에서 (? {}) 및 (?? {}) 그룹으로 진행됩니다. 첫 번째는 반환 값을 무시하고 Perl 코드를 실행하고 두 번째는 반환 값을 정규식으로 사용하여 코드를 실행합니다.


perl은 너무 많은 정규 표현식 확장 프로그램을 개발하여 다른 프로그램이 원래 정규 표현식 언어 대신 pcre (perl 호환 정규 표현식)를 사용하는 경우가 많습니다.
Sec

여기에 약간의 짧은 광고 읽기 perldoc.perl.org/... - D
JJ

펄은 정규 표현식과 관련하여 팩을 이끌고 있습니다.
브래드 길버트

내가 아는 한 이것은 여전히 ​​실험적이며 향후 Perls에서 동일한 방식으로 작동하지 않을 수 있습니다. 유용하지는 않지만, s /// 명령의 / e 플래그에서 약간 더 안전하고 사용 가능한 버전을 찾을 수 있습니다 : s/(pattern)/reverse($1);/ge;# reverses all patterns.
Chris Lutz

@Chris Lutz, @Leon Timmerman :이 두 구성은 이제 불완전합니다. 또한 두 번째 패턴은 더 이상 재귀 패턴을 적용하는 데 사용될 필요가 없으므로 캡처 그룹에서 재귀를 수행 할 수 있습니다. @ 브래드 길버트 : PCRE가 우리를 추적하는 적절한 작업을 수행하지만 맞습니다. Perl이 완전히 도전 할 수없는 정규 표현식의 한 영역은 유니 코드 속성에 대한 액세스입니다. 의 unitrio 분포 uninames, unichars특히 uniprops내가 의미하는 것의 일부만 볼 수 있습니다.
tchrist

13
while(/\G(\b\w*\b)/g) {
     print "$1\n";
}

\ G 앵커. 그것은이다 뜨거운 .


3
... 이전 경기의 끝 위치를 나타냅니다.
Dave Sherohman

1
그러나 스칼라 컨텍스트에서 정규식을 호출해야합니다.
davidnicol

@ davidnicol : 위의 코드가 작동합니다. 무슨 뜻인지 알 수 있습니까?
JJ

13

m//운영자는 일부 모호한 특별한 경우가 있습니다 :

  • ?구분 기호로 사용 하는 경우을 호출하지 않으면 한 번만 일치합니다 reset.
  • '구분 기호로 사용 하면 패턴이 보간되지 않습니다.
  • 패턴이 비어 있으면 마지막으로 성공한 패턴을 사용합니다.

2
이들은 숨겨진 기능보다 숨겨진 문제와 유사합니다! 나는 그들을 좋아하는 사람을 모른다. p5p의 스레드는 어느 때나 작은 따옴표를 기억할 수 없기 때문에 / r은 보간이 없음을 의미합니다 (문자는 중요하지 않습니다).
08 년

2
@dland : 동의 함; 이 숨겨진 잘못된 기능을 호출 하여 프로덕션 코드에서 사용하지 않습니다.
Michael Carman

7
Perl 프로그래머가 작은 따옴표가 보간을 의미하지 않는다는 것을 기억하지 못하거나 추측 할 수 없다고 상상할 수 없습니다. 이 시맨틱의 사용법은 내가 기대 하는 언어에서 거의 보편적이다 .
sundar-Reinstate Monica

패턴이 비어 있고 마지막으로 성공한 일치 항목이 / o 수정 자로 컴파일 된 경우 해당 패턴에 고정됩니다.
davidnicol

1
빈 패턴 동작은 더 이상 사용되지 않습니다. 주로 $ foo가 비어 있으면 m / $ foo /와 같은 패턴이 불쾌한 버그가되기 때문입니다.
Matthew S

12

널 파일 핸들 다이아몬드 연산자 <> 는 명령 행 도구를 만드는 데 사용됩니다. <FH>명령 줄 파일 이름 또는 STDIN 중에서 가장 먼저 찾은 것을 마술처럼 선택한다는 점을 제외하면 핸들에서 읽는 것처럼 작동 합니다. perlop에서 찍은 :

while (<>) {
...         # code for each line
}

4
또한 "-"를 사용하여 "stdin에서 읽음"을 의미하는 UNIX 의미에 따라 수행 할 수 있습니다. 따라서 perl myscript.pl file1.txt - file2.txtperl은 첫 번째 파일을 처리 한 다음 stdin을 처리 한 다음 두 번째 파일을 처리합니다.
Ryan C. Thompson

할 수 있습니다 자신의 객체에 대한 연산자 (overload<><$var> ) 반복자처럼 . 그러나 목록 컨텍스트에서 예상 한대로 작동하지 않습니다.
고인돌

11

특수 코드 블록 과 같은 BEGIN, CHECK그리고 END. 그들은 Awk에서 왔지만 Perl에서 다르게 작동합니다. 레코드 기반이 아니기 때문입니다.

BEGIN블록 파싱 단계의 일부 코드를 지정하기 위해 사용될 수있다; syntax-and-variable-check 할 때도 실행됩니다 perl -c. 예를 들어, 구성 변수를로드하려면 다음을 수행하십시오.

BEGIN {
    eval {
        require 'config.local.pl';
    };
    if ($@) {
        require 'config.default.pl';
    }
}

11
rename("$_.part", $_) for "data.txt";

반복하지 않고 data.txt.part를 data.txt로 이름을 바꿉니다.


10

약간 모호한 것은 스칼라 컨텍스트를 강제하는 물결표 "연산자"입니다.

print ~~ localtime;

와 같다

print scalar localtime;

그리고 다른

print localtime;

5
perl5.10.0에 "스마트 일치 연산자"가 도입되어 ~~정규식 일치를 수행하고 항목이 배열에 포함되어 있는지 여부를 확인할 수 있기 때문에 이는 특히 명확 하지 않습니다.
moritz

그것은 모호하지 않으며, 모호합니다 (골프 및 JAPH에게 유용합니다).
Michael Carman

이것은 정확하지 않습니다! ~~는 참조에 안전하지 않습니다! 그것들은 그들을 끈으로 묶습니다.
Leon Timmermans

그래 문자열 화는 스칼라 컨텍스트로 강제 될 때 참조에 발생합니다. 그러면 "~~ 강제 스칼라 컨텍스트"가 어떻게 잘못됩니까?
Dave Sherohman

3
@Nomad Dervish : 스칼라 컨텍스트 / = 문자열. 예를 들어 "$ n = @a"는 스칼라 컨텍스트입니다. "$ s = qq '@ a'"는 문자열입니다. 참조와 관련하여 "$ ref1 = $ ref2"는 스칼라 컨텍스트이지만 문자열 화는 아닙니다.
Michael Carman


9

Perl의 루프 제어 구조의 "절망 모드"는 스택을 찾아서 일치하는 레이블을 찾도록합니다.

SKIP: {
    skip() if $something;

    print "Never printed";
}

sub skip {
    no warnings "exiting";
    last SKIP;
}

작은 알려진 .pmc 파일이 있습니다. "use Foo"는 Foo.pm 전에 @INC에서 Foo.pmc를 찾습니다. 컴파일 된 바이트 코드를 먼저로드하기위한 것이지만 Module :: Compile 은이를 사용하여 소스 필터링 된 모듈을 캐시하여보다 빠른로드 시간과 더 쉬운 디버깅을 수행합니다.

경고를 오류로 전환하는 기능

local $SIG{__WARN__} = sub { die @_ };
$num = "two";
$sum = 1 + $num;
print "Never reached";

그것이 언급되지 않은 내 머리 꼭대기에서 내가 생각할 수있는 것입니다.


9

염소 연산자 *:

$_ = "foo bar";
my $count =()= /[aeiou]/g; #3

또는

sub foo {
    return @_;
}

$count =()= foo(qw/a b c d/); #4

스칼라 컨텍스트의 목록 할당은 할당되는 목록의 요소 수를 생성하기 때문에 작동합니다.

* 실제로 연산자는 아닙니다.


그것은 가장 아름답고 아름다운 "운영자"입니다.
Chris Lutz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.