Hi All,
Like many people, I think, I have been frustrated by perl's oo system. I have always liked in C++ and java you could declare your object's instance variables and then inside your methods you could just refer to those variables without having to use $self->variable or this->variable. So I figured out a way to use 'tie' to be able to do this in perl, so you can right code like this:
use strict;
package person;
use Class::InstanceVariables qw(
$first
$last
$middle
);
sub new{
my $class = shift;
local $self = instance();
$first = shift;
$middle = shift;
$last = shift;
return $self;
}
sub full_name{
local $self = shift;
return "$last, $first $middle";
}
sub marry{
local $self = shift;
my $spouse = shift;
return "$first married ".$spouse->first();
}
package main;
my $john = new person(qw(John F Jones));
my $sue = new person(qw(Suzy P Edwards));
print $john->full_name()."\n";
print $sue->full_name()."\n";
print $john->marry($sue)."\n";
How this works is for each instance variable desired in the parameters passed to the "InstanceVariables" module, a tied variable with the appropriate name is created for the package. These variables are tied to sub routines that access the package variable "$self". So for each method the first argument is shifted in a 'local $self'. Then when the tied variables are accessed the appropriate object is altered or accessed.
I know that having tied variables creates a certain amount of overhead and that using 'local' is generally frowned upon. But what I was wondering is it so bad to use these, if for me it makes it some much easier to use OOP? Right now I only use this module for personal stuff, but after I have refined it some more, I plan on using for work purposes, but before I did I would like to hear your comments about whether you would like to able to access your instance variables like this and what the plusses and minuses of this approach would be.
Here is the current source code for the module:
use strict;
package Class::InstanceVariables;
sub import{
my $class = shift;
my $caller = caller();
my $ties =
"package $caller;\n".'no strict;
$self="";
sub TIESCALAR{
my $class = shift;
my $var = shift;
bless \$var,$class;
}
sub FETCH{
my $thing = shift;
$self->{$$thing};
}
sub STORE{
my $thing = shift;
$self->{$$thing} = shift;
}
';
no strict 'refs';
*{$caller."::self"} = \${$caller."::self"};
foreach my $ivar (@_) {
if($ivar!~/^\$([A-Za-z_]\w*)$/) {
die "$ivar is not a valid variable name!\n";
}
my $varname = $1;
*{$caller."\:\:$varname"} = \${$caller."\:\:$varname"};
$ties .= "sub $varname : lvalue { \$_[0]->{$varname} }\n";
$ties .= "tie \${$varname},'$caller','$varname';\n";
}
*{$caller."::instance"}=sub{
bless {},$caller;
};
eval $ties;
if ($@) {
die $@;
}
}
1;
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.