The question should really be titled, "What strings can Perl treat as numbers?", but even that has a nuance.
Perl's data types are polymorphic, and its operators are mostly monomorphic. This means that you can do this:
my $value = "abc" + "def";
print "$value\n";
And quietly, behind the scenes, the string "abc" and the string "def" will be upgraded to numbers. And $value will contain 0.
It is how Perl performs these polymorphic mutations that is tripping you up. The rules are a little hard to remember. But one easy way to remember most of the cases (while missing a few special cases) is that if the string starts with numeric digits, or with a decimal followed by numeric digits, and possibly preceded by a sign, Perl will be able to use the sign and digits in its transmutation. Therefore, a string that looks like "123abc" will be seen in numeric context as the number 123. But a string that looks like "abc123" will be seen as 0 in numeric context.
You are asking about the string "(123)". That string starts with a paren, which is not a digit or a sign. Perl will see it as a non-numeric string, and will treat it as numeric zero in numeric context.
Earlier I said "quietly, behind the scenes", and that's mostly true, unless you enable warnings, in which case string upgrades to their numeric value will trigger a warning if that value is zero and is not based on finding a number at the start of the string.
Update: I realized this doesn't really answer how to make a string be treated as an expression (which is what you are requesting), rather than as a number. There is no simple answer, because strings are just a bunch of characters with very simple semantic meaning. If you want to treat the string with more elaborate semantics, you need a way to accomplish that. The best way is to lex and parse the string. If you don't want to write a lexer and parser yourself, you have options. The simplest option is to eval the string. But that carries risks because Perl's eval will treat the string as Perl code, which means it gives the string more elaborate semantics than you probably intend. But if you are certain that the string cannot be meddled with, and certain that it will look as you expect, string eval can be a reasonable solution.
Another solution is to use a CPAN module that handles mathematical lexing, parsing, and evaluating. Math::Expression is a good starting point.
A naive approach would be to take "(42)" and use tr/// or s/// to strip away the parts you don't want. That may be just fine if you have only simple cases to deal with. But if the input potentially gets more complex than just stripping parens, you could end up bolting on more and more one-off substitutions, and the result could become difficult to maintain and debug.
|