Open p5pRT opened 20 years ago
I've run into many bugs with references to tied hash keys. Some of them are documented in bug # 27555. In addition to what's there\, I've had core dumps that I haven't reported because I couldn't find a self-contained test case. Basically I've concluded that refereces to tied hash keys are too broken to use.
Even if all of the bugs in 27555 were fixed (and the core dumps too)\, there would still be a problem: tied hash code sometimes needs to know that a reference has been made. My soon-to-be-released persistent object store module uses tied hashes that very much need to know about references.
I propose that an additional tie method: GETREF.
GETREF would be invoked whenver someone did:
$x = \%tiedhash{key}
It would return the reference.
If a GETREF method isn't provided\, perl can fall back to the current broken behavior.
An example from my module... Values in $hash1 and $hash2 are only loaded into memory as they are accessed.
$hash1->{x} = \$hash2->{y};
... time passes and $hash1 is saved persistently and is no longer in memory...
$hash1->{z} = \$hash2->{y}; # a ref is made
delete $hash2->{y};
${$hash1->{z}} = 'a'; # change the value
$hash1->{b} = ${$hash1->{x}}; # $hash1->{x} is loaded into memory
in my module $hash1->{b} is 'a' but that's only possible because I fake up a call to GETREF. Just fixing the bug # 27555 would not allow this to work.
Here's how I'm working around the lack of GETREF:
use B qw(svref_2object);
sub workaround27555 { my $self = shift; my ($tiedaddr\, $key) = tied_hash_reference($_[0]); print "workaround27555($qaddr{\$_[0]}) no tied addr\n" if $debug_27555 && ! $tiedaddr; return $_[0] unless $tiedaddr;
... application specific code to translate from $tiedaddr to $tied ...
$_[0] = $tied->GETREF($key); print "workaround27555($qaddr{\$_[0]}) references %*$id/'$key - replaced with GETREF\n" if $debug_27555; return $_[0]; }
sub tied_hash_reference { my ($ref) = @_; local($@); return eval { my $magic = svref_2object($ref)->MAGIC; $magic = $magic->MOREMAGIC while lc($magic->TYPE) ne 'p'; return (${$magic->OBJ->RV}\, $magic->PTR->as_string); }; }
It's used like:
$x = \%tiedhash{key}
$myobj->workaround27555($x);
I also have an explicit getref function alternative:
use UNIVERSAL qw(can);
sub getref(\%$) { my $hash = shift; my $key = shift; my $tied = tied %$hash; die unless reftype($hash) eq 'HASH'; return \$hash->{$key} unless $tied && $tied->can('GETREF'); print "getref getting references for '$key'\n" if $debug_27555; return $tied->GETREF($key); }
It's used as:
$x = getref(%tiedhash\, 'key');
On Wed Apr 28 00:57:52 2004\, muir@idiom.com wrote:
This is a bug report for perl from muir@idiom.com\, generated with the help of perlbug 1.34 running under perl v5.8.3.
----------------------------------------------------------------- [Please enter your report here]
I've run into many bugs with references to tied hash keys. Some of them are documented in bug # 27555. In addition to what's there\, I've had core dumps that I haven't reported because I couldn't find a self-contained test case. Basically I've concluded that refereces to tied hash keys are too broken to use.
Even if all of the bugs in 27555 were fixed (and the core dumps too)\, there would still be a problem: tied hash code sometimes needs to know that a reference has been made. My soon-to-be-released persistent object store module uses tied hashes that very much need to know about references.
Was that module ever released to CPAN? (Nothing at http://search.cpan.org/~muir/ leaps out to me.)
I propose that an additional tie method: GETREF.
GETREF would be invoked whenver someone did:
$x = \\%tiedhash\{key\}
It would return the reference.
If a GETREF method isn't provided\, perl can fall back to the current broken behavior.
An example from my module... Values in $hash1 and $hash2 are only loaded into memory as they are accessed.
$hash1\->\{x\} = \\$hash2\->\{y\}; \.\.\. time passes and $hash1 is saved persistently and is no longer in memory\.\.\. $hash1\->\{z\} = \\$hash2\->\{y\}; \# a ref is made delete $hash2\->\{y\}; $\{$hash1\->\{z\}\} = 'a'; \# change the value $hash1\->\{b\} = $\{$hash1\->\{x\}\}; \# $hash1\->\{x\} is loaded into memory
in my module $hash1->{b} is 'a' but that's only possible because I fake up a call to GETREF. Just fixing the bug # 27555 would not allow this to work.
Here's how I'm working around the lack of GETREF:
use B qw\(svref\_2object\); sub workaround27555 \{ my $self = shift; my \($tiedaddr\, $key\) = tied\_hash\_reference\($\_\[0\]\); print "workaround27555\($qaddr\{\\$\_\[0\]\}\) no tied addr\\n" if
$debug_27555 && ! $tiedaddr; return $_[0] unless $tiedaddr;
\.\.\. application specific code to translate from $tiedaddr to $tied
...
$\_\[0\] = $tied\->GETREF\($key\); print "workaround27555\($qaddr\{\\$\_\[0\]\}\) references %\*$id/'$key \-
replaced with GETREF\n" if $debug_27555; return $_[0]; }
sub tied\_hash\_reference \{ my \($ref\) = @​\_; local\($@​\); return eval \{ my $magic = svref\_2object\($ref\)\->MAGIC; $magic = $magic\->MOREMAGIC while lc\($magic\->TYPE\) ne 'p'; return \($\{$magic\->OBJ\->RV\}\, $magic\->PTR\->as\_string\); \}; \}
It's used like:
$x = \\%tiedhash\{key\} $myobj\->workaround27555\($x\);
I also have an explicit getref function alternative:
use UNIVERSAL qw\(can\); sub getref\(\\%$\) \{ my $hash = shift; my $key = shift; my $tied = tied %$hash; die unless reftype\($hash\) eq 'HASH'; return \\$hash\->\{$key\} unless $tied && $tied\->can\('GETREF'\); print "getref getting references for '$key'\\n" if $debug\_27555; return $tied\->GETREF\($key\); \}
It's used as:
$x = getref\(%tiedhash\, 'key'\);
Thank you very much. Jim Keenan
The RT System itself - Status changed from 'new' to 'open'
Yes. It is OOPS (http://search.cpan.org/~muir/OOPS/).
I developed a workaround for the issue that complicates use of my module (as a user of the module\, you have to do something special with your tied hash key references so that OOPS can handle them). My workaround uses B::svref_2object.
I would still like the GETREF tie method.
Thanks\, -Dave
On Thu\, Oct 11\, 2012 at 5:21 PM\, James E Keenan via RT \< perlbug-followup@perl.org> wrote:
On Wed Apr 28 00:57:52 2004\, muir@idiom.com wrote:
This is a bug report for perl from muir@idiom.com\, generated with the help of perlbug 1.34 running under perl v5.8.3.
----------------------------------------------------------------- [Please enter your report here]
I've run into many bugs with references to tied hash keys. Some of them are documented in bug # 27555. In addition to what's there\, I've had core dumps that I haven't reported because I couldn't find a self-contained test case. Basically I've concluded that refereces to tied hash keys are too broken to use.
Even if all of the bugs in 27555 were fixed (and the core dumps too)\, there would still be a problem: tied hash code sometimes needs to know that a reference has been made. My soon-to-be-released persistent object store module uses tied hashes that very much need to know about references.
Was that module ever released to CPAN? (Nothing at http://search.cpan.org/~muir/ leaps out to me.)
I propose that an additional tie method: GETREF.
GETREF would be invoked whenver someone did:
$x = \\%tiedhash\{key\}
It would return the reference.
If a GETREF method isn't provided\, perl can fall back to the current broken behavior.
An example from my module... Values in $hash1 and $hash2 are only loaded into memory as they are accessed.
$hash1\->\{x\} = \\$hash2\->\{y\}; \.\.\. time passes and $hash1 is saved persistently and is no longer in memory\.\.\. $hash1\->\{z\} = \\$hash2\->\{y\}; \# a ref is made delete $hash2\->\{y\}; $\{$hash1\->\{z\}\} = 'a'; \# change the value $hash1\->\{b\} = $\{$hash1\->\{x\}\}; \# $hash1\->\{x\} is loaded
into memory
in my module $hash1->{b} is 'a' but that's only possible because I fake up a call to GETREF. Just fixing the bug # 27555 would not allow this to work.
Here's how I'm working around the lack of GETREF:
use B qw\(svref\_2object\); sub workaround27555 \{ my $self = shift; my \($tiedaddr\, $key\) = tied\_hash\_reference\($\_\[0\]\); print "workaround27555\($qaddr\{\\$\_\[0\]\}\) no tied addr\\n" if
$debug_27555 && ! $tiedaddr; return $_[0] unless $tiedaddr;
\.\.\. application specific code to translate from $tiedaddr
to $tied ...
$\_\[0\] = $tied\->GETREF\($key\); print "workaround27555\($qaddr\{\\$\_\[0\]\}\) references
%*$id/'$key - replaced with GETREF\n" if $debug_27555; return $_[0]; }
sub tied\_hash\_reference \{ my \($ref\) = @​\_; local\($@​\); return eval \{ my $magic = svref\_2object\($ref\)\->MAGIC; $magic = $magic\->MOREMAGIC while lc\($magic\->TYPE\) ne 'p'; return \($\{$magic\->OBJ\->RV\}\,
$magic->PTR->as_string); }; }
It's used like:
$x = \\%tiedhash\{key\} $myobj\->workaround27555\($x\);
I also have an explicit getref function alternative:
use UNIVERSAL qw\(can\); sub getref\(\\%$\) \{ my $hash = shift; my $key = shift; my $tied = tied %$hash; die unless reftype\($hash\) eq 'HASH'; return \\$hash\->\{$key\} unless $tied && $tied\->can\('GETREF'\); print "getref getting references for '$key'\\n" if
$debug_27555; return $tied->GETREF($key); }
It's used as:
$x = getref\(%tiedhash\, 'key'\);
Thank you very much. Jim Keenan
--- via perlbug: queue: perl5 status: new https://rt-archive.perl.org/perl5/Ticket/Display.html?id=29224
Is there anything blocking this request to add the GETREF tie method?
On Wed Jul 06 13:17:48 2016\, dcollinsn@gmail.com wrote:
Is there anything blocking this request to add the GETREF tie method?
Not that I know of.
On Wed Jul 06 13:17:48 2016\, dcollinsn@gmail.com wrote:
Is there anything blocking this request to add the GETREF tie method?
Not that I know of.
Migrated from rt.perl.org#29224 (status was 'open')
Searchable as RT29224$