Peter’s blog ✴ Week 286 ✴ 9 September 2024

THE WEEKLY CHALLENGE
My word - and min max

The Perl Camel

Task 1

Self spammer

Write a program which outputs one word of its own script / source code at random. A word is anything between whitespace, including symbols.

Examples


Example 1
If the source code contains a line such as: 
'open my $fh, "<", "ch-1.pl" or die;'
then the program would output each of the words
{ open, my, $fh,, "<",, "ch-1.pl", or, die; }
(along with other words in the source) with some positive 
probability.

Example 2
Technically 'print(" hello ");' is *not* an 
example program, because it does not
assign positive probability to the other two words in the
script.
It will never display print(" or ");

Example 3
An empty script is one trivial solution, and here is 
another:
echo "42" > ch-1.pl && 
   perl -p -e '' ch-1.pl

Analysis

Perhaps the hardest part of this is finding the full path to the current script, so that it can be read in. So far as I know, there is no predefined Perl variable that contains it.

In the end I opted for use File::Spec;.

The rest is trivial. I have written it as 3 lines of code for ease of understanding, but they could all be combined into a single line

Perl Weekly’s review

from PW issue 686

CPAN can be handy when you struggle to find the quick solution. How? Please checkout the post.

Try it 

Try running the script:

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2024-09-09
use utf8;     # Week 286 - task 1 - Self spammer
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use File::Spec;

self_spammer();

sub self_spammer {

    my ($script_path, @words, $rand);
    
    # find location of source script
    $script_path = File::Spec->rel2abs(__FILE__);

    # split it into 'words'
    @words = split(/\s+/, `cat $script_path`);

    # select a random 'word'
    $rand = int(rand(@words));  
    say qq[\nInput: (see script)\nOutput: word $rand of ] . (scalar(@words) - 1) . qq[ is '$words[$rand]'];
}

6 lines of code

Output from script


Output: word 50 of 78 is 'into'

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain