무엇을 선택"((선택(s),$|=1)[0])" 에서 하 Perl?
문제
본 끔찍한 일부로 작성된 코드에서는 Perl,하지만 할 수 없습니다 머리도 꼬리의 하나:
select((select(s),$|=1)[0])
그것의 일부 네트워크는 우리가 사용하는 서버와 통신하고 나는 가정의 버퍼(이 설정 $|
).
하지만 내가 알아낼 수 없습니다 왜 여러가지가 있고 select
전화 또는 배열을 참조합니다.누구든지 나를 도울 수 있습니까?
해결책
그러한 작은 관용구를 위한 설정행에 그 파일 핸들을 지정하면 된다 STDOUT.
select()
은 공급되는 그 파일 핸들을 지정하면 된고(기본적으로)대체 STDOUT 며,그것을 반환합니다 오래 된 그 파일 핸들을 지정하면 된 때 이루어집니다.
그래서 (select($s),$|=1)
리디렉션 그 파일 핸들을 지정하면 된다( select
반전),그리고 집행하($| = 1
).이 목록에서((...)[0]
고)첫 번째 값을 반환합니다(는 결과 select
출-원본 STDOUT),그리고 그런 다음 전달 그 으로 다시 다른 select
을 복구하려면 원래 STDOUT 그 파일 핸들을 지정하면 된.휴.
그러나 이제 당신은 그것을 이해(아마;)),이는 대신:
use IO::Handle;
$fh->autoflush;
다른 팁
코드를 알아내는 방법은 코드를 분리하는 것입니다. 당신은 괄호 안에있는 것들이 외부에서 물건을 먹기 전에 발생한다는 것을 알고 있습니다. 이것은 코드가 다른 언어로 무엇을하고 있는지 알아내는 것과 같은 방식입니다.
첫 번째 비트는 다음과 같습니다.
( select(s), $|=1 )
이 목록에는 두 가지 요소가 있습니다.이 요소는 두 가지 작업 결과입니다. s
파일 핸들은 기본값으로 설정할 수 있습니다 $|
진정한 가치로. 그만큼 $|
현재 선택된 파일 핸들에만 적용되는 파일 당 변수 중 하나입니다 ( 글로벌 변수를 이해합니다 ~에 효과적인 Perler). 결국 두 가지 항목 목록이 있습니다 : 이전 기본 파일 핸들 (결과) select
), 1.
다음 부분은 인덱스 0에서 항목을 꺼내는 문자 목록 슬라이스입니다.
( PREVIOUS_DEFAULT, 1 )[0]
그 결과 이전 기본 파일 핸들 인 단일 항목입니다.
다음 부분은 슬라이스의 결과를 가져 와서 다른 호출에 대한 인수로 사용합니다. select
select( PREVIOUS_DEFAULT );
사실상, 당신은 설정했습니다 $|
파일 핸들에서 기본 파일 핸들로 시작한 곳으로 돌아 왔습니다.
select($fh)
새 기본 파일 핸들을 선택하십시오. 보다 http://perldoc.perl.org/functions/select.html
(select($fh), $|=1)
AutoFlush를 켭니다. 보다 http://perldoc.perl.org/perlvar.html
(select($fh), $|=1)[0]
이 튜플의 첫 번째 값을 반환하십시오.
select((select($fh), $|=1)[0])
select
즉, 이전 기본 파일 핸들을 복원합니다.
동등합니다
$oldfh = select($fh);
$| = 1;
select($oldfh);
이는 의미합니다
use IO::Handle;
$fh->autoflush(1);
perldoc 페이지에서 보여 주듯이.
다른 장소에서, 나는 한 번 더 이해하기 쉬운 버전이 다음과 같이 제안했다.
for ( select $fh ) { $| = 1; select $_ }
이것은 주변 범위에서 가변적 인 요구가 없다는 소형 관용구의 유일한 이점을 보존합니다.
또는 당신이 편안하지 않다면 $_
, 당신은 다음과 같이 쓸 수 있습니다.
for my $prevfh ( select $fh ) { $| = 1; select $prevfh }
의 범위 $prevfh
로 제한됩니다 for
차단하다. (그러나 당신이 perl을 쓰면 당신은 정말로 $_
.)
핸들에 버퍼 플러싱을 켜기위한 지나치게 영리한 코드입니다. s
그런 다음 현재 핸들을 다시 선택합니다.
보다 perldoc -f select
이상.
확인해주십시오 perldoc -f select. 의 의미를 위해 $|
, 확인해주십시오 Perldoc Perlvar
IO :: 핸들로드를 건너 뛰는 것은 과도한 최적화입니다.
use IO::Handle;
$fh->autoflush(1);
훨씬 더 읽기 쉽습니다.