Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^3: How to tie a hash to a class

by afoken (Chancellor)
on Sep 08, 2018 at 13:54 UTC ( [id://1221949]=note: print w/replies, xml ) Need Help??


in reply to Re^2: How to tie a hash to a class
in thread How to tie a hash to a class

Please edit your posting to have a <code> block per file, and another <code> block for the result.


Did you read tie? You really should, because it specifies how to write a class usable for tie().

Tieing a hash (or array, scalar, handle, ...) to a class completely hides the original hash (array, ...) and replaces it with the tied one.

Now look at your example:

use tahash; my %hash = ( "Jan" => 1, "Feb" => 2, "Mar" => 3, ); my $val = tie(%hash,"tahash") or die "Can't tie : $!";
package tahash; sub TIEHASH { print "<@_ \n>"; my $class = shift; my %hash = @_; print "In TIEHASH .... \n"; return bless(\%hash); }

tie calls TIEHASH() for you, passing all of its arguments, except for the first one, to TIEHASH(). The first argument to TIEHASH() is the class name, that your code correctly assigns to $class. The remaining ones form the content of your new hash.

Now look at the debug output from your code:

<tahash >In TIEHASH .... The object is destroyed...

When TIEHASH() is called, there is only one argument: The class name. So your tied hash is empty.

If you use Data::Dumper, you can see that even better:

#!/usr/bin/perl use strict; use warnings; use tahash; use Data::Dumper (); # just for debugging, remove from production code my %hash = ( "Jan" => 1, "Feb" => 2, "Mar" => 3, ); my $val = tie(%hash,"tahash") or die "Can't tie : $!"; print Data::Dumper->new([$val],['val'])->Dump(),"\n"; print Data::Dumper->new([\%hash],['*hash'])->Dump(),"\n";
package tahash; use strict; use warnings; use Data::Dumper (); # just for debugging, remove from production code sub TIEHASH { print Data::Dumper->new([\@_],['*_'])->Dump(),"\n"; my $class = shift; my %hash = @_; print "In TIEHASH .... \n"; return bless(\%hash); } sub DESTROY { print "The object is destroyed...\n"; } 1;
X:\>perl 1221948.pl @_ = ( 'tahash' ); In TIEHASH .... $val = bless( {}, 'tahash' ); Can't locate object method "FIRSTKEY" via package "tahash" at C:/straw +berry/perl /lib/Data/Dumper.pm line 190. The object is destroyed... X:\>

Ignore the "Can't locate object method" error for a while, your first problem is in the tie call. I've already explained what goes wrong, and fixing it is easy. (RTFM!)

The "Can't locate object method" error tells you that your tahash class needs a few more methods. Again, RTFM.


Update:

If you are lazy (and that's one of the virtues of any programmer), you can use existing code to implement the missing methods. See Tie::Hash:

package tahash; use strict; use warnings; use Data::Dumper (); # just for debugging, remove from production code # For historic reasons, the Tie::StdHash class is hidden in Tie::Hash. # So you have to load Tie::Hash instead of Tie::StdHash and set @INC m +anually. # Otherwise, you could simply do this: #use parent 'Tie::StdHash'; use Tie::Hash (); our @ISA=qw(Tie::StdHash); sub FIRSTKEY { my $self=shift; print "Hey, someone scans my keys!\n"; return $self->SUPER::FIRSTKEY(@_); } sub DESTROY { my $self=shift; print "The object is destroyed...\n"; $self->SUPER::DESTROY(); } 1;

Output:

X:\>perl 1221949.pl $val = bless( {}, 'tahash' ); Hey, someone scans my keys! %hash = (); The object is destroyed... X:\>

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1221949]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-04-26 05:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found