blessed hash
sub new {
my $classname = shift;
my $rh = {}; # Reference to Hash, rh :)
bless $rh, $classname;
return $rh;
}
All variables can be created just by assigning something to blessed hash:
my $foo = my_class->new();
$foo->{bar} = 42;
print $foo->{bar};
Unfortunatelly there is lack of encapsulation - you have access to all methods and properties.
Get control of object properties - use fields
package my_class;
use fields qw(bar); # declare used object vars
sub new {
my $classname = shift;
return fields::new $classname;
}
# usage:
my my_class $foo = my_class->new();
$foo->{baz} = 42; # trying to use not declared field - error!
print $foo->{bar}; # works
We have control on object properties. Anyway, we still do not have private variables.
Private variables (scalar-bless)
package my_class;
{
my %bar; # All vars are declared as hashes
sub new {
my $classname = shift;
my $rs = \do{ my $scalar }; # reference to scalar
bless $rs, $classname;
return $rs;
}
sub set_bar {
my $this = shift;
$bar{$this} = shift;
}
sub get_bar {
my $this = shift;
return $bar{$this};
}
}
And now all variables are private!!!
Potential problem: it's not working with threads. To have a copy of such object instance in threads, you need to workaround this closure with get_all_data()/set_all_data() methods - and all object data need to be passed as additional parameters when creating new thread.
my $foo = my_class->new();
$foo->{bar} = 42; # sorry, no bonus! Use set/get method instead.
print $foo->{bar}; # This is private variable, not accessible outside class.
print $foo->get_bar(); # works!
Private, public, protected - objects like in perl6:
like in manual:
use Perl6::Classes;
class Composer {
submethod BUILD { print "Giving birth to a new composer\n" }
method compose { print "Writing some music...\n" }
}
class ClassicalComposer is Composer {
method compose {
print "Writing some muzak...\n";
$_->do_private;
}
method do_private is private { print "really private thing\n" }
}
class ModernComposer is Composer {
submethod BUILD($) { $.length = shift }
method compose() { print((map { int rand 10 } 1..$.length), "\n") }
has $.length;
}
my $beethoven = new ClassicalComposer;
my $barber = new ModernComposer 4;
my $mahler = ModernComposer->new(400);
$beethoven->compose; # Writing some muzak...
$barber->compose; # 7214
#$beethoven->do_private;
compose $mahler; # 8927586934796837469875
Pretty well, uhh? For me it was like "look, this is almost like in Java!" Just change is to extends.
Perl6::Classes works as a filter for code and do all this translation job. Well, we pay for it - it is 20x slower than hash/scalar blessed objects. If this latency doesn't matter - use it.
No comments:
Post a Comment