답변:
sub
리터럴을 피하십시오 . 대부분의 경우 {}
코드 블록에 간단히 사용할 수 있습니다 . 예를 들어 다음 코드를 작성하지 마십시오.
sub ($a){$a*2}
대신 블록 구문을 사용하십시오. 이것은 또한 사용할 수 있습니다 $_
, @_
그리고 %_
당신은 단지 하나의 변수가 필요하면 자리 표시 자 변수. 더 필요한 경우 $^a
, $^b
변수 등을 사용할 수 있습니다 .
{$_*2}
또한 드문 경우에, 어떤 코드 (특히 간단한 표현식이있는 경우)를 사용할 수도 있습니다. 는 *
자리 표시 자 인수를 대체합니다.
* *2
Perl 6은 Nd , Nl 및 No 범주의 모든 유니 코드 문자 를 유리수 리터럴로 사용할 수있는 기괴한 기능을 가지고 있습니다 . 이 중 일부는 ASCII로 숫자 값을 쓰는 것보다 짧습니다.
¼
(2 바이트)보다 짧 .25
거나 1/4
(3 바이트).¾
(2 바이트)보다 짧 .75
거나 3/4
(3 바이트).৴
(3 바이트)는 1/16
(4 바이트) 보다 짧습니다 .𐦼
(4 바이트)는 11/12
(5 바이트) 보다 짧습니다 .𒐲
(4 바이트)는 216e3
(5 바이트) 보다 짧습니다 .𒐳
(4 바이트)는 432e3
(5 바이트) 보다 짧습니다 .입력을 읽는 기능을 배우십시오. Perl 6에는 ARGV 또는 STDIN (ARGV에 아무것도 지정되지 않은 경우)에서 입력을 쉽게 읽을 수있는 많은 흥미로운 기능이 있으며, 올바르게 사용하면 코드가 단축 될 수 있습니다. 파일 핸들 메소드로 호출하면 특정 파일 핸들에서 작동하도록 강제 할 수 있습니다 (예를 들어 from에서 읽지 STDIN
만 ARGV에서 인수를 읽어야 하는 경우 유용합니다 ).
get
이 함수는 단일 라인을 가져 와서 자동으로 꽉 들어 오게 할 필요가 없습니다. 한 줄만 읽어야하는 경우에 유용합니다.
lines
이 함수는 파일 또는 STDIN에서 모든 행을 가져옵니다. 게으른 목록이므로와 함께 사용 for
하면 필요한 내용 만 읽습니다. 예를 들어.
say "<$_>"for lines
slurp
전체 파일 또는 STDIN을 읽고 결과를 단일 문자열로 리턴합니다.
say "<$_>" for lines
지금 작동합니다
경고 : 텍스트 벽이 다가오고 있습니다. 시간이 지남에 따라 수집 된 많은 작은 트릭입니다.
이것은 이미 언급되었지만 반복하고 싶습니다. TIO에서는 my $f =
헤더에 코드를 작성하고 블록을 코드로 작성하고 바닥 글을로 시작할 수 ;
있습니다. 이것은 작업을 수행하는 가장 짧은 방법 인 것 같습니다 (입력 내용을 신경 쓰지 않아도되므로 인수로 제공됩니다).
또 다른 좋은 방법은 -n
또는 -p
스위치를 사용하는 것이지만 TIO에서 작동시키는 방법을 찾지 못했습니다.
즉, 대신 1 개의 문자를 저장하고 저장할 thing.method(foo,bar)
수 있습니다 thing.method:foo,bar
. 불행히도, 분명한 이유로 결과에 다른 메소드를 호출 할 수 없으므로 블록의 마지막 메소드에만 사용하는 것이 좋습니다.
$_
최대한 많이 사용하십시오이 때문에 여러 개별 인수보다 단일 목록 인수를 취하는 것이 더 나은 경우도 있습니다. 액세스 할 때 $_
, 당신은 점으로 시작하여 메소드를 호출 할 수 있습니다 : 예는 .sort
동일합니다 $_.sort
.
그러나 각 블록은 자체 $_
블록을 가지므로 외부 블록의 매개 변수는 내부 블록으로 전파되지 않습니다. 내부 블록에서 메인 기능의 파라미터에 액세스해야하는 경우 ...
^
수없는 경우 변수를 사용하십시오.$_
다음 ^
과 같이시길과 변수 이름 사이에를 삽입하십시오 $^a
. 이들은 블록 안에서만 작동합니다. 컴파일러는 먼저 블록에 몇 개가 있는지 계산하고 사전 식으로 정렬 한 다음 첫 번째 인수를 첫 번째 인수에 지정하고 두 번째 인수를 두 번째 인수에 지정합니다. ^
필요성은 가변 최초로 검출에 사용된다. 따라서 {$^a - $^b}
2 개의 스칼라를 빼고 뺍니다. 중요한 것은 알파벳 순서뿐이므로 {-$^b + $^a}
같은 것입니다.
혹시 뾰족한 블록 구문을 (같이 사용하는 것 같은 느낌 경우 ->$a,$b {$a.map:{$_+$b}}
), 당신은 훨씬 더를 사용하여 블록의 시작에 가짜 문을 작성하는 길 이죠 ^
(같은 메인 블록에 사용하지 않을거야 각 인수에 대해 {$^b;$^a.map:{$_+$b}}
) (주 골프를하는 더 좋은 방법은 {$^a.map(*+$^b)}
바로 컨셉을 보여주고 싶었습니다.)
운영자는 매우 강력하며 종종 작업을 수행하는 가장 짧은 방법입니다. 특히 메타 사업자 (인수로 통신을 사업자) []
, [\]
, X
, <<
/ >>
그리고 Z
당신의주의의 가치가있다. meta-op이 다른 meta-op을 인수로 사용할 수 있음을 잊지 마십시오 ( 여기 에서 XZ%%
내가 사용했던 것처럼 ). 당신이 사용할 수있는 지도보다 훨씬 저렴 될 수있는, 너무 메소드 호출 ( 대신 ,하지만 조심, 그들은 같은 아니에요! ). 마지막으로 바이너리를 사용하기 전에 훨씬 적은 수의 문자로 동일한 작업을 수행 한다는 점을 명심 하십시오.>>
@list>>.method
@list.map(*.method)
<< >>
Z
많은 메타 -op를 서로 힙핑하는 경우 대괄호를 사용하여 우선 순위를 지정할 수 있습니다 []
. 너무 많은 연산자를 쌓아 컴파일러를 혼란스럽게 할 때 절약 할 수 있습니다. (매우 자주 발생하지는 않습니다.)
마지막으로, BOOL, 지능 또는 str을에 강제 변환 것들에 필요한 방법을 사용하지 않는 경우 .Bool
, .Int
그리고 .Str
, 오히려 사업자 ?
, +
및 ~
. 또는 더 나은 방법으로 산술 표현식에 넣어서 Int 등으로 강제하는 것입니다. 목록의 길이를 얻는 가장 짧은 방법은 +@list
입니다. 2를 목록 길이의 거듭 제곱으로 계산하려면 그냥 말하면 2**@list
올바른 일을 할 것입니다.
$
를 사용 @
하고%
각 블록에서 $
(또는 @
또는 %
) 의 모든 발생은 반짝이는 새 스칼라 (또는 배열 또는 해시) 상태 변수 (값이 블록에 대한 호출에서 지속되는 변수)를 나타냅니다. 소스 코드에서 한 번만 참조해야하는 상태 변수가 필요한 경우이 세 가지가 큰 친구입니다. (대부분 $
.) 예를 들어, 역 수학 사이클 챌린지에서는으로 인덱스 된 배열에서 주기적으로 연산자를 선택하는 데 사용할 수 있습니다 $++%6
.
map
, grep
외.의미 : 대신 할 map {my block},list
보다 list.map({my block})
. 를 사용하더라도 list.map:{my block}
이러한 두 가지 접근 방식은 동일한 바이트 수로 나타납니다. 그리고 종종 메소드를 호출 할 때 목록을 괄호로 묶어야하지만 서브를 호출 할 때는 그렇지 않습니다. 따라서 하위 접근 방식은 항상 방법 방법과 동일하거나 적어도 동일합니다.
여기에서 유일한 예외는 map
ped, grep
ped 등 의 오브젝트 가에있는 경우 $_
입니다. 그럼 .map:{}
분명히 이겼다 map {},$_
.
&
과 |
) 대신 &&
하고 ||
.분명히, 그들은 1 바이트 더 짧습니다. 반면에 부울 컨텍스트로 강제로 축소해야합니다. 이것은 항상으로 수행 할 수 있습니다 ?
. 여기서 당신은 !
op
bool 컨텍스트를 강제 op
하고 결과를 사용 하고 부정 하는 meta-op에 대해 알고 있어야합니다 .
당신은 목록을 가지고 있고 사용하지 않는, 접합으로 바꿀하려는 경우 [&]
와 [|]
. 대신 .any
및을 사용하십시오 .all
. 또한이 .none
그렇게 쉽게 접합 작전에 의해 모방 할 수없는.
&&
하고 ||
여전히 단락에 유용합니까?
여기에는 몇 가지 부분이 있습니다.
사용하여 선언 된 변수는 my
일반적으로 my
변수 이름 사이에 공백없이 선언 될 수 있습니다 . my @a
와 같습니다 my@a
.
다음과 같이 백 슬래시를 사용하여 변수를 선언하여 변수 이름 앞의시길을 제거 할 수 있습니다.
my \a=1;
(불행히도 공백을 제거 할 수 없습니다 :()
나중에 나중에 변수 이름으로 참조 할 수 있으므로 유용합니다.
a=5;
a.say
기본적으로 코드의 다른 곳에서 변수를 두 번 이상 사용하면 바이트가 절약됩니다. 단점은 변수를 초기화해야한다는 것입니다.
$!
및$/
이러한 사전 선언 된 변수는 일반적으로 예외 및 정규식 일치에 각각 사용되지만을 사용하여 정의 할 필요는 없습니다 my
.
$!=1;
$/=5;
$/
배열로 사용하고 바로 가기 $
와 숫자를 사용하여 $/
배열의 해당 요소에 액세스하는 것이 특히 유용합니다 .
$/=100..200;
say $5; #105
say $99; #199
...
대신 사용first
일반적으로 어떤 조건과 일치하는 첫 번째 숫자를 찾으려면 &f
다음과 같이 나타낼 수 있습니다.
first &f,1..*
그러나 대신 ...
연산자를 사용할 수 있습니다 .
+(1...&f)
에서 시작 0
해야하는 경우 -1
이후에 대신 사용할 수 있습니다 +
.
@a
condition이 있는 목록에서 첫 번째 요소의 색인을 원하면 &f
일반적으로 다음을 수행하십시오.
first &f,@a,:k
대신 :
(@a...&f)-1
(또는 색인이 0 인 경우 그 반대). 같은 방식으로 모든 요소를 조건을 통과 한 첫 번째 요소까지 가져올 수 있습니다.
이것의 단점은 목록 이 어떤 시점에서 조건을 통과해야한다는 ...
것입니다. 그렇지 않으면 연산자는 목록의 끝을 외삽하여 오류를 던질 것입니다. 왼쪽의 Whatever 코드는 시퀀스의 일부로 해석되므로 사용할 수 없습니다.
say (3² + 4², 2²⁰, 5⁻²)
==> 와 함께 유니 코드 지수를 사용할 수도 있습니다(25 1048576 0.04)
. 이 같은 학대 할 수 있습니다 유니 코드의 전체 목록은 여기에 있습니다 : docs.perl6.org/language/unicode_texas .