{ package Spellaid; # nothing significant about this name use warnings; use strict; use Scalar::Util qw(refaddr); use Data::Dumper; our $VERSION = '0.1.0'; my %stuff_of; # single hash per object my @vars = qw(name task); { no strict qw(refs); # all the attributes foreach my $var ( @vars ) { =for old_1 *{$var} = sub { return $var; }; # the spell-checker! =cut *{'set_'.$var} = sub { ${$stuff_of{refaddr $_[0]}}{$var} = $_[1];}; *{'get_'.$var} = sub { return ${$stuff_of{refaddr $_[0]}}{$var};} } } sub new { my($class, @args) = @_; my $obj = bless \do{my $anon_scalar}, $class; my $c; ${$c}{name} = 'the name'; ${$c}{task} = 'the task'; # begin added after commenting out "for old_1" { no strict qw(refs); foreach my $var ( @vars ) { ${$c}{'_'.$var} = sub { return $var; }; } } # end added $stuff_of{refaddr $obj} = $c; return $obj; } =for old_1 sub a_complex_sub { my ($self, $new_name) = @_; # deep inside this complex sub, we need the name ... # issue is to catch mis-spelling of the hash key "name" # print "nom: [", ${$stuff_of{refaddr $self}}{name()}, "]\n"; # next line will fail during run time (_not_ compile time) # but does fail with a Kaboom! # Undefined subroutine &Spellaid::nmae called at # So a good/explicit Kaboom!, albeit a late one. print "nom: [", ${$stuff_of{refaddr $self}}{nmae()}, "]\n"; } =cut # begin added after commenting out "for old_1" sub a_complex_sub { my ($self, $new_name) = @_; # deep inside this complex sub, we need the name ... # the correct way would be to extract the name via: # # my $whatever_for_name = ${$stuff_of{refaddr $self}}{_name}(); # # Typo of whatever_for_name will be caught at compile time, # but we are interested in typos of the attribute "name" # So suppose we make a typo "nmae": my $whatever_for_name = ${$stuff_of{refaddr $self}}{_nmae}(); # the preceding line fail during run time (_not_ compile time) # but failure message will show precisely what went wrong # and where exactly. So we do have a good/explicit # Kaboom!, albeit a late one. # how a_complex_sub() would use name: print "nom: [", ${$stuff_of{refaddr $self}}{$whatever_for_name}, "]\n"; } # end added sub dump_stuff { print Dumper($stuff_of{refaddr $_[0]}); } 1 } my $s_obj = Spellaid->new(); $s_obj->set_name('the new name'); # set print "task: [",$s_obj->get_task(), "]\n"; # get $s_obj->a_complex_sub(); # spell check $s_obj->dump_stuff(); # data dumper __END__ for old_1 output: # with misspelling task: [the task] Undefined subroutine &Spellaid::nmae called at # without misspellin task: [the task] nom: [the new name] $VAR1 = { 'name' => 'the new name', 'task' => 'the task' }; output after commenting out old_1: # with misspelling task: [the task] Use of uninitialized value in subroutine entry at Can't use string ("") as a subroutine ref while "strict refs" in use at # without misspellin task: [the task] nom: [the new name] $VAR1 = { '_name' => sub { "DUMMY" }, 'name' => 'the new name', '_task' => sub { "DUMMY" }, 'task' => 'the task' };