Date Created: 2024-06-24 Date Modified: 2024-06-24 ============================================================================ EVAL LOOP ============================================================================ INTRODUCTION ============================================================================ Today, we're exploring an unconventional way to create a loop in Perl using more self-modifying code. This technique, while not practical for everyday use, showcases Perl's flexibility and power. Let's dive into this intriguing code snippet: #!/usr/bin/env perl use feature qw|say|; $_ = <<'EOF'; 10; s~(\d+)(?{ say qq($1) })~$1-1~e; sleep 1; $1 ? eval : say q(Countdown complete!); EOF eval; This code creates a countdown from 10 to 1 without using any traditional loop constructs. Let's break it down. ============================================================================ ============================================================================ PART 1: THE HEREDOC SETUP ============================================================================ We start by assigning a heredoc to the $_ variable. This heredoc contains the code that will be repeatedly evaluated. The first line in the heredoc sets our starting number: 10. ============================================================================ ============================================================================ PART 2: THE SUBSTITUTION OPERATOR ============================================================================ The substitution operator s~~~ is the heart of our loop simulation: s~(\d+)(?{ say qq($1) })~$1-1~e; This line does several things: - It matches a number (\d+) - It prints the matched number using a code block (?{ say qq($1) }) - It replaces the number with itself minus one ($1-1) - The 'e' flag at the end tells Perl to evaluate the replacement as code ============================================================================ ============================================================================ PART 3: SLOWING IT DOWN ============================================================================ We add a sleep 1; to slow down the countdown for visual effect. ============================================================================ ============================================================================ PART 4: THE EXIT CONDITION ============================================================================ The final line in the heredoc is our exit condition: $1 ? eval : say q(Countdown complete!); If $1 (our number) is truthy (non-zero), it evaluates the code again. Otherwise, it prints "Countdown complete!" ============================================================================ ============================================================================ PART 5: KICKING IT OFF ============================================================================ Finally, outside the heredoc, we have a single eval; statement. This kicks off the whole process by evaluating the code in $_. ============================================================================ ============================================================================ PART 6: THE RESULT ============================================================================ When run, this script will count down from 10 to 1, pausing for a second between each number, and then print "Countdown complete!" ============================================================================ CONCLUSION ============================================================================ While this example is more of a curiosity than a practical coding technique, it illustrates Perl's flexibility and the creative ways we can bend the language to our will. It's a reminder of why Perl is often described as a "Swiss Army chainsaw" of programming languages! ============================================================================ perl.gg