Mike: On Sun, Jan 18, 2015 at 07:00:05PM -0500, Mike wrote: > So I've got a text file in a multi column format (three > columns), each column is separated by a single space. Here is a > snippet for reference: > > artless base-court apple-john > bawdy bat-fowling baggage > beslubbering beef-witted barnacle > > I want to be able to randomly select a word from the first > column, then from the second column, then from the third > column, and concatenate them to together into a single string. > Here's the code I currently have, but I'm stuck:
First a little code review. Be sure to always use strict and warnings to help identify bugs. Add this to the top of your programs. use strict; use warnings; Perhaps you're already using it. At the very least, your snippet is strict and warnings approved. :) That said, it is best to include a full example of what you'e trying, including pragmas. It saves us the trouble of emphasizing best practices that you're already following and omitting them might also alter the behavior of code and confuse us and you. So hopefully you're already using strict and warnings, but next time include them in your post too! :) > sub gen_ins { > open(FH, '<', 'insults2.txt') or die "[-] ERROR: Can't find > insult list."; It is better to use lexical file handles. open(my $fh, '<', 'insults2.txt') or die "[-] ERROR: Can't find insult list."; Good job using 3-arg open and handling failure. Often you should include the output of $! in your error message because it will contain information about what exactly went wrong. For example, perhaps insults2.txt exists, but the user doesn't have the necessary permissions to read it. Take that into account also when you're writing your error messages to avoid confusing the user (which may be yourself). open(my $fh, '<', 'insults2.txt') or die "[-] ERROR opening insults list: $!"; > my @cols = split (" ", <FH>); > print "$cols[0]"; > close FH; > } > > gen_ins(); > > When currently run, gen_ins() will print out the first word of > the given column: $cols[0], $cols[1], or $cols[2]. How can I > access the rest of the words below the first? Others have demonstrated good solutions to this problem already. Here's an alternative take emphasizing modularity and reuse. use strict; use warnings; use Readonly; exit(main(@ARGV)); sub main { Readonly::Scalar my $Filename => 'insults2.txt'; my ($max) = (@_, 1); my $insults = load_insults($Filename); for (1..$max) { my @chain = random_insult_chain($insults); local $, = ' '; print @chain, "\n"; } return 0; } sub get_random_index($) { my ($length) = @_; # Note: rand() is not meant to be particular good at picking # randomly. Look to CPAN for alternative options if you need # something *good*. return int rand $length; } sub load_insults { my ($filename) = @_; open my $fh, '<', $filename or die "open $filename: $!"; my @insults; # Load the insults into an array of arrays. while (<$fh>) { my ($first, $second, $third) = split; push @{$insults[0]}, $first; push @{$insults[1]}, $second; push @{$insults[2]}, $third; } close $fh or warn "close $filename: $!"; return \@insults; } sub random_insult_chain { my ($insults) = @_; my @words = map random_insult_word($_), @$insults; return @words; } sub random_insult_word { my ($insult_column) = @_; my $i = get_random_index @$insult_column; my $word = $insult_column->[$i]; return $word; } __END__ Regards, -- Brandon McCaig <bamcc...@gmail.com> <bamcc...@castopulence.org> Castopulence Software <https://www.castopulence.org/> Blog <http://www.bambams.ca/> perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }. q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.}; tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say'
signature.asc
Description: Digital signature