An interesting layout, with interesting challenges. Here are some ideas that came to mind as I looked at it -- you might consider: Keeping all the initialization data in its own file, separate from the code, is usually helpful for maintenance -- fixing data is different from fixing code. Here's what the code might look like for loading such data:
my %game_data; open( IN, "<", "game_data.txt" ) or die "game_data.txt: $!"; while (<IN>) { chomp; my ( $key, @values ) = split( /\s*[:|]\s*/ ); $game_data{$key} = [ @values ]; } close IN; my %init_func = { color = sub { my $val=some_simple_op(); return $val}, roll = \&roll, ... } for my $key ( keys %game_data ) { my @replace_vals = (); for my $val ( @{$game_data{$key}} ) { if ( $val =~ /[@&]_\S+/ ) { # need to split and process my @words = split ' ', $val; $val = ''; for my $wrd ( @wrds ) { if ( $wrd =~ /\@_(\S+)/ ) { my $refkey = $1; if ( exists( $game_data{$refkey} )) { my $n = @{$game_data{$refkey}}; $wrd = $game_data{$refkey}[rand $n]; } else { warn "No $refkey in game_data for $key\n"; } } elsif ( $wrd =~ /\&_(\S+)/ ) { my ( $refkey, @args ) = split /[:,]/, $1; if ( exists( $init_func{$refkey} )) { $wrd = $init_func{$refkey}->(@args); } else { warn "No $refkey function for $key\n"; } } $val .= "$wrd "; } } push @replace_vals, $val; } $game_data{$key} = [ @replace_vals ]; }
You'll probably want to tweak that to suite your tastes for notations and additional flexibility (and I haven't tried testing it, so it may need some fixing as well).

There is one likely (possibly vexing) downside to this approach: the sequence in which %game_data elements are initialized (replacement values put in as needed) will matter, e.g. if a key/array "foo" depends on values from key/array "bar", which depends on values from "glub", etc. If "foo" elements get processed first, they will contain "unprocessed" strings from the "bar" list.

To get around that, the data file would need to be ordered according to "primitive sets first", "first-order dependencies next", etc, so that any line with "template symbol" references to arrays is guaranteed to come after the arrays that it references.

In that case, you'll need to move the logic for parsing and replacement of values into the "while" loop that reads the file. The for ( keys %game_data ) loop that I suggested above would do them in random order, which would probably do the wrong thing.


In reply to Re^2: Creating a random generator by graff
in thread Creating a random generator by Lady_Aleena

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.