Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[perl #24551] Scoping for Tied hashes

0 views
Skip to first unread message

Sreeji

unread,
Nov 25, 2003, 6:53:59 AM11/25/03
to bugs-bi...@netlabs.develooper.com
# New Ticket Created by Sreeji
# Please include the string: [perl #24551]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=24551 >


Hi
We are in the process of migrating to perl-5.8.1. We
have few programs which need to keep hashes ordered
for the regressions to pass (I know code should not be
dependant on hash-ordering - but changing this code
would be costly). So I decided to simply add a:
tie %hash, 'Tie::IxHash'. While this handled most of
the cases, I found a case failing.

Following is a test script that demonstrates the
problem.
% cat test.pl
use Tie::IxHash;

my %hash;
tie %hash, "Tie::IxHash";

%hash = (1 => 'ONE', 2 => 'TWO');
foreach my $line (get_values()) { $line = 100; }
foreach my $line (values(%hash)) { print "$line\n"; }

sub get_values { return values(%hash); }

% perl test.pl
100
100

Now comment the following line and re-run:
# tie %hash, "Tie::IxHash";

% perl test.pl
ONE
TWO

-----------
I would expect the behaviour to be the same
irrespective of whether the hash is tied or not.
Would that be considered a bug ?

I have tried the script on perl-5.6.1 and 5.8.1 and
the results were same.

This is my perl-5.8.1 configuration, if that matters:
Summary of my perl5 (revision 5.0 version 6 subversion
1) configuration:
Platform:
osname=linux, osvers=2.4.9-12custom,
archname=i686-linux
uname='linux test 2.4.9-12custom #1 smp wed feb 6
13:55:56 pst 2002 i686 unknown '
config_args='-de -Dprefix=/local
-Dmake=/usr/bin/make -Dbin=/local/bin/
-Uinstallusrbinperl -Dstartperl=#!/local/bin/perl
-Dscriptdir=/nfs/group/local/arch/share/bin
-Dsitebin=/local/bin'
hint=recommended, useposix=true,
d_sigaction=define
usethreads=undef use5005threads=undef
useithreads=undef usemultiplicity=undef
useperlio=undef d_sfio=undef uselargefiles=define
usesocks=undef
use64bitint=undef use64bitall=undef
uselongdouble=undef
Compiler:
cc='cc', ccflags ='-fno-strict-aliasing
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-fno-strict-aliasing'
ccversion='', gccversion='2.96 20000731 (Red Hat
Linux 7.1 2.96-85)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8,
byteorder=1234
d_longlong=define, longlongsize=8,
d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double',
nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, usemymalloc=n, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lndbm -lgdbm -ldl -lm -lc -lcrypt
-lutil
perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
libc=/lib/libc-2.2.2.so, so=so, useshrplib=false,
libperl=libperl.a
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef,
ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared
-L/usr/local/lib'


Characteristics of this binary (from libperl):
Compile-time options: USE_LARGE_FILES
Built under linux
Compiled at Sep 20 2002 15:20:12
%ENV:
PERL5LIB="/local/test/pm"
@INC:
/local/test/pm
/local/lib/perl5/5.6.1/i686-linux
/local/lib/perl5/5.6.1
/local/lib/perl5/site_perl/5.6.1/i686-linux
/local/lib/perl5/site_perl/5.6.1
/local/lib/perl5/site_perl
.
-------

thx
Sreeji

________________________________________________________________________
Want to chat instantly with your online friends? Get the FREE Yahoo!
Messenger http://mail.messenger.yahoo.co.uk

Rafael Garcia-Suarez

unread,
Nov 29, 2003, 5:40:05 AM11/29/03
to perl5-...@perl.org, perlbug-...@perl.org
Sreeji (via RT) wrote:
> We are in the process of migrating to perl-5.8.1. We
> have few programs which need to keep hashes ordered
> for the regressions to pass (I know code should not be
> dependant on hash-ordering - but changing this code
> would be costly). So I decided to simply add a:
> tie %hash, 'Tie::IxHash'.

(this is not directly related to your bug)

Don't.

Tied hashes are way slower than regular hashes. If you want
to disable hash randomization by default, compile perl
with -DUSE_HASH_SEED_EXPLICIT. (See the INSTALL file for
details.)

> While this handled most of
> the cases, I found a case failing.
>
> Following is a test script that demonstrates the
> problem.
> % cat test.pl
> use Tie::IxHash;
>
> my %hash;
> tie %hash, "Tie::IxHash";
>
> %hash = (1 => 'ONE', 2 => 'TWO');
> foreach my $line (get_values()) { $line = 100; }
> foreach my $line (values(%hash)) { print "$line\n"; }
>
> sub get_values { return values(%hash); }
>
> % perl test.pl
> 100
> 100
>
> Now comment the following line and re-run:
> # tie %hash, "Tie::IxHash";
>
> % perl test.pl
> ONE
> TWO
>
> -----------
> I would expect the behaviour to be the same
> irrespective of whether the hash is tied or not.
> Would that be considered a bug ?

Or in other words, does values() return a list of lvalues ?
It does only so if individual values have some sort of magic
attached to them, which is only the case with tied hashes.
If the hash is not tied values() only returns a list of aliases
to the hash values. Once you copy this list the magic is lost.
I don't consider this to be a bug.

Yitzchak Scott-Thoennes

unread,
Dec 14, 2003, 4:30:51 PM12/14/03
to Rafael Garcia-Suarez, perl5-...@perl.org, perlbug-...@perl.org

I have to disagree. A non-lvalue sub should not return lvalues.
Something has gone awry here:

#!/usr/bin/perl -w
use strict;
use warnings;
use Tie::Hash;

our %nottied = ('a'..'d');
tie our %tied, "Tie::StdHash";
%tied = ('a'..'d');

print "tied is: ", %tied, "\n";
print "nottied is: ", %nottied, "\n";

$_ = "x" for &{sub { values %tied }};
$_ = "x" for &{sub { values %nottied }};

print "tied is now: ", %tied, "\n";
print "nottied is now: ", %nottied, "\n";
__END__
output is:

tied is: cdab
nottied is: cdab
tied is now: cxax
nottied is now: cdab

0 new messages