# Leacher.pm package Leacher; # author: bliako # for: https://perlmonks.org/?node_id=1229804 # 13/02/2019 # Makes get/set subs for each 'our' method of guest module # which matches build in regex, or all if none provided. # Usage: # use Leacher 'Person.pm'; # my $mp = Leacher->new('^address_'); # print "var[1] = ".$mp->get_var(1)."\n"; # $mp->set_var(1, 101010); # print "now is var[1] = ".$mp->get_var(1)."\n"; use strict; use warnings; use lib '.'; my $par = undef; sub import { die __PACKAGE__."::import() : you need to specify a class to leach like use Leacher 'XYZ.pm';".__PACKAGE__." 'class-to-leach-name'.\n" unless defined ($par=$_[1]); $par =~ s/\.pm$//i; print __PACKAGE__."::import() : leaching on ".$_[1]."\n"; require $_[1]; } # takes 1 param: a string-regex to match the variables you are looking for in # the other module. It uses the remaining match till the end of string as the key # for you to access these vars. # for example your regex is "^address_" # then it will match every "our" var starting with "address_" and use the # remaining var name (e.g. if "address_xyz", the remaining var name will be "xyz") # as the key to get/set that variable. # TODO: the case when we have just "our address_;" sub new { die __PACKAGE__."::new() : you need to specify a class to leach like use ".__PACKAGE__." 'class-to-leach-name'.\n" unless defined $par; my $class = $_[0]; # input param (optional, if empty matches all 'our' params): # e.g. "^address_". In this case the key will be anything following till the end my $regex_to_match_parent_vars = $_[1]; $regex_to_match_parent_vars = '' unless defined $regex_to_match_parent_vars; my $self = { 'vars' => {} }; bless($self, $class); print __PACKAGE__."::new() : looking for vars in '$par' using /$regex_to_match_parent_vars/ ...\n"; my @k = (); eval('@k = keys %'.${par}.'::'); foreach my $entry ( @k ){ if( $entry =~ /^${regex_to_match_parent_vars}/ ){ (my $index) = $entry =~ /^${regex_to_match_parent_vars}(.*?)$/; if( ! defined $index or $index eq "" ){ print STDERR __PACKAGE__."::new() : nothing left for key after subtracting regex '$regex_to_match_parent_vars' from varname ".$par."::$entry, skipping that...\n"; next } eval('$self->{"vars"}->{$index} = \$Person::'.$entry); print __PACKAGE__."::new() : found variable '$entry' and adding it with the key '$index'.\n"; } }; return $self } sub get_var { return ${$_[0]->{'vars'}->{$_[1]}} } sub set_var { return ${$_[0]->{'vars'}->{$_[1]}} = $_[2] } 1; #### # Person.pm package Person; use strict; use warnings; our $VERSION = 0; our $address_1 = 11; our $address_2 = 12; our $address_3 = 13; our $address_ = 14; 1; #### #!/usr/bin/env perl # harness.pl use strict; use warnings; use lib './'; use Leacher 'Person.pm'; my $mp = Leacher->new('^address_'); die unless defined $mp; print "vars[1]=".$mp->get_var(1)."\n"; $mp->set_var(1,1222); print "vars[1]=".$mp->get_var(1)."\n"; my $mp2 = Leacher->new(); die unless defined $mp2; print "vars[1]=".$mp2->get_var('address_1')."\n"; $mp2->set_var('address_1',666); print "vars[1]=".$mp2->get_var('address_1')."\n"; #### $ perl -I. harness.pl Leacher::import() : leaching on Person.pm Leacher::new() : looking for vars in 'Person' using /^address_/ ... Leacher::new() : nothing left for key after subtracting regex '^address_' from varname Person::address_, skipping that... Leacher::new() : found variable 'address_3' and adding it with the key '3'. Leacher::new() : found variable 'address_2' and adding it with the key '2'. Leacher::new() : found variable 'address_1' and adding it with the key '1'. vars[1]=11 vars[1]=1222 Leacher::new() : looking for vars in 'Person' using // ... Leacher::new() : found variable 'VERSION' and adding it with the key 'VERSION'. Leacher::new() : found variable 'BEGIN' and adding it with the key 'BEGIN'. Leacher::new() : found variable 'address_' and adding it with the key 'address_'. Leacher::new() : found variable 'address_3' and adding it with the key 'address_3'. Leacher::new() : found variable 'address_2' and adding it with the key 'address_2'. Leacher::new() : found variable 'address_1' and adding it with the key 'address_1'. vars[1]=1222 vars[1]=666