Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
I'm afraid this is a very long and complex question, or at least it appears to be one.


Contents of GMS/MemberFile.pm
package GMS::MemberFile; require 5.6.0; use strict; require GMS; require Tie::Hash; use Carp; our $VERSION = "0.75"; our @ISA = ("GMS","Exporter","Tie::StdHash"); our @EXPORT = qw(); our @EXPORT_OK = qw(); our $GMS = new GMS(settings => 1); #USE: tie(%HASH,"GMS::MemberFile",{UID=>123,NAME=>'John'}); #Accepted Arguments #UID=>UID #NAME=>NAME #GENFILE=>1/0 #READONLY => 1/0 #Under normal circumstances, the only required field is UID... when ge +nerating #a file, however, NAME and GENFILE are required, and if UID is specifi +ed #the tie will fail. #Using READONLY on, you cannot change values, readonly is ignored if g +enfile is active sub TIEHASH { my ($self,%DETAIL) = @_; my ($this,$filedata,$ini,$uid,$tohash, $name); unless(exists $DETAIL{UID} xor $DETAIL{GENFILE}){ croak "Missing UID in TIE attempt or UID provided while construc +ting new file, UID = $DETAIL{UID}, GENFILE = $DETAIL{GENFILE}"; } #my $MEMBERDIRL = $GMS->getsetting("FILE","MEMBERDIRL"); my $MEMBERDIRL = 'TestMember\\'; if($DETAIL{GENFILE}){ $DETAIL{READONLY} = 0; croak "Missing MemberName in memberfile generation attempt" unle +ss($DETAIL{'MEMBER'}); #$uid = $GMS->getsetting("OTHER","UIDCOUNT") + 1; $uid = 1; $ini = new IniFile("$MEMBERDIRL$DETAIL{'MEMBER'}.gmf"); croak "Error, UID retrieved from settings already exists" if($in +i->exists([$uid])); $ini->put([$uid,"UID",$uid], -add => 1); $ini->put([$uid,"DATEJOIN", time], -add => 1); $ini->save(); #$GMS->changesetting("OTHER","UIDCOUNT",$uid); #print "Saved GenFile as $MEMBERDIRL$DETAIL{'MEMBER'}.gmf"; }else{ $uid = $DETAIL{'UID'}; if(exists $DETAIL{MEMBER} && defined $DETAIL{MEMBER} && -e "$MEM +BERDIRL$DETAIL{MEMBER}.gmf"){ $ini = new IniFile("$MEMBERDIRL$DETAIL{MEMBER}.gmf"); croak "Unable to locate UID '$uid' in $MEMBERDIRL$DETAIL{'MEM +BER'}.gmf" unless($ini->exists([$uid])); }else{ my $mlist = new IniFile($MEMBERDIRL."memberlist.gms"); croak "Unable to locate UID '$uid' in $MEMBERDIRL"."memberlis +t.gms" unless($name = $ini->get(['UID',$uid], -mapping => 'single')); $ini = new IniFile("$MEMBERDIRL$name.gmf"); croak "Unable to locate UID '$uid' in $MEMBERDIRL$DETAIL{'MEM +BER'}.gmf" unless($ini->exists([$uid])); } } $tohash = $ini->get([$uid]); #print "$tohash"; croak "Unknown Error retrieving file data: $!" unless(ref($tohash)) +; $filedata = {_ini => $ini, _uid => $uid, _read => $DETAIL{'READONLY'}, _keylist => {} }; #print " Generated filedata hash\n"; my %temparray = getdatakey($ini,$uid); $filedata->{_keylist} = \%temparray; #print "\n"."returning"; return bless $filedata, $self; } sub FETCH { my($self,$key) = @_; my $ini = $self->{_ini}; my $uid = $self->{_uid}; croak "Unable to locate $key" unless($ini->exists([$uid,$key])); return $ini->get([$uid,$key], -mapping => 'single'); } sub STORE { my($self,$key,$change) = @_; if(!$self->{_read}){ my $ini = $self->{_ini}; croak "INI Missing" unless(ref $ini); my $uid = $self->{_uid}; $ini->delete([$uid,$key]); $ini->put([$uid,$key,$change], -add => 1); my %temp = getdatakey($ini,$uid); $self->{_keylist} = \%temp; } print "Store $key, $change"; } sub DELETE { my($self,$key) = @_; if(!$self->{_read}){ my $ini = $self->{_ini}; my $uid = $self->{_uid}; $ini->delete([$uid,$key]); my %temp = getdatakey($ini,$uid); $self->{_keylist} = \%temp; } } sub FIRSTKEY { my($self,$key) = @_; my $temp = keys(%{ $self->{_keylist} }); return scalar each %{ $self->{_keylist} }; } sub NEXTKEY { my $self = shift; return scalar each %{ $self->{_keylist} }; } sub DESTROY { print "Attempting Save"; my $self = shift; my $ini = $self->{_ini}; print "Ini Is: ".ref $ini; if(!$self->{_read}){ print "Stage 2\n"; #Fails here my $ini = $self->{_ini}; print "Stage 3: ini = $ini !!!\n"; print ref $ini; croak "\n\nError retrieving INI interface" unless(ref $ini); print "Stage 4\n"; $ini->save() || croak "Failed Save! $!"; print "Saved!\n"; }else{ print "Skiping due to read only"; } } #Send it the INI and the UID, it should be able to determine the curre +nt list of keys sub getdatakey { return; my($ini,$uid) = @_; my (%temp,$key); my %testhash = %{ $ini->get([$uid]) }; foreach $key (keys %testhash){ $temp{$key} = 1; #print "Processing '$key'"; } #print "Finished Getdatakey\n"; return %temp; } 1;


The test program, testtie.cgi:
#!/usr/bin/perl use GMS::MemberFile; %member; tie(%member,"GMS::MemberFile", MEMBER=>'Iron', GENFILE => 0, UID=> 1); print "The UID for the new member is $member{UID}\n"; print "Did Ini Exit already?";


Explanation: The goal of the GMS::MemberFile package, was to provide a tied hash-link to the IniFile commands, which would also command IniFile to save after the last use of the current file using DESTROY

The problem is, the INI object, which is stored in the MemberFile object, is being destroied before MemberFile for some reason I don't understand... and it is destroying twice, although it only created one object (The output from executing testtie is pasted below)

Is there some reason that INI is vanishing before the object that holds it?

Note: I have added a small destroy sub to the IniFile package, it simply prints a warning that IniFile is gone... which is how I know it is destroying twice.


Execution Result:
-------------
E:\GMS>perl -w testtie.cgi
Odd number of elements in hash assignment at GMS.pm line 40.
Useless use of a variable in void context at testtie.cgi line 11.
The UID for the new member is 1
Did Ini Exit already?

IniFile is exiting!



IniFile is exiting!

Attempting SaveIni Is: Stage 2
Use of uninitialized value in concatenation (.) at GMS/MemberFile.pm line 148 during global destruction.
Stage 3: ini = !!!
(in cleanup)

Error retrieving INI interface at testtie.cgi line 0

-----------
End of result

So, if anyone can help me, I would appreciate it, I'm sorry this question is so long, but I'm not yet experienced enough at Perl OOP to single out what could be causing the problem.

Please ask me to clarify anything that doesn't make sense.

The code was executed with -w


Flame ~ Lead Programmer: GMS
http://gms.uoe.org
"Wierd things happen, get used to it"

In reply to Tie & Destroy, OOP by Flame

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-04-24 07:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found