Why does substr not return undef at the end of a string?

perl, substr

Solution

substr($string, length($string), 1)

This gave you an empty string because, `substr` considers the `offset` between `0 to len(str)`, and anything beyond that range is `undef`.

So, `substr("aa", 2, 1);` -> will give you the empty string after last `a` and,`substr("aa", 3, 1);` -> Will give you `undef` (Substring completely outside range)

Similarly: -

- `substr("aa", 2, 2);` -> Will give you the empty string after last `a` (Substring partly outside the range)

Now, for the second one: -

substr($string, length($string) + 1, 1)

This is already past the last allowed `offset`. So it returns `undef` value.

Suppose: -

$str = "abcd";

Then, the index will look like: -

  a   b   c   d             undef
0   1   2   3  len(str)  len(str) + 1

UPDATE: -

So, as @Borodin explained in his post, the character `d` comes between the offsets - `3` and `len(str)` in the above example.

But, if we try to access anything beyond `len(str)` including `len(str)`, we will get an `empty` string, as in the documentation, which says that -

If OFFSET and LENGTH specify a substring that is partly outside the string, only the part within the string is returned.

Also, if we try to access anything beyond `len(str)` excluding the `len(str)`, we will get `undef` value, as in docs: -

If the substring is beyond either end of the string, substr() returns the undefined value and produces a warning.

Problem

I'm not sure whether this is defined behaviour or not. I have the following code: ``` use strict; use warnings; use Data::Dumper; my $string = 'aaaaaa0aaaa'; my $char = substr($string, length($string), 1); my $char2 = substr($string, length($string)+1, 1); print Dumper($char); print Dumper($char2); ``` Besides getting one warning about `substr()` past the end of a string, I'm confused about the output: ``` $VAR1 = ''; $VAR1 = undef; ``` Perldoc says about `substr`: substr EXPR,OFFSET,LENGTH If OFFSET and LENGTH specify a substring that is partly outside the string, only the part within the string is returned. If the substring is beyond either end of the string, substr() returns the undefined value and produces a warning. Both `length($string)` and `length($string) + 1` are beyond the (zero-indexed) end of the string, so I don't know why `substr` returns the empty string in one case and `undef` in the other. Does it have to do with the NULL character that C uses for string termination and that is somehow returned by `substr` in the first case, so that there is an "invisible" last character to this string that is not counted by `length`? Am I missing something obvious here?

Original source