Perl special variables

Input and output special variables

$_- Default input and pattern search variables

# 在循环中使用默认变量
foreach (1..5) {
    print;  # 打印 $_
}

# 在模式匹配中使用
$_ = "Hello World";
print if /World/;  # 如果包含 World 则打印

# 在 grep 和 map 中使用
my @evens = grep { $_ % 2 == 0 } (1..10);
my @squared = map { $_ * $_ } (1..5);

@_- Array of subroutine parameters

sub add {
    my ($a, $b) = @_;
    return $a + $b;
}

print add(10, 20);  # 30

$.- Current line number

while (my $line = <STDIN>) {
    print "Line $.: $line";
}

$/- Enter record separator

# 读取整个文件
local $/;
my $content = <FILE>;

# 段落模式(空行分隔)
$/ = "";
my @paragraphs = <FILE>;

# 自定义分隔符
$/ = "---\n";
my @records = <FILE>;

$\- Output record delimiter

local $\ = "\n";  # 每次打印后自动添加换行符
print "Hello";     # 输出:Hello\n
print "World";     # 输出:World\n

$|- Automatic refresh

$| = 1;  # 启用自动刷新
print "Processing...";  # 立即输出
sleep(2);
print "Done\n";

$"- List interpolation separator

$" = ", ";
my @array = (1, 2, 3);
print "@array";  # 输出:1, 2, 3

$,- Output field separator

$, = " - ";
print "a", "b", "c";  # 输出:a - b - c

Pattern matching special variables

$1, $2, $3, ... - capturing group

if ("hello world" =~ /(hello) (\w+)/) {
    print "$1\n";  # hello
    print "$2\n";  # world
}

if ("2024-01-15" =~ /(\d{4})-(\d{2})-(\d{2})/) {
    print "Year: $1, Month: $2, Day: $3\n";
}

$&- matching string

if ("hello world" =~ /world/) {
    print "Matched: $&\n";  # world
}

`$`` - the string before the match

if ("hello world" =~ /world/) {
    print "Before: $`\n";  # hello 
}

$'- The matched string

if ("hello world" =~ /world/) {
    print "After: $'\n";  # 空
}

if ("hello world test" =~ /world/) {
    print "After: $'\n";  #  test
}

$+- the last capturing group

if ("test@example.com" =~ /(\w+)@(\w+)\.(.+)/) {
    print "Last capture: $+\n";  # com
}

$^N- Recently completed capture groups

if ("test123" =~ /(test)(\d+)/) {
    print "Most recent: $^N\n";  # 123
}

Process special variables

$$- Current process ID

print "PID: $$\n";

$?- The exit status of the last child process

system("ls -l");

if ($? != 0) {
    print "Command failed with status: $?\n";
}

# 获取退出码和信号
my $exit_status = $? >> 8;
my $signal = $? & 127;

$0- Program name

print "Program name: $0\n";

$^O- Operating system name

print "OS: $^O\n";  # linux, darwin, MSWin32 等

$^T- Script start time

my $start_time = $^T;
print "Start time: ", scalar localtime($start_time), "\n";

# 计算运行时间
my $elapsed = time - $^T;
print "Elapsed: $elapsed seconds\n";

$^X- Perl interpreter path

print "Perl interpreter: $^X\n";

File handle special variables

ARGV- Command line parameters

# 读取命令行指定的文件
while (<>) {
    print;
}

# 访问当前文件名
print "Current file: $ARGV\n";

@ARGV- Array of command line parameters

foreach my $arg (@ARGV) {
    print "Argument: $arg\n";
}

STDIN, STDOUT, STDERR

# 标准输入
my $input = <STDIN>;

# 标准输出
print STDOUT "Output to STDOUT\n";

# 标准错误
print STDERR "Error message\n";

Format special variables

$#- the last index of the array

my @array = (10, 20, 30);
print "Last index: $#array\n";  # 2
print "Array size: " . ($#array + 1) . "\n";  # 3

$%- Current page number

# 在格式化输出中使用
format STDOUT_TOP =
Page @<
$%
.

$=- Number of lines per page

$= = 50;  # 设置每页 50 行

$-- Current number of rows

print "Lines left on this page: $-\n";

$~- Current format name

$~ = "MYFORMAT";
format MYFORMAT =
@<<<<<<<<<< @<<<<<<<<< @>>>>>>>
$name, $email, $salary
.

Regular expression special variables

$^R- The final successful regular expression code execution result

if ("test123" =~ /(?{$count++})test/) {
    print "Code executed $^R times\n";
}

Other important special variables

$!- System error messages

open(my $fh, '<', 'nonexistent.txt')
    or die "Error: $!";

$@-eval error message

eval {
    die "An error occurred";
};

if ($@) {
    print "Error: $@\n";
}

$^E- Extended error messages

open(my $fh, '<', 'file.txt') or die "Error: $!, $^E";

$^I- Edit backup extensions in place

local $^I = '.bak';  # 创建备份文件

while (<>) {
    s/foo/bar/g;  # 替换 foo 为 bar
    print;        # 输出修改后的内容
}

# 运行:perl -i.bak script.pl file1.txt file2.txt

$^F- Maximum system file descriptor size

print "Max file descriptors: $^F\n";

$^H- syntax hash (used internally)

# 用于修改编译器行为

$^M- Emergency memory pool

# 用于内存不足时的紧急分配
$^M = ' ' x 1024 * 1024;

$^P- debugger flags

$^P = 0x01;  # 启用单步调试

$^S- Current interpreter status

eval {
    print "In eval: $^S\n";  # 1
};

print "Not in eval: $^S\n";  # 0

$^V- Perl version

my $version = $^V;
printf "Perl version: v%d.%d.%d\n",
       $version->[0], $version->[1], $version->[2];

Practical example

Example 1: Line numbers and file handling

#!/usr/bin/perl
use strict;
use warnings;

my $file = shift or die "Usage: $0 <filename>";

open(my $fh, '<', $file) or die "Cannot open $file: $!";

my $line_count = 0;

while (my $line = <$fh>) {
    chomp $line;
    $line_count++;
    printf "%4d: %s\n", $., $line;
}

close($fh);

print "\nTotal lines: $line_count\n";

Example 2: Regular expression extraction

#!/usr/bin/perl
use strict;
use warnings;

my $text = "Contact us at support@example.com or sales@example.com";

while ($text =~ /(\w+)@(\w+)\.(\w+)/g) {
    print "Email: $&\n";
    print "Username: $1\n";
    print "Domain: $2\n";
    print "TLD: $3\n";
    print "Context: $` <<MATCH>> $'\n";
    print "-" x 40 . "\n";
}

Example 3: Command line tools

#!/usr/bin/perl
use strict;
use warnings;

print "Script name: $0\n";
print "Arguments:\n";

foreach my $i (0..$#ARGV) {
    print "  [$i] $ARGV[$i]\n";
}

print "\nTotal arguments: " . scalar(@ARGV) . "\n";
print "Perl version: $^V\n";
print "OS: $^O\n";
print "PID: $$\n";

# 读取命令行指定的文件
if (@ARGV) {
    print "\nProcessing files:\n";
    while (<>) {
        print "File $ARGV, Line $.: $_";
    }
}

Example 4: Progress display

#!/usr/bin/perl
use strict;
use warnings;

use Time::HiRes qw(sleep);

$| = 1;  # 启用自动刷新

my @files = ('file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', 'file5.txt');
my $total = scalar(@files);

print "Processing $total files...\n";

for my $i (0..$#files) {
    my $progress = ($i + 1) / $total * 100;
    printf "\rProgress: [%-50s] %.0f%% (%d/%d)",
           "=" x ($progress / 2),
           $progress,
           $i + 1,
           $total;
    
    sleep 0.5;  # 模拟处理
}

print "\nDone!\n";

Summary

This chapter learned about Perl’s special variables:

  1. ✅ Input and output special variables
  2. ✅ Pattern matching special variables
  3. ✅ Process special variables
  4. ✅ File handle special variables
  5. ✅ Format special variables
  6. ✅ Other important special variables

Next, we'll learn about Perl Regular Expressions.