# Scalars A scalar is the unit value of Perl. It holds one of: a number (integer or float), a string, a reference, or `undef`. The sigil is `$`, in every position where the value is a single scalar — including when the value is one element of an array or hash: ```perl $x # the scalar named x $arr[0] # the first element of @arr — also a scalar $h{key} # one value from %h — also a scalar ``` A scalar is *not* statically typed. The same variable can hold a number now and a string a moment later. Perl converts between the two whenever an operator demands one shape or the other; see [numbers and strings](numeric-strings.md). ## Truth, definedness, and `undef` Two related but distinct questions about a scalar: ```perl defined $x # is there any value at all? $x ? T : F # is the value true? ``` A scalar is **false** in boolean context if it is one of: ```perl undef # the undefined value 0 # numeric zero 0.0 # also numeric zero "" # empty string "0" # the literal string "0" ``` Everything else is true. Note `"00"`, `"0.0"`, `"0 but true"`, and `"0E0"` are all *true* — they are non-empty strings that don’t match the literal `"0"`. The last two are common idioms for ”this function returned successfully but there was nothing to count“: ```perl sub touch_files { my $count = 0; $count++ for grep { -e $_ && utime undef, undef, $_ } @_; return $count || '0E0'; # true even on zero work, so callers # can write `if (touch_files(...))` } ``` `defined` is the only way to tell `undef` from the false-but-defined values. A common bug: ```perl if ($cache{$key}) { ... } # WRONG — false for empty/0/undef if (exists $cache{$key}) { ... } # right — pure presence test if (defined $cache{$key}) { ... } # right — value-not-undef test ``` Use [`defined`](../perlfunc/defined.md) when the only thing you care about is ”is there a value here at all“; [`exists`](../perlfunc/exists.md) for ”is this key/index in the container“ (the two differ for sparse arrays and `delete`d keys). ## Dynamic typing A scalar can change shape during execution: ```perl my $x = 42; # internally an integer $x = "hello"; # now a string $x = 3.14; # now a float $x = \@items; # now a reference ``` Most code never needs to think about which internal shape a scalar currently has. The exceptions are JSON-serialisation libraries that care whether `1` was assigned as a number or a string, and the [`Scalar::Util`](../../Scalar/Util.md) introspection helpers (`looks_like_number`, `dualvar`). ## ”Looks like a number“ When Perl converts a string to a number it stops at the first character that isn’t part of a valid numeric prefix: ```perl "42" + 1 # 43 "42abc" + 1 # 43 — leading digits parsed "abc42" + 1 # 1 — no leading digits, treated as 0 " 42" + 1 # 43 — leading whitespace allowed "4_2" + 1 # 5 — underscores in literals only, NOT in strings "0x1F" + 1 # 1 — hex string is NOT auto-recognised; hex() does ``` The mismatch between numeric *literals* (which honour `_` and `0x`) and numeric *strings* (which do not) is one of the most reported ”why“ questions in Perl. Use [`hex`](../perlfunc/hex.md) / [`oct`](../perlfunc/oct.md) when the input is a string in non-decimal form: ```perl my $bytes = hex "1F"; # 31 my $perms = oct "0755"; # 493 my $perms = oct "0o755"; # 493 — explicit octal prefix my $bytes = oct "0x1F"; # 31 — oct() accepts any prefix ``` Under `use warnings`, an arithmetic operation on a non-numeric string emits *Argument ”…“ isn’t numeric in addition (+)*. The operation still returns 0 — the warning, not a fatal error, is the signal. ## Dual values Some scalars carry both a string and a number form simultaneously, chosen by context. The classic example is `$!`: ```perl $! # in string context: "Permission denied" $! + 0 # in numeric context: 13 ``` You can build your own with [`Scalar::Util::dualvar`](../../Scalar/Util.md): ```perl use Scalar::Util qw(dualvar); my $err = dualvar 13, 'Permission denied'; print "err is $err"; # "err is Permission denied" print "err is " . ($err + 0); # "err is 13" ``` Dual scalars are a niche tool. The common case where one matters is the `$!` errno; the general escape hatch is the dualvar helper. ## ”0 but true“ The literal string `"0 but true"` is the canonical Perl idiom for ”a function whose normal return is a count, but the count is zero and the call succeeded“. It is true (non-empty, non-`"0"`) but numerically equals 0: ```perl my $hits = "0 but true"; if ($hits) { print "succeeded\n"; } # prints print $hits + 0; # 0 print "got $hits results\n"; # got 0 but true results ``` The compiler also recognises `"0 but true"` specifically and skips the *isn’t numeric* warning that any other ”0 followed by garbage“ string would emit. ## See also - [Numbers and strings](numeric-strings.md) — how integer, float, and string forms convert into one another and where the corners are. - [References](references.md) — `\X` produces a scalar that points to another value. - [Context](context.md) — when a scalar gets one value vs many. - [`defined`](../perlfunc/defined.md), [`undef`](../perlfunc/undef.md) — test for and produce the undefined value. - [`scalar`](../perlfunc/scalar.md) — force scalar context on a list or array. - [`$_`](../perlvar/default.md) — the implicit scalar for many built-ins.