--- name: chop signature: 'chop VARIABLE' signatures: - 'chop VARIABLE' - 'chop( LIST )' - 'chop' since: 5.0 status: documented categories: ["SCALARs and strings"] --- ```{index} single: chop; Perl built-in ``` *[SCALARs and strings](../perlfunc-by-category)* # chop Remove the last character from a string and return it. `chop` shortens its argument in place by exactly one character and returns the character that was removed. It does not scan the string and does not copy it — it simply moves the end. If `VARIABLE` is omitted, `chop` operates on [`$_`](../perlvar). If `VARIABLE` is a hash, `chop` chops every value of the hash (not the keys) and resets the hash's [`each`](each) iterator as a side effect. Any lvalue is a valid target, including an assignment expression. ## Synopsis ```perl chop VARIABLE chop( LIST ) chop ``` ## What you get back The character that was removed, as a string. If the target was empty or undefined, the empty string is returned and the target is left unchanged. When `chop` is applied to a list, every element is chopped but only the character removed from the **last** element is returned. ```perl my $last = chop $line; # one character, or "" if $line was empty ``` ## Global state it touches Reads [`$_`](../perlvar) when called with no argument. No other special variables are consulted — in particular, `chop` is **not** affected by [`$/`](../perlvar) (the input record separator), which is [`chomp`](chomp)'s concern. ## Examples Chop a scalar: ```perl my $s = "hello"; my $c = chop $s; # $s is now "hell", $c is "o" ``` Chop [`$_`](../perlvar) when no argument is given — idiomatic inside a read loop that wants the terminator gone regardless of what it is: ```perl while (<$fh>) { chop; # drops whatever character ends the line push @rows, $_; } ``` Chop a list. Every element loses its last character; the return value is the character removed from the **last** element only: ```perl my @lines = ("foo\n", "bar\n", "baz!"); my $last = chop @lines; # @lines is ("foo","bar","baz"), $last is "!" ``` Chop a hash. Values are chopped, keys are not, and the [`each`](each) iterator is reset: ```perl my %h = (a => "one\n", b => "two\n"); chop %h; # %h is (a => "one", b => "two") ``` Chop an assignment — `chop` works on any lvalue, and an assignment returns one: ```perl chop(my $cwd = `pwd`); # strip the trailing newline from pwd's output ``` Keep all but the last character without modifying the original — not a job for `chop`, which mutates. Use [`substr`](substr) with a negative length instead: ```perl my $head = substr($s, 0, -1); # $s is unchanged ``` ## Edge cases - **Empty or undefined target**: returns the empty string `""` and leaves the target alone. `chop` on [`undef`](undef) does *not* raise a warning by itself; it simply produces `""`. - **Read-only target**: raises `Modification of a read-only value attempted`. This includes string literals and values flagged read-only via `Internals::SvREADONLY`. - **UTF-8 strings**: `chop` removes one **character**, not one byte. A multi-byte character at the end of the string is removed whole and returned as a UTF-8 string. The target's UTF-8 flag is preserved on what remains. - **List return value**: only the character chopped from the last element is returned; the others are discarded. If you need every removed character, chop the elements individually in a loop. - **One character vs. a line ending**: `chop` unconditionally removes **one** character, whatever it is — including spaces, digits, or letters. To conditionally remove a line terminator (what [`$/`](../perlvar) says one looks like), use [`chomp`](chomp). - **Parser parenthesisation**: `chop($x = $y)` chops the result of the assignment, which is `$x`. `chop $x, $y` is parsed as `chop($x), $y` — the comma does not extend `chop`'s argument list without parentheses. Write `chop($x, $y)` when you mean the list form. - **Hash iteration reset**: because `chop %h` walks the values via the hash iterator, any in-progress [`each`](each) loop over `%h` is invalidated. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`chomp`](chomp) — conditional cousin: removes a trailing [`$/`](../perlvar), not an unconditional last character; returns the number of characters removed rather than the character itself - [`substr`](substr) — non-destructive alternative; `substr($s, 0, -1)` returns all but the last character without mutating `$s` - [`s///`](../perlop) — `$s =~ s/.\z//s` is the regex equivalent and the one `chop` is explicitly faster than, because `chop` neither scans nor copies - [`lc`](lc), [`uc`](uc) — other in-place(ish) string transforms that accept any lvalue - [`$_`](../perlvar) — the implicit target when `chop` is called with no argument - [`$/`](../perlvar) — **not** consulted by `chop`; documented here only to flag the contrast with [`chomp`](chomp)