You're confusing the internal representation (as reported by is_utf8) and the external one.
+-----------------------------------------------------------------+
| |
| Decoded Text |
| |
| |
| +--------------------+ downgrade +--------------------+ |
| | Internally encoded | --------------> | Internally encoded | |
| | as UTF-8 | | as iso-8859-1 | |
| | (is_utf8 = 1) | <-------------- | (is_utf8 = 0) | |
| +--------------------+ upgrade +--------------------+ |
| |
+-----------------------------------------------------------------+
| ^
| |
encode | | decode
| |
v |
+-----------------------------------------------------------------+
| |
| Bytes or |
| Encoded Text |
| |
| |
| +--------------------+ downgrade +--------------------+ |
| | Internally encoded | --------------> | Internally encoded | |
| | as UTF-8 | | as iso-8859-1 | |
| | (is_utf8 = 1) | <-------------- | (is_utf8 = 0) | |
| +--------------------+ upgrade +--------------------+ |
| |
+-----------------------------------------------------------------+
- upgrade refers to utf8::upgrade or an implicit upgrade.
- downgrade refers to utf8::downgrade.
- decode refers to Encode::decode, utf8::decode, :encoding on an input stream, etc.
- encode refers to Encode::encode, utf8::encode, :encoding on an output stream, etc.
- is_utf8 refers to Encode::is_utf8 or utf8::is_utf8 (which return the value of the UTF8 flag).
- utf8::upgrade is safe to call on strings that are already upgraded.
- utf8::downgrade is safe to call on strings that are already downgraded.
- It is a bug to encode a string that's already encoded.
- It is a bug to decode a string that's already decoded.
Your code should be
use Encode qw(is_utf8 encode decode);
binmode STDOUT,':encoding(iso-8859-1)';
my $str = "This's a \x{201c}test\x{201d}"; # This is a "decoded" str.
print "$str\n"; # Encoded by :encoding
or
use Encode qw(is_utf8 encode decode);
my $str = "This's a \x{201c}test\x{201d}"; # This is a "decoded" str.
print encode('iso-8859-1', "$str\n");
Why, perl say that it's an utf8 but can't decode it?
Perl said the internal encoding is UTF8. You shouldn't have care what the internal encoding is. (Unfortunately, you still need to know in some circumstances. This isn't one of those.)
if \x{201c} is not an utf8 character
There's no such thing as a "utf8 character" or "UTF-8 character" since utf8 and UTF-8 aren't character sets. \x{201c} generates a Unicode character (U+201C, LEFT DOUBLE QUOTATION MARK) which can be encoded using UTF-8.