This is rather simplistic, and may look somewhat complex, but note that 1/3rd of the lines are data which could be in a DB or a config file; and half of the code is simply used to generate some test data.

The entire thing is data-driven. Hand code some more attribute types into the __AE__ section (or add some values in the arrays in GenData package and uncomment the first line of main) and nothing else need to change apart from adding event handlers to suit any new events.

The event handlers become class data for the widget class. The attribute-event table becomes class data for the attribute class. The rest, hopefully, is self-explanatory.

#! perl -slw use strict; use Inline::Files; use Data::Dumper; package Widget; my %handlers = ( email => sub{ print "Sending email to $_[ 0 ]" }, phone => sub{ print "Phoning $_[ 0 ]" }, fax => sub{ print "Faxing $_[ 0 ]" }, ); sub new { my( $class, %attribs ) = @_; return bless { map{ $_ => Attribute->new( $_, $attribs{ $_ } ) } keys %attrib +s }, $_[ 0 ]; } sub do_events { my $self = shift; map{ my( $event, $parameter ) = split '=', $_; $handlers{ $event }->( $parameter ); } $self->{ $_ }->events for keys %$self; } 1; package Attribute; my %AttrEvents; my( $type, $value, $events ); push @{ $AttrEvents{ $type }{ $value } }, split ',', $events while ( $type, $value, $events ) = split ' ', <main::AE>; #print Data::Dumper::Dumper \%AttrEvents; sub new { my( $class, $type, $value ) = @_; return bless { type => $type, value=> $value, }, $class; } sub value{ $_[ 0 ]->{value}; } sub events{ my $self = shift; my $AERef = $AttrEvents{ $self->{type} }{ $self->{ value } }; wantarray ? @$AERef : $AERef; } 1; package GenData; ## This package is ONLY used to generate test data. use List::Util qw[shuffle]; our @colors = qw[ red orange yellow green blue indigo violet ]; our @sizes = 10 .. 20; our @weights = map{ 250 * $_ } 1 .. 10; our @materials = qw[ plastic wood steel bronze ]; our %edata = ( email=>'@somewhere.com', phone=>'0800-CALL-', fax=>'0800-FAX-', ); our %attrs = ( color => \@colors, size => \@sizes, weight => \@weights, material => \@materials, ); our @events = qw[ email phone fax ]; our @types = map{ "type$_" } 'A' .. 'Z'; sub init{ my @lines; while( @colors or @sizes or @weights or @materials ) { for my $attr ( ( keys %attrs )[ rand keys %attrs ] ) { next unless @{ $attrs{ $attr } }; my $value = splice( @{ $attrs{ $attr } }, int( rand @{ $at +trs{ $attr } } ), 1 ); my @events = ( shuffle @events )[ 0 .. rand @events ]; push @lines, "$attr\t" . $value . "\t" . join( ',', map{ $_ eq 'email' ? "$_=${value}$edata{$_}" : "$_=$edata{$_}\U$value" } @events ); } } print main::AE "$_\n" for sort @lines; } 1; package main; # GenData::init; my $widget = Widget->new( color => $GenData::colors [ rand @GenData::colors ], size => $GenData::sizes [ rand @GenData::sizes ], weight => $GenData::weights [ rand @GenData::weights ], material => $GenData::materials[ rand @GenData::materials ], ); print Data::Dumper::Dumper $widget; $widget->do_events; __END__ __AE__ color blue fax=0800-FAX-BLUE color green email=green@somewhere.com color indigo phone=0800-CALL-INDIGO color orange email=orange@somewhere.com,phone=0800-CALL-ORAN +GE color red email=red@somewhere.com,phone=0800-CALL-RED,fa +x=0800-FAX-RED color violet email=violet@somewhere.com,fax=0800-FAX-VIOLET color yellow phone=0800-CALL-YELLOW,fax=0800-FAX-YELLOW,emai +l=yellow@somewhere.com material bronze phone=0800-CALL-BRONZE material plastic email=plastic@somewhere.com material steel phone=0800-CALL-STEEL,fax=0800-FAX-STEEL,email=st +eel@somewhere.com material wood fax=0800-FAX-WOOD size 10 fax=0800-FAX-10,email=10@somewhere.com,phone=080 +0-CALL-10 size 11 phone=0800-CALL-11 size 12 fax=0800-FAX-12,email=12@somewhere.com,phone=080 +0-CALL-12 size 13 fax=0800-FAX-13,email=13@somewhere.com size 14 email=14@somewhere.com size 15 email=15@somewhere.com,fax=0800-FAX-15 size 16 fax=0800-FAX-16,phone=0800-CALL-16,email=16@some +where.com size 17 phone=0800-CALL-17 size 18 email=18@somewhere.com size 19 email=19@somewhere.com,phone=0800-CALL-19,fax=08 +00-FAX-19 size 20 fax=0800-FAX-20,phone=0800-CALL-20,email=20@some +where.com weight 1000 fax=0800-FAX-1000 weight 1250 phone=0800-CALL-1250,email=1250@somewhere.com weight 1500 email=1500@somewhere.com,fax=0800-FAX-1500,phone +=0800-CALL-1500 weight 1750 phone=0800-CALL-1750,fax=0800-FAX-1750 weight 2000 email=2000@somewhere.com,phone=0800-CALL-2000 weight 2250 fax=0800-FAX-2250 weight 250 fax=0800-FAX-250,email=250@somewhere.com weight 2500 fax=0800-FAX-2500 weight 500 fax=0800-FAX-500,email=500@somewhere.com weight 750 email=750@somewhere.com,phone=0800-CALL-750

Ouputs:

P:\test>395427 $VAR1 = bless( { 'color' => bless( { 'value' => 'green', 'type' => 'color' }, 'Attribute' ), 'weight' => bless( { 'value' => 1000, 'type' => 'weight' }, 'Attribute' ), 'size' => bless( { 'value' => 13, 'type' => 'size' }, 'Attribute' ), 'material' => bless( { 'value' => 'steel', 'type' => 'material' }, 'Attribute' ) }, 'Widget' ); Sending email to green@somewhere.com Faxing 0800-FAX-1000 Faxing 0800-FAX-13 Sending email to 13@somewhere.com Phoning 0800-CALL-STEEL Faxing 0800-FAX-STEEL Sending email to steel@somewhere.com

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

In reply to Re: OT: Design question by BrowserUk
in thread OT: Design question by dragonchild

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.