Michael C. Toren on Fri, 18 Apr 2003 05:07:37 -0400


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: tying stashes


> i definitely found this interesting. unfortunately, when you tie a hash, it
> clears the hash before it's blessed as a new object. everything i try (based
> on your example) causes all available memory to be consumed, resulting in a
> segfault.

All of the examples given in my previous post were generated on a sparc
platform running perl 5.6.1.  I just spent some time tonight running another
set of tests on an x86 machine with perl 5.8.0, and was surprised to see
different results.  Using 5.8.0, if %main:: is tied the program initially
behaves the same as with 5.6.1, however once the program finishes and perl
runs garbage collection, MCT::TieHash::DESTROY is never called, and the perl
process appears to allocate more and more memory until the system resources
are entirely consumed and it's killed.  Very bizarre:

	The program:

		package MCT::TieHash;
		require Tie::Hash;
		@ISA = (Tie::StdHash);
		sub DESTROY { print "> DESTROY\n" }

		package main;
		print "v$]\n";
		tie %main:: => 'MCT::TieHash' or die;
		print "tied ", tied %main::, "\n";
		END { print "Bye\n" }

	Run through perl 5.6.1:

		[mct@quint ~/perl]$ perl stashtie2.pl
		v5.006001
		tied MCT::TieHash=HASH(0x2da50)
		Bye
		> DESTROY

	Run through perl 5.8.0:

		[mct@antarctica ~/perl]$ perl stashtie2.pl
		v5.008
		tied MCT::TieHash=HASH(0x8152ad8)
		Bye
		Killed

I also tried tying a stash other than %main::, which worked better in the
sense that it didn't cause perl 5.8.0's garbage collection to go berserk,
but it still didn't call my MCT::TieHash::STORE and FETCH methods when
variables in the package were accessed.

> i tried putting all this in a BEGIN block, but no luck.

Both you and Kyle Burton suggested placing the tie in the BEGIN block,
which led to some very interesting results.  My STORE and FETCH functions
still aren't being called, however all variables appear to contain undef
when queried, even when they have been previously assigned true values.
This is true for both perl 5.6.1 and 5.8.0.  The sample code (minus the
MCT::TieHash package which in this case contains only debug information
for each method in Tie::StdHash):

	package main;
	BEGIN { tie %main::, 'MCT::TieHash' or die; }
	$foo = "foo";
	print "\$foo contains ``$foo''\n";

When run:

	[mct@quint ~/perl]$ perl stashtie3.pl
	> TIEHASH main
	$foo contains ``''
	> DESTROY

Here's a (useless) application of that side effect, Undef.pm, which
causes variables in the callers package to always return undef (with
the exception of variables lexically scoped with "my"):

	# Michael C. Toren <mct@toren.net>
	# mct, Fri Apr 18 04:48:25 EDT 2003

	package Undef;

	use Carp;
	require Tie::Hash;
	@ISA = qw(Tie::StdHash);

	sub import
	{
		my $class = shift;
		my $caller = caller;

		croak "Don't use Undef.pm in package 'main'"
			if ($caller eq "main" && $] > 5.006001);

		tie %{"$caller\::"}, $class
			or croak "tie failed";
	}

Sample code:

	package notmain;
	use Undef;
	$foo = 1;
	print "\$foo is", (defined $foo ? " " : "NOT "), "defined\n";

when run:

	[mct@antarctica ~/perl]$ perl foo.pl
	$foo is NOT defined

Too bad I missed April Fool's by 18 days :)

I still can't think of any useful applications of all of this.

-mct
-
**Majordomo list services provided by PANIX <URL:http://www.panix.com>**
**To Unsubscribe, send "unsubscribe phl" to majordomo@lists.pm.org**