펄의 숨겨진 기능?


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.