use strict; use warnings; package RandThing; use overload '""' => 'getValue'; my %_groups; # Load default groups while () { chomp; next if ! length; my ($type, @values) = split /,/; $_groups{$type} = \@values; } return 1; sub new { my ($class, $type, @values) = @_; die "RandThing::new must be called using RandThing->new ('type') syntax!\n" if ! defined $class || ref $class; die "$class->new requires a group type parameter\n" if ! defined $type; die "Group type $type is unknown and no values given to define a new type\n" if ! exists $_groups{$type} && ! @values; if (! @values) { # Use an existing group @values = @{$_groups{$type}}; } elsif (ref $values[0]) { $_groups{$type} = \(@values = doLAMagic (@values)); } else { # Add a new group or update an old one $_groups{$type} = \@values; } my $self = bless {values => \@values}, $class; $self->genValue (); return $self; } sub doLAMagic { my ($list, $key) = @_; my @values; return @$list if 'ARRAY' eq ref $list; return @{$list->{$key}} if exists $list->{$key}; return keys %{$list} if $key eq 'keys'; return map (@{$list->{$_}}, keys %{$list}) if $key eq 'all'; $key = 'undef value' if ! defined $key; die "Can't do LA magic on a hash using $key. 'keys' or 'all' required"; } sub getValue { my ($self) = @_; return $self->{value}; } sub genValue { my ($self) = @_; $self->{value} = $self->{values}[rand @{$self->{values}}]; return $self->{value}; } __DATA__ Weather,stormy,windy,rainy,calm Light,bright,dark,gloomy,dazzling DayPart,morning,evening,afternoon,night #### use strict; use warnings; use RandThing; my $dp = RandThing->new ('DayPart'); my $lt = RandThing->new ('Light'); my $wt = RandThing->new ('Weather'); my $tense = RandThing->new ('Tense', 'was', 'is', 'will be'); my $la = RandThing->new ('LA', [qw(Lady Aleena magic)]); print "It $tense a $lt and $wt $dp ($la).\n";