Skip to content

Perl Scalars

A scalar is Perl’s fundamental data type for representing a single value. This value can be a number (integer or floating-point), a string of characters, or a reference (which is a scalar that points to another data structure like an array, hash, or subroutine). Scalar variables are prefixed with a dollar sign ($).

Here’s a basic example illustrating scalar variables:

#!/usr/bin/perl
use strict;
use warnings;
my $age = 30; # An integer
my $name = "Alice Wonderland"; # A string
my $price = 19.99; # A floating-point number
my $undefined_var; # Initially holds 'undef'
print "Name: $name\n";
print "Age: $age\n";
print "Price: $price\n";
if (defined $undefined_var) {
print "Undefined Var: $undefined_var\n";
} else {
print "Undefined Var is undef\n";
}

This will produce the following result:

Name: Alice Wonderland
Age: 30
Price: 19.99
Undefined Var is undef

Numeric scalars can be integers or floating-point numbers. Perl handles conversions between them automatically as needed. Numbers can also be specified in octal (base 8, prefix 0) or hexadecimal (base 16, prefix 0x). Underscores can be used within numbers for readability (e.g., 1_000_000).

#!/usr/bin/perl
use strict;
use warnings;
my $integer_val = 2023;
my $negative_val = -50;
my $float_val = 3.14159;
my $scientific_notation = 6.022e23; # Avogadro's number
my $octal_val = 0377; # 255 in decimal (3*64 + 7*8 + 7*1)
my $hex_val = 0xFF; # 255 in decimal (15*16 + 15*1)
my $large_number = 1_234_567.89;
print "Integer: $integer_val\n";
print "Negative: $negative_val\n";
print "Float: $float_val\n";
print "Scientific: $scientific_notation\n";
print "Octal (0377) in decimal: $octal_val\n";
print "Hex (0xFF) in decimal: $hex_val\n";
print "Large Number: $large_number\n";

Output:

Integer: 2023
Negative: -50
Float: 3.14159
Scientific: 6.022e+23
Octal (0377) in decimal: 255
Hex (0xFF) in decimal: 255
Large Number: 1234567.89

String scalars are sequences of characters. They can be defined using single quotes ('...') or double quotes ("...").

  • Single-quoted strings: Perform almost no interpolation. Only \' (to embed a single quote) and \\ (to embed a backslash) are special.
  • Double-quoted strings: Perform variable interpolation (e.g., $variable is replaced by its value) and escape sequence processing (e.g., \n for newline, \t for tab).
#!/usr/bin/perl
use strict;
use warnings;
my $fruit = "apple";
my $single_quoted = 'This is a $fruit. \n (literal)';
my $double_quoted = "This is an $fruit. \n (interpolated)";
my $escaped_chars = "Path: C:\\Program Files\\My App\nPrice: \$100";
print "Single: $single_quoted\n";
print "Double: $double_quoted"; # Note: no \n here, using from string
print "Escaped: $escaped_chars\n";

Output:

Single: This is a $fruit. \n (literal)
Double: This is an apple.
(interpolated)Escaped: Path: C:\Program Files\My App
Price: $100

Perl provides various operators for scalars. Numeric operators (+, -, *, /, %, **) work on numbers. String concatenation is done with the dot operator (.). The string repetition operator is x.

#!/usr/bin/perl
use strict;
use warnings;
my $greeting = "Hello" . " " . "Perl!"; # String concatenation
my $sum = 10 + 5.5; # Numeric addition (result is 15.5)
my $product = 3 * 7; # Numeric multiplication
my $repeated_str = "Ha" x 3; # String repetition ("HaHaHa")
my $mixed_concat = $greeting . $sum; # Numbers converted to strings for concatenation
print "Greeting: $greeting\n";
print "Sum: $sum\n";
print "Product: $product\n";
print "Repeated: $repeated_str\n";
print "Mixed: $mixed_concat\n";

Output:

Greeting: Hello Perl!
Sum: 15.5
Product: 21
Repeated: HaHaHa
Mixed: Hello Perl!15.5

Perl automatically converts between strings and numbers based on the operator being used. This is called auto-vivification or DWIM (Do What I Mean) behavior. Use looks_like_number from Scalar::Util to check if a scalar looks like a number.

For longer multiline strings, “here documents” are convenient. They start with << followed by a delimiter token, then the string content on subsequent lines, and end with the same delimiter token on a line by itself.

#!/usr/bin/perl
use strict;
use warnings;
my $message_type = "Urgent";
my $email_body = <<"END_OF_EMAIL";
To: recipient@example.com
From: sender@example.com
Subject: $message_type Message
This is the body of the email.
It can span multiple lines.
Best regards,
The Sender
END_OF_EMAIL
print $email_body;
# Indented here-doc (Perl 5.26+)
my $indented_text = <<~"STOP";
This line is indented.
So is this one.
STOP
print "---\n$indented_text---";

If the delimiter is quoted (e.g., <<"EOF"), it behaves like a double-quoted string (interpolation occurs). If unquoted (e.g., <<EOF), it’s like double quotes. If single-quoted (e.g., <<'EOF'), it’s like a single-quoted string (no interpolation). The ~ before the delimiter (Perl 5.26+) allows the body and the terminator to be indented.

V-Strings (Version Strings / Vector Strings)

Section titled “V-Strings (Version Strings / Vector Strings)”

A literal of the form v1.2.3 or v65.66.67 is a v-string. It’s parsed as a string composed of characters with the specified ordinal values (dot-separated numbers). If there’s only one number after v (e.g. v65), it’s interpreted as a single character with that ordinal value. If there are no dots and more than one number (e.g. v102.111.111), this syntax is primarily for representing version numbers, but Perl may parse v1.2.3 as \x1\x2\x3.

Historically, v-strings were intended for version numbers. Using them to construct arbitrary character strings via ordinals (e.g., v65.66.67 for “ABC”) is less common than chr(65) . chr(66) . chr(67) or "\x41\x42\x43".

#!/usr/bin/perl
use strict;
use warnings;
use utf8; # Important for handling Unicode characters correctly
use feature 'say';
my $version_string = v5.36.0;
say "Version: $version_string"; # Often stringifies to something like "^X6\0"
# To get the intended version representation, it's better to handle it as such:
# printf "Version: %vd\n", $version_string; # prints 5.36.0
my $char_A = v65;
say "Character A (from v65): $char_A"; # Output: A
my $hello_world_ords = v72.101.108.108.111.32.87.111.114.108.100;
say "String from ordinals: $hello_world_ords"; # Output: Hello World
# Modern way to print version objects:
my $perl_version = $^V; # $^V is a special variable holding Perl version as a v-string
printf "Running Perl version: %vd\n", $perl_version;

Output (may vary slightly for version representation without printf %vd):

Version: \x05(\x00
Character A (from v65): A
String from ordinals: Hello World
Running Perl version: 5.xx.y (actual version)

Perl provides special literals that represent information about the current state of the program:

  • __FILE__: The name of the current file.
  • __LINE__: The current line number in the script.
  • __PACKAGE__: The current package (namespace).
  • __SUB__: A reference to the current subroutine (Perl 5.16+).
  • __END__: Logically ends the script. Any text after __END__ can be read from the DATA filehandle.

These are tokens, not variables, so they don’t interpolate directly into double-quoted strings without concatenation.

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
sub show_literals {
say "This code is in package: " . __PACKAGE__;
say "Running from file: " . __FILE__;
say "Currently at line: " . __LINE__;
if (defined &${__SUB__}) { # Check if __SUB__ is available and defined
say "Inside subroutine: " . ((__SUB__)->() ? (__SUB__)->() : 'N/A');
}
}
show_literals();
say "End of main script logic.";
__END__
This is data after __END__.
It can be read via the DATA filehandle.

Output (filename and line numbers will vary):

This code is in package: main
Running from file: ./your_script_name.pl
Currently at line: 9
Inside subroutine: main::show_literals
End of main script logic.