use strict; use warnings; {package Object::Tiny;} {package Foo; use parent -norequire ,"Object::Tiny"; Object::Tiny::->import( qw|bar baz headers myhash|); } my $f = Foo::->new(bar=>44, baz=>"Value of baz"); $f->headers_set(["This is H-1","This is H-2"]); # SETTER - sets arrayref print "Object f Scalar: $_=> ",$f->$_,";\n" for qw |baz bar |; # Get a callback for each member of array ref: $f->headers_forEach(sub{print "Object f :(Array component) header=$_[0];\n"}); $f->baz_forEach(sub{print "Object f : (Scalar accessed as array) baz value=$_[0];\n"}); $f->myhash_set({Uno=>"One", Dos=>"Two", Tres=>"Three"}); # Setter - sets hashref # Get a callback for each KEY. # Extra parameters (R/W) returned are the extra param passed to forEach() $f->myhash_forEach(sub{print "Object f (HashRef): myhash KEY:$_[0]; VALUE:$_[1]; Extra args($_[2],", ++$_[3],")\n"}, "Extra-arg1", 25); #### BEGIN{ package Object::Tiny; use strict 'vars', 'subs'; no strict 'refs'; our $VERSION = '1.10'; sub import { return unless shift eq __PACKAGE__; my $pkg = caller; my $child = !! @{"${pkg}::ISA"}; eval join "\n", "package $pkg;", ($child ? () : "\@${pkg}::ISA = __PACKAGE__;"), map { defined and ! ref and /^[^\W\d]\w*\z/s or die "Invalid accessor name '$_'"; "sub $_ { return \$_[0]->{$_} };" ."sub ${_}_set { return \$_[0]->{$_} = \$_[1] };" ."sub ${_}_forEach { my (\$item,\$subref,\@parm)=(\$_[0]->{$_}, \$_[1],\@_[2..\$#_]); my \$type=ref \$item; \$subref->(\$item), return unless \$type; if (\$type eq 'ARRAY') { \$subref->(\$_,\@parm) for \@\$item} elsif(\$type eq 'HASH') {\$subref->(\$_,\$item->{\$_},\@parm) for sort keys \%\$item}; };" } @_; die "Failed to generate $pkg:$@" if $@; return 1; } sub new { my $class = shift; bless { @_ }, $class; } 1; } #### $ perl test-obj-tiny.pl Object f Scalar: baz=> Value of baz; Object f Scalar: bar=> 44; Object f :(Array component) header=This is H-1; Object f :(Array component) header=This is H-2; Object f : (Scalar accessed as array) baz value=Value of baz; Object f (HashRef): myhash KEY:Dos; VALUE:Two; Extra args(Extra-arg1,26) Object f (HashRef): myhash KEY:Tres; VALUE:Three; Extra args(Extra-arg1,27) Object f (HashRef): myhash KEY:Uno; VALUE:One; Extra args(Extra-arg1,28)