1

I have a Perl class which is a based on a blessed hashref ( https://github.com/kylemhall/Koha/blob/master/Koha/Object.pm )

This is a community based project, with many developers of varying skill.

What I've seen is some developers accidentally using our objects as hashrefs. The actual data is not stored in the blessed hashref, but in a dbic object that is stored in the hashref ( in $self->{_result} ). When the dev tries something like $object->{id} perl doesn't complain, it just returns undef, as would be expected.

What I'd like to do is to either A) Make the script explode with an error when this happens B) Allow the use of the hashref syntax for setting / getting values in the dbic objects stored in $self->{_result}

I tried using:

use overload '%{}' => \&get_hashref;

but when I do this, get_hashref is called any time a regular method is called! This makes sense in a way, since the object itself is a hashref. I'm sure this has something to do with the Perl internals for blessed hashrefs as objects.

Is what I'm trying to accomplish even possible?

Kyle
  • 213
  • 1
  • 3
  • 13
  • Actually I think instead of trying to create errors for invalid usage, teach the "developers of varying skill." to write correct code. There is no reasonable mechanism that prevents misusing Perl objects. – U. Windl Aug 30 '21 at 07:11

2 Answers2

5

I suggest using a scalar-based or array-based object instead of a hash-based object. This is a cheap (efficient) solution since it simply causes the offender to run afoul of existing type checks.

For example, the object produced by the following is simply a reference to the actual object. Just use $$self instead of $self in the methods.

$ perl -e'
   sub new {
      my $class = shift;
      my $self = bless(\{}, $class);
      # $$self->{...} = ...;
      return $self;
   }
   my $o = __PACKAGE__->new();
   my $id = $o->{id};
'
Not a HASH reference at -e line 9.
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Thanks! With this idea, I was able to not only protect the objects from mis-use, but was able to accomplish the hashref emulation I awas looking to do! – Kyle Feb 08 '16 at 17:18
  • Link to the patch for those who are interested: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=15759 – Kyle Feb 08 '16 at 17:18
  • @ikegami - nice! When you suggested a "scalar-based or array-based object instead" I thought there'd be major rewriting required. – G. Cito Feb 08 '16 at 18:54
3

One way to do this, is by using "inside-out objects", where the object is just a blessed simple scalar, and the data is stored separately. See, for instance, Class::STD

mscha
  • 6,509
  • 3
  • 24
  • 40
  • :-D yay! Sort of OT but good point to raise. I predict Inside Out will be cool again one day. Have you tried [`Dios`](https://metacpan.org/pod/Class::Std)? – G. Cito Feb 08 '16 at 18:47