[Question]
  [
What general tips do you have for golfing in Perl? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to Perl (e.g. "remove comments" is not an answer). Please post one tip per answer.
  
[Answer]
## TMTOWTDI
That's the most important Perl golfing tip you need to know. Whenever you're looking at some too-long sequence of characters you absolutely have to have in order to accomplish your task, ask yourself if there isn't some other way to get the same effect using a different feature. There usually is. Here are just a handful:
* `~~` enforces a scalar context and is 4 chars shorter than `scalar`.
* `y///c` is one char shorter than `length` when getting the length of `$_`.
* Need to iterate over the chars in `$_`? Replace `split//` with `/./gs`. (Or use `/./g` if you also want to skip newlines.) This works with other variables: replace `split//,$x` with `$x=~/./gs`.
* Every Perl builtin returns something. `print` returns 1, for example, to indicate successful I/O. If you need to initialize `$_` to a true value, for example, `$_=print$foo` allows you to kill two birds with one stone.
* Almost every statement in Perl can be written as an expression, allowing it to be to used in a wider variety of contexts. Multiple statements can be become multiple expressions chained together with commas. Tests can be done with short-circuiting operators `?:` `&&` `||`, and also with `and` and `or`, which do the same thing but with precedence lower than all other operators (including assignment). Loops can be done via `map` or `grep`. Even keywords like `next`, `last` and `return` can be used in an expression context, even though they don't return! Keeping these kinds of transformations in mind give you opportunities to replace code blocks with expressions that can be stuffed into a wider variety of contexts.
[Answer]
Abuse Perl's special variables!
* As noted in a previous answer `$/` and `$"` are initialized by default to `"\n"` and `" "`, respectively.
* `$,` and `$\` are both set to `undef` by default, and are 3 chars shorter.
* Setting `$\` to a value will cause it to be appended to every `print`. For example: `perl -ple '$\="=".hex.$/'` is a handy hex-to-decimal converter.
* If you're not reading files from the command-line, you can use the `-i` command-line switch as an extra channel for inputting a string. Its value will be stored in `$^I`.
* `$=` forces whatever is assigned to it to be an integer. Try running `perl -ple '$_=$==$_'` and giving it various inupts. Likewise, `$-` forces its value to be a non-negative integer (i.e. a leading dash is treated as a non-numeric character).
* You can use `$.` as a boolean flag that is automatically reset to a true (nonzero) value on every iteration of a `while(<>)` loop.
[Answer]
# `-n` and unmatched curly brackets
It is well known that the command line switch `-n` can be used to execute the script once for every line.
`perl --help` says:
```
  -n                assume "while (<>) { ... }" loop around program
```
What it doesn't say explicitly is that Perl doesn't just assume a loop around the program; it *literally* wraps `while (<>) { ... }` around it.
This way, the following commands are equivalent to each other:
```
 perl -e 'while(<>){code}morecode'
 perl -ne 'code;END{morecode}'
 perl -ne 'code}{morecode'
```
# `-p` and unmatched curly brackets
Similarly to the above, the `-p` switch wraps `while (<>) { ... ; print }` around the program.
By using unmatched curly brackets, `perl -p 'code}{morecode'` will only print once after executing `code` for all lines of input, followed by `morecode`.
Since `$_` is undefined when `morecode;print` is executed, the output record separator `$\` can be abused to print the actual output.
For example
```
perl -pe '$\+=$_}{'
```
reads one number per line from STDIN and prints their sum.
[Answer]
Use `$_` to eliminate scalar references. It is the special variable that is used as a default by most functions, and just leaving out parameters is a shortcut to reference this variable. 
By changing `$n` to `$_`, you can change `$n=<>;chop$n;print$n` to `$_=<>;chop;print`
Here, the `print` function prints the contents of `$_` by default, and `chop` also works on `$_`.
[Answer]
Use Perl's special variables where-ever you can, eg:
* Use `$"` instead of `" "`
* Use `$/` instead of `"\n"`
They have the added benefit of being a guaranteed one-character long identifier, with help from the lexer. This makes it possible to glue it to the keyword following it, as in: `print$.for@_`
The list of all the special variables is available here: [Special Variables](http://perldoc.perl.org/perlvar.html)
[Answer]
Don't use `qw`. This is waste of two characters that could be used in better way. For example, don't write the following.
```
@i=qw(unique value);
```
Instead use barewords.
```
@i=(unique,value);
```
Or if you cannot use barewords, use `glob` syntax.
```
@i=<unique value>;
```
`glob` syntax can also be used for interesting effects.
```
@i=<item{1,2,3}>;
```
[Answer]
Use statement modifiers instead of compound statements.
Compound statements tend to require parentheses for the argument and braces for the block, whereas statement modifiers need neither.
Compare:
* `$a++,$b++while$n--` vs `while($n--){$a++;$b++}`
* `chop$,if$c` vs `if($c){chop$,}`
Note that the last example ties with `$c&&chop$,`, but starts really shining for most multi-statement operations. Basically anything that loses operator precedence to `&&`.
[Answer]
Don't `use strict`. (don't quote me on this, PCG.SE context kinda matters) And, more importantly, don't code as if under strict. The usual suspects:
* don't `my`-declare variables if you can avoid it. The only variables that really need `my` are those you want lexically scoped. That's barely any of them when golfing, where you don't need scope protection and tend to fully control recursion.
* don't quote one-word strings: ([example](https://codegolf.stackexchange.com/a/8746/199)). Do ensure you don't have a function with the same name, though.
[Answer]
I'm sure some of these have formal names and I'm just not aware of them.
* If you have a while loop (or a for loop you can make into a while loop) you can define the "while" after the command: `print $n++ while ($n < 10)`
* If you need to read everything from STDIN into a string: `$var = join('',<>)`
* As CeilingSpy pointed out, using $/ instead of \n is faster in some situations: `print ('X'*10) . "\n";` is longer than `print ('X'*10) . $/;`
* Perl's `say` function is shorter than `print`, but you'll have to run the code with `-E` instead of `-e`
* Use ranges like `a..z` or even `aa..zz`. If needed as a string, use `join`.
* Incrementing strings: `$z = 'z'; print ++$z;` will display `aa`
That's all I can think of right now. I may add some more later.
[Answer]
# Use non-word characters as variable names
Using `$%` instead of `$a` can allow you to place the variable name right next to an `if`, `for` or `while` construct as in:
`@r=(1,2,3,4,5);$%=4;`
`print$_*$%for@r`
Many can be used, but check the [docs](http://perldoc.perl.org/perlvar.html) and [@BreadBox's answer](https://codegolf.stackexchange.com/questions/5105/tips-for-golfing-in-perl#answer-5957) for which ones have magic effects!
---
# Use map when you can't use statement modifiers
If you can't use statement modfiers as per [@JB's answer](https://codegolf.stackexchange.com/questions/5105/tips-for-golfing-in-perl#answer-5130), map might save a byte:
`for(@c){}` vs. `map{}@c;`
and is useful if you want to do nested iterations as you can put postfix `for` loops inside the `map`.
---
# Use all the magic Regular Expression variables
Perl has magic variables for 'text before match' and 'text after match' so it is possible to split to groups of two with potentially fewer characters:
```
($x,$y)=split/,/,$_;
($x,$y)=/(.+),(.+)/;
/,/; # $x=$`, $y=$'
# Note: you will need to save the variables if you'll be using more regex matches!
```
This might also work well as a replacement for `substr`:
```
$s=substr$_,1;
/./;# $s=$'
$s=substr$_,4;
/.{4}/;# $s=$'
```
If you need the contents of the match, `$&` can be used, eg:
```
# assume input like '10 PRINT "Hello, World!"'
($n,$c,$x)=split/ /,$_;
/ .+ /; # $n=$`, $c=$&, $x=$'
```
---
# Replace subs with long names with a shorter name
If you call say `print` four or more times in your code (this obviously varies with the length of the routine you're calling), replace it with a shorter sub name:
```
sub p{print@_}p;p;p;p
```
vs.
```
print;print;print;print
```
---
# Replace conditional incrementors/decrementors
If you have code like:
```
$i--if$i>0
```
you can use:
```
$i-=$i>0
```
instead to save some bytes.
---
# Convert to integer
If you aren't assigning to a variable and so can't use [breadbox's](https://codegolf.stackexchange.com/q/5957) tip, you can use the expression `0|`:
```
rand 25 # random float eg. 19.3560355885212
int rand 25 # random int
0|rand 25 # random int
rand 25|0 # random int
~~rand 25 # random int
```
It's worth noting however than you don't need to use an integer to access an array index:
```
@letters = A..Z;
$letters[rand 26]; # random letter
```
[Answer]
`redo` adds loop behavior to a block without `for` or `while`. `{redo}` is an infinite loop.
[Answer]
Don't parenthesize function calls.
Perl lets you call a known (core or predeclared) function using the `NAME LIST` syntax. This lets you drop the `&` sigil (if you were still using it) as well as the parentheses.
For example: `$v=join'',<>`
[Full documentation](http://perldoc.perl.org/perlsub.html)
[Answer]
You can run multiple different statements within nested ternary logic.
Suppose you have a big `if`-`elsif` statement. This could be any logic and any number of statements.
```
if( $_ < 1 ) {
    $a=1;
    $b=2;
    $c=3;
    say $a.$b.$c;
} elsif($_ < 2 ) {
    $a=3;
    $b=2;
    $c=1;
    say $a.$b.$c;
} elsif( $_ < 3) {
    $a=2;
    $b=2;
    $c=2;
    say $a.$b.$c;
}
```
You can use `(cmd1, cmd2, cmd3)` inside the ternary operator to run all of the commands.
```
$_ < 1 ?
    ($a=1,$b=2,$c=3,say$a.$b.$c):
$_ < 2 ?
    ($a=3,$b=2,$c=1,say$a.$b.$c):
$_ < 3 ?
    ($a=2,$b=2,$c=2,say$a.$b.$c):
0; #put the else here if we have one
```
Here's a dummy example:
```
perl -nE'$_<1?($a=1,$b=2,$c=3,say$a.$b.$c):$_<2?($a=3,$b=2,$c=1,say$a.$b.$c):$_<3?($a=2,$b=2,$c=2,say$a.$b.$c):0;' <(echo 2)
```
[Answer]
# If you need an alternating boolean
Instead of doing something like `$-++%2`, use `$|--`.
[Try it online!](https://tio.run/##K0gtyjH9/7@gKDOvRKVGVzctv0jBUE/P0OD//3/5BSWZ@XnF/3VzAA "Perl 5 – Try It Online")
[Answer]
Try to use the value of an assignment expression, like so:
```
# 14 characters
$n=pop;$o=$n&1
# 13 characters, saves 1
$o=($n=pop)&1
```
This works because `$n` is 2 characters in Perl. You may change `$n` to `()` at no cost, and save 1 semicolon by moving the assignment into the parentheses.
[Answer]
# Use the free `;` from `-n`/`-p`
Thanks to [@Neil](https://codegolf.stackexchange.com/users/17602/neil) for letting me know this tip wasn't in the list!
Further to [@Dennis' tip](https://codegolf.stackexchange.com/a/32884/9365) of using the implicit code added via `-n`/`-p`, a `;` is inserted as well and using this to your advantage, you can sometimes save a byte:
Using `$;` as the final variable:
`$a=$_*say$--1?"...":$_-1if$-=$_-1-$a` vs. [`$;=$_*say$--1?"...":$_-1if$-=$_-1-$`](https://codegolf.stackexchange.com/a/249643/9365)
Used with a quote-like operator:
`s/(.)(.)/$2$1/` vs. [`s;(.)(.);$2$1`](https://codegolf.stackexchange.com/a/249567/9365)
Or used with a list:
`pop@a;push@a,/\w+/g;$,="/";/{/&&say@a` vs.
[`pop@;;push@;,/\w+/g;$,="/";/{/&&say@`](https://codegolf.stackexchange.com/a/246920/9365)
The only stipulation is that it needs to be the last statement.
[Answer]
# Use `select(undef,undef,undef,$timeout)` instead of `Time::HiRes`
(Taken from <https://stackoverflow.com/a/896928/4739548>)
Many challenges require you to sleep with greater precision than integers. `select()`'s timeout argument can do just that.
```
select($u,$u,$u,0.1)
```
is much more efficient than:
```
import Time::HiRes qw(sleep);sleep(0.1)
```
The former is only 20 bytes, whereas the latter takes up 39. However, the former requires you aren't using `$u` and have never defined it.
If you're going to use it a lot importing `Time::HiRes` pays off, but if you only need it once, using `select($u,$u,$u,0.1)` saves 19 bytes, which is definitely an improvement in most cases.
[Answer]
## Use expression regexes.
Decent illustration of this is the following code shaping the input into sine wave:
```
s/./print" "x(sin($i+=.5)*5+5).$&/eg;
```
As you can see, it's a pretty compact way of iterating over characters in standard input. You could use other regex to change the way how things are matched.
[Answer]
# Use globs like string literals
Occasionally (often when dealing with [quine](/questions/tagged/quine "show questions tagged 'quine'") or [restricted-source](/questions/tagged/restricted-source "show questions tagged 'restricted-source'") challenges) you benefit greatly from the ability to nest string literals. Normally, you'd do this with `q(…)`. However, depending on what characters you need inside the string, you may be able to save a byte and use `<…>`, the glob operator. (Note that what's inside the angle brackets can't look like a filehandle, and can't look like it's meant to be expanded into a list of filenames, which means that quite a lot of characters won't work correctly.)
[Answer]
# Useful escape sequences
See [perlrebackslash](https://perldoc.perl.org/perlrebackslash.html), but you can potentially save a lot of bytes using these effectively.
In matches:
```
[A-Za-z]        \pl
[^A-Za-z]       \Pl
(?<=\w)         \B
```
In replacements (or double quoted strings):
```
\utext          Text            (e.g s/ (.)/uc$1/e vs. s/ (.)/\u$1/)
\Utext          TEXT
\lTEXT          tEXT
\LTEXT          text
```
[Answer]
# Don't reassign `$_` in nested `for`/`map`s
If you aren't using `m//` or `s///` in the body of the loop, you can make the most of `$'` in a nested loop by performing an empty match (`//`) and using `$'` instead of assigning `$_` to another variable:
```
$i=$_,say map{qw(0 * +)[max(abs,abs$i)%3]}@;for @;=- --$_..$_
```
vs.
```
//,say map{qw(0 * +)[max(abs,abs$')%3]}@;for@;=- --$_..$_
```
[Answer]
# Use `sub` signatures
If you're submitting a function, using `-Mfeature+signatures` might save you 4 bytes vs. using `@_`:
```
sub{($a,$b)=@_;...}
sub($a,$b){...}
```
[Answer]
# Use hash keys for random ordering.
If a set of items needs to be in a random order, or you need a (pseudo)random subset of items, storing them as hash keys will allow them to be ordered randomly without a call to `rand`. The order will remain consistent within a program run as long as no insertions or deletions are made to the hash.
# Hash keys can be defined quickly
If the information to be stored/randomized is already in an array, the hash can quickly be created with:
```
 @hash{@array}++;
```
The values of the hash are not particularly useful here, but then the array elements can be retrieved in a random order with:
```
@random_ordered_array = keys %hash;
```
[Answer]
# Shorten your print statements
Unless the challenge specifies otherwise, you don't need trailing newlines.  
Our 'challenge' says 'output a random number from 0 to 9 to STDOUT'. We can take this code (28 bytes):
```
$s=int(rand(10));print"$s\n"
```
And shorten it to this (25 bytes):
```
$s=int(rand(10));print $s
```
by simply printing the variable. This last one only applies to this challenge specifically (19 bytes):
```
print int(rand(10))
```
but that only works when you don't have to do anything to the variable in between assignment and printing.
[Answer]
# If you need a variable that is falsy on first call and truthy thereafter
Instead of something like `!!$x++`, use `$|++`.
[Try it online!](https://tio.run/##K0gtyjH9/7@gKDOvRKVGWzstv0jBUE/P0OD//3/5BSWZ@XnF/3VzAA "Perl 5 – Try It Online")
[Answer]
# Use `s///` to set `$_` instead of `$_="..."`
If you ever need to set an empty `$_` to, or add a prefix of, a value that would otherwise require quoting, using `s//<value to set>/` can save a byte:
```
$_="A'B"; # vs:
s//A'B/;
```
[Answer]
Chain transliterations and substitutions with the `/r` modifier instead of assigning to `$_` first, and directly use the result, rather than using `$_` (possibly implicitly) in a separate statement. For example, if your code does:
```
$_="complex_string";s/pat/repl/;print
# Or when $_ is in use, the even more verbose
$a="complex_string";$a=~/pat/repl/;print$a
```
you can shave two characters, and free up `$_` for other uses, with:
```
print"complex_string"=~s/pat/repl/r
```
[Answer]
# Arrays become strings become numbers
When needing to do math involving the first element of an array, `"@array"` will evaluate to the same value as `$array[0]` and is one byte shorter. This assumes that the value of `$"` has not been modified in a way that would join the elements of the array into a single number when concatenated together.
This is because `"@array"` expands to `$array[0].$".$array[1].$".$array[2]...`. When Perl parses a scalar in a numeric context, it stops parsing it after encountering a character that is not part of the number, leaving just the first number in the string to be used as the value.
[Answer]
# Two copies of input
The `-F` and `-a` give you a split version of your input in `@F` as well as the complete input in `$_`. Both `@F` and `$_` can be used and modified as needed.
]