relax99 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have just started learning OOPerl a couple months ago and I'm still a little bit confused as to how some stuff works. Let's say I set up a calendar class that is tied to a file on disk using MLDBM::Sync. I need to use MLDBM::Sync, because I need concurrent access to this file by multiple users (through a web interface). Below is how the beginning of my calendar class looks like including the constructor:

package Calendar; # class variables my $sync_dbm_obj; # constructor sub new { my $class = shift; my %args = @_; my $calendar = {}; $sync_dbm_obj = tie(%{$calendar}, 'MLDBM::Sync', "$args{DIR}\\$arg +s{year}.db", O_CREAT|O_RDWR, 0640) or die "can't open tie to $args{year}.db: $!"; # if just created, initialize hash with default values if( !$calendar->{months} ) { $sync_dbm_obj->Lock; $calendar->{year} = $args{year}; $calendar->{months} = {}; my $aref = $calendar->{months}; foreach my $month (1..12) { $aref->{$month} = _init_days($calendar->{year}, $month); } $calendar->{months} = $aref; $sync_dbm_obj->UnLock; } return bless $calendar, $class; }

Now, if I need to create two calendar objects I would do something like:

my $calendar1 = Calendar->new(year => "2002", DIR => "c:\a_dir"); my $calendar2 = Calendar->new(year => "2003", DIR => "c:\a_dir");

Once I create the second object, the $sync_dbm_obj class variable points to the second file (2003.db in this example), so if I call any methods for $calendar1 object, file 2002.db is not going to be locked. And if I were to destroy $calendar1 by either letting it go out of scope or calling undef $calendar1, then $sync_dbm_obj becomes undefined and methods for $calendar2 object stop functioning, because they're trying to lock 2003.db using $sync_dbm_obj, but it is now undefined.

Can you think of how to fix this or suggest a nice workaround? One workaround would, of course, be to use just one calendar object at a time, but there's a part in my program where I need to have two calendar objects active at the same time. And I do need fine-grained persistant and syncronized access to files offered by MLDBM and MLDBM::Sync to prevent concurrency issues. Any input is welcome!

Replies are listed 'Best First'.
Re: Need a workaround: Class variables with MLDBM::Sync
by perrin (Chancellor) on Oct 11, 2002 at 16:58 UTC
    Just store the tied hash inside your object: $calendar->{'data'}. That way you have a separate MLDBM::Sync instance for each calendar object.
      Thank you! I have no idea why I didn't think about it before... Now it does seem like an obvious solution. I still didn't get it to work though. I did exactly what you suggested, but now I get this error: (I'm using Storable for serializing data in MLDBM) Can't store CODE items at blib\lib\Storable.pm (autosplit into blib\lib\auto\Storable\_freeze.al) line 264, at C:/Perl/site/lib/MLDBM/Serializer/Storable.pm line 20

        Perhaps you're running into the same issue that was being addressed over here. (or related anyway). The jist is you should see about upgrading your Storable and maybe perl itself.

        __SIG__ printf "You are here %08x\n", unpack "L!", unpack "P4", pack "L!", B:: +svref_2object(sub{})->OUTSIDE
        I can't tell you what's going on without seeing your code. Make sure you are only tie-ing the data, not the whole calendar object.