This is the first thing I've written in Perl besides one-liners. It just generates random text based on a text file. I was inspired by this. Any tips on making this better are welcome. I'd especially like to know if there are more idiomatic ways I could do certain things.

#!/usr/bin/env perl
use strict;
use warnings;
use File::Open qw(fopen);
use Data::Munge;

my $k = shift;                  # k-gram length
my $n = shift;                  # number of iterations
my $file = shift;
my $long_string = slurp fopen $file;

# loop through each k-gram; if no entry exists in %markov_chain,
# initialize it to an empty array. In either case, push the next
# k-gram into the array.

my %markov_chain;               # hash of arrays

for my $i (0 .. (length $long_string) - 1) {
  my $curr = substr $long_string, $i, $k;
  my $next = substr $long_string, $i + 1, $k;
  $markov_chain{$curr} //= [];
  push $markov_chain{$curr}, $next;

# Take the first k-gram from the original document. Draw a random
# k-gram from this k-gram's entry in %markov_chain. This will be the
# k-gram for the next iteration. Print the last character of the
# k-gram.

sub rand_elem { $_[rand @_] }

my $seed = substr $long_string, 0, $k;
print $seed;
for my $i (0 .. $n) {
  $seed = rand_elem @{$markov_chain{$seed}};
  print substr $seed, -1;

1 Answer 1


The only thing that comes to mind is the way you open the file.

You could do this instead:

open(my $file, "<", "$ARGV[0]") or die;
$data = do { local $/; <$file> };
close $file;

Which is a well known Perl idiom to read an entire file in one go.

For more info see these links





Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.