Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When building hash, hash keys that are function calls are not being called #4095

Closed
p5pRT opened this issue Jun 19, 2001 · 12 comments
Closed

Comments

@p5pRT
Copy link

p5pRT commented Jun 19, 2001

Migrated from rt.perl.org#7130 (status was 'resolved')

Searchable as RT7130$

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From hnine@netarx.com

This is to report a bug in perl 5.6.1.
The bug is as follows​:

When building a hash, key-values for the hash can be calls to functions.
The return value of
the function is then the actual key for the hash. In the current
version (5.6.1) of perl,
specifically in the Debian distribution of Linux, function calls that
are used as hash
key-values in the construction of a hash are not called, but are instead
converted directly to
strings.
This is demonstrated by the following script​:

-- start script --
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
  foo​::bar => 'foobar',
  'other' => 'whatever'
);

foreach my $key (keys %foo) {
  print "\$key = $key\n";
}
--- end script ---

The output of this script is as follows​:
-- start output of above script --
$key = other
$key = foo​::bar
--- end output of above script ---

The second key, i.e. foo​::bar, should actually be the output of the
'bar' function in
package 'foo', i.e. 'HASHKEY'.

HTH

-- Harmon S. Nine

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From [Unknown Contact. See original ticket]

I believe this is not a bug...

What's happening is that => implicitly single quotes its left argument, so
your

%foo = (
  foo​::bar => 'foobar',
  'other' => 'whatever'
);

becomes

%foo = (
  'foo​::bar' => 'foobar',
  'other' => 'whatever'
);

and the function call never happens...

This works​:

-- start script --
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
  foo​::bar, 'foobar',
  'other', 'whatever'
);

foreach my $key (keys %foo) {
  print "\$key = $key\n";
}
-- end script --

Hope this helps,
--
Mike Giroux
via, but not for, Bear-Stearns

***********************************************************************
Bear Stearns is not responsible for any recommendation, solicitation,
offer or agreement or any information about any transaction, customer
account or account activity contained in this communication.
***********************************************************************

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From [Unknown Contact. See original ticket]

-- start script --
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
foo​::bar => 'foobar',

Your mistake is using the => (fat comma) operator. This does its best to
ensure that the left-hand side is treated as a quoted string. If you used
a real comma, the function would be called.

'other' => 'whatever'
);

foreach my $key (keys %foo) {
print "\$key = $key\n";
}
--- end script ---

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From [Unknown Contact. See original ticket]

On Jun 19, Harmon S. Nine said​:

-- start script --
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
foo​::bar => 'foobar',

Your mistake is using the => (fat comma) operator. This does its best to
ensure that the left-hand side is treated as a quoted string. If you used
a real comma, the function would be called.

Upon further investigation, => did not behave like this in 5.6.0.

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From @tamias

Nor in perl5.005.

The docs are quite vague on what actually counts as a word for =>.

Anyway, this is definitely a change in behavior.

Ronald

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From [Unknown Contact. See original ticket]

Wierd... You're right, not in perl5.005_03 either.

Wasn't it SUPPOSED to do that all along, though?

Ooh, cute. Check this out... It looks like :​: on the left side of
=> was a special case.

~>cat hashKey.pl
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

sub foo__bar { return 'foo_bar_HASHKEY'; }

%foo = (
  foo​::bar,'foobar',
  foo__bar,'foobar',
  'other', 'whatever'
);
%foo2 = (
  foo​::bar => 'foobar',
  foo__bar => 'foobar',
  'other' => 'whatever'
);

print "foo (,)\n";
foreach my $key (keys %foo) {
  print "\$key = $key\n";
}

print "foo2 (=>)\n";
foreach my $key (keys %foo2) {
  print "\$key = $key\n";
}

~>perl hashKey.pl
foo (,)
$key = other
$key = foo_bar_HASHKEY
$key = HASHKEY
foo2 (=>)
$key = other
$key = HASHKEY
$key = foo__bar

~>perl -v

This is perl, version 5.005_03 built for sun4-solaris
...
--
Mike Giroux
via, but not for, Bear-Stearns

***********************************************************************
Bear Stearns is not responsible for any recommendation, solicitation,
offer or agreement or any information about any transaction, customer
account or account activity contained in this communication.
***********************************************************************

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From [Unknown Contact. See original ticket]

On Tue, Jun 19, 2001 at 12​:18​:46PM -0400, Jeff 'japhy' Pinyan wrote​:

On Jun 19, Jeff 'japhy' Pinyan said​:

On Jun 19, Harmon S. Nine said​:

-- start script --
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
foo​::bar => 'foobar',

Your mistake is using the => (fat comma) operator. This does its best to
ensure that the left-hand side is treated as a quoted string. If you used
a real comma, the function would be called.

Upon further investigation, => did not behave like this in 5.6.0.

Nor in perl5.005.

The docs are quite vague on what actually counts as a word for =>.

Anyway, this is definitely a change in behavior.

Well, apparently now => is uber alles.

  jefpin@​towers [12​:29pm] ~/perl-current #128> ./miniperl -le 'print q=>w'
  qw

Hmm...

  jefpin@​towers [12​:30pm] ~/perl-current #129> ./miniperl -l
  print q
  => w;
  Can't find string terminator "=" anywhere before EOF at - line 2.

There still seems to be some confusion there, but newlines
non-withstanding, a => turns ANY bareword before it into a quoted
string. It used to NOT do that, for things like s and q and m and such.

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From [Unknown Contact. See original ticket]

Moin,

Mike Giroux wrote​:

Harmon S. Nine wrote​:

This is to report a bug in perl 5.6.1.
The bug is as follows​:

When building a hash, key-values for the hash can be calls to
functions.
The return value of
the function is then the actual key for the hash. In the current
version (5.6.1) of perl,
specifically in the Debian distribution of Linux, function calls that
are used as hash
key-values in the construction of a hash are not called, but
are instead
converted directly to
strings.
This is demonstrated by the following script​:

I believe this is not a bug...
[snip]

This works​:

-- start script --
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
foo​::bar, 'foobar',
'other', 'whatever'
);

foreach my $key (keys %foo) {
print "\$key = $key\n";
}
-- end script --

As does this (note "()")​:

- ---- start script ----
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
  foo​::bar() => 'foobar',
  'other' => 'whatever'
);

foreach my $key (keys %foo) {
  print "$key = $foo{$key}\n";
}
- ---- end script ----

Not sure if this helps,

- --
perl -MMath​::String -e 'print \
Math​::String->from_number("+215960156869840440586892398248"),"\n"'

http​://bloodgate.com/thief/ Thief - The Dark Project
http​://bloodgate.com/perl My current Perl projects
http​://freedomforlinks.de Fight for your right to link.
PGP key available on http​://bloodgate.com/tels.asc or via email

-----BEGIN PGP SIGNATURE-----
Version​: 2.6.3i
Charset​: latin1

iQEVAwUBOy+DL3cLPEOTuEwVAQG5lAf/Q2nqTcs09LsNBidzBWbL0v8n6C2yk69e
9cKWeH/Xl6N2mZFBrAOsu9JE7AdRFCg3+8D6E2tJZjjf/0HRCSiZEsnHBYcTQ6Dg
4cU0t/jmydpFAAb1mPSgGbJk9PEJzoAS17xKQ3R+zHGit+XQEN0sm7O9ixh46/bq
RMbeHQBRVXYv9qxwgfzwY0dSNwpgrJ6E7k1E4/WxexJlcGdVYlahYmiLMGZc0g9n
5VU2g0bU7oqYpt+i+Nzcp671g1VsWLt11+ujxYk2lnHDbGI6BYPHpT1yoMNc6/50
oF49nEXjYTzXqDxBhy7IZmpd9wPJWyZSp73EnbtkDpHLxrp55mAMNg==
=VTbq
-----END PGP SIGNATURE-----

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From The RT System itself

Received​: (qmail 77094 invoked by uid 1005); 19 Jun 2001 18​:54​:12 -0000
Delivered-To​: perlmail-richard-perlbug@​tmtowtdi.perl.org
Received​: (qmail 77091 invoked by uid 1005); 19 Jun 2001 18​:54​:12 -0000
Delivered-To​: perlmail-perlbugtron@​perl.org
Received​: (qmail 77068 invoked by uid 1005); 19 Jun 2001 18​:54​:12 -0000
Mailing-List​: contact perl5-porters-help@​perl.org; run by ezmlm
Precedence​: bulk
List-Help​: <mailto​:perl5-porters-help@​perl.org>
List-Unsubscribe​: <mailto​:perl5-porters-unsubscribe@​perl.org>
List-Post​: <mailto​:perl5-porters@​perl.org>
Delivered-To​: mailing list perl5-porters@​perl.org
Delivered-To​: moderator for perl5-porters@​perl.org
Received​: (qmail 5790 invoked from network); 19 Jun 2001 16​:27​:35 -0000
Message-Id​: <3B2F7D08.3030709@​netarx.com>
Date​: Tue, 19 Jun 2001 12​:25​:44 -0400
From​: "Harmon S. Nine" <hnine@​netarx.com>
User-Agent​: Mozilla/5.0 (X11; U; Linux 2.4.5-686 i686; en-US; rv​:0.9.1)
  Gecko/20010612
X-Accept-Language​: en-us
MIME-Version​: 1.0
To​: "Giroux, Mike (Exchange)"
  <mgiroux@​bear.com>, perl5-porters@​perl.org, perlbug@​rfi.net
Subject​: Re​: [ID 20010619.002] When building hash, hash keys that are func
  tion calls are not being called
References​: <03CF7D5B2CFFD211990300A0C95DEA0C0679D261@​whmsx18.is.bear.com>
Content-Type​: multipart/alternative;
  boundary="------------060603060007080207050807"
X-Spam-Rating​: onion.valueclick.com 1.6.2 0/1000/N
--------------060603060007080207050807
Content-Type​: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding​: 7bit

The odd thing is that this code worked before 5.6.1, i.e. in 5.6.0 and
in all versions previous
that I've used. Here's the output from my colleague's machine, who is
still using 5.6.0​:

-- start output --
$key = other
$key = HASHKEY
--- end output ---

If it's not a bug, it should definitely go into the release notes.

-- Harmon

Giroux, Mike (Exchange) wrote​:

Harmon S. Nine wrote​:

This is to report a bug in perl 5.6.1.
The bug is as follows​:

When building a hash, key-values for the hash can be calls to
functions.
The return value of
the function is then the actual key for the hash. In the current
version (5.6.1) of perl,
specifically in the Debian distribution of Linux, function calls that
are used as hash
key-values in the construction of a hash are not called, but
are instead
converted directly to
strings.
This is demonstrated by the following script​:

I believe this is not a bug...

What's happening is that => implicitly single quotes its left argument, so
your

%foo = (
foo​::bar => 'foobar',
'other' => 'whatever'
);

becomes

%foo = (
'foo​::bar' => 'foobar',
'other' => 'whatever'
);

and the function call never happens...

This works​:

-- start script --
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
foo​::bar, 'foobar',
'other', 'whatever'
);

foreach my $key (keys %foo) {
print "\$key = $key\n";
}
-- end script --

Hope this helps,

--------------060603060007080207050807--

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From [Unknown Contact. See original ticket]

The appended patch (to perl-current) should fix this, although the
documentation is somewhat vague about what exactly is quoted by =>.
5.6.0 and earlier did not do this, though, so the patch should be
applied in the interests of backwards compatibility.

I'd be happy to write tests for this if somebody can suggest a good
place to put them.

- ams

Inline Patch
--- perl/toke.c~	Wed Jun 20 01:42:29 2001
+++ perl/toke.c	Wed Jun 20 02:06:30 2001
@@ -1894,7 +1894,7 @@
 	if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, FALSE)) {
 	    s = skipspace(s);
 	    if ((PL_bufend - s) >= 2 && *s == '=' && *(s+1) == '>')
-		return 0;	/* no assumptions -- "=>" quotes bearword */
+		return 0;	/* no assumptions -- "=>" quotes bareword */
       bare_package:
 	    PL_nextval[PL_nexttoke].opval = (OP*)newSVOP(OP_CONST, 0,
 						   newSVpvn(tmpbuf,len));
@@ -3950,7 +3950,7 @@
 		}
 
 		/* Look for a subroutine with this name in current package,
-		   unless name is "Foo::", in which case Foo is a bearword
+		   unless name is "Foo::", in which case Foo is a bareword
 		   (and a package name). */
 
 		if (len > 2 &&
@@ -4024,19 +4024,9 @@
 		    }
 		}
 
-
 		PL_expect = XOPERATOR;
 		s = skipspace(s);
 
-		/* Is this a word before a => operator? */
-		if (*s == '=' && s[1] == '>') {
-		    CLINE;
-		    sv_setpv(((SVOP*)yylval.opval)->op_sv, PL_tokenbuf);
-		    if (UTF && !IN_BYTES && is_utf8_string((U8*)PL_tokenbuf, len))
-		      SvUTF8_on(((SVOP*)yylval.opval)->op_sv);
-		    TERM(WORD);
-		}
-
 		/* If followed by a paren, it's certainly a subroutine. */
 		if (*s == '(') {
 		    CLINE;
@@ -4108,6 +4098,15 @@
 		    PL_expect = XTERM;
 		    force_next(WORD);
 		    TOKEN(NOAMP);
+		}
+
+		/* Is this a word before a => operator? */
+		if (*s == '=' && s[1] == '>') {
+		    CLINE;
+		    sv_setpv(((SVOP*)yylval.opval)->op_sv, PL_tokenbuf);
+		    if (UTF && !IN_BYTES && is_utf8_string((U8*)PL_tokenbuf, len))
+		      SvUTF8_on(((SVOP*)yylval.opval)->op_sv);
+		    TERM(WORD);
 		}
 
 		/* Call it a bare word */

@p5pRT
Copy link
Author

p5pRT commented Jul 26, 2008

From p5p@spam.wizbit.be

On Tue Jun 19 01​:57​:30 2001, hnine@​netarx.com wrote​:

This is to report a bug in perl 5.6.1.
The bug is as follows​:

When building a hash, key-values for the hash can be calls to
functions.
The return value of
the function is then the actual key for the hash. In the current
version (5.6.1) of perl,
specifically in the Debian distribution of Linux, function calls
that
are used as hash
key-values in the construction of a hash are not called, but are
instead
converted directly to
strings.
This is demonstrated by the following script​:

-- start script --
#!/usr/bin/perl

package foo;

sub bar { return 'HASHKEY'; }

package main;

%foo = (
foo​::bar => 'foobar',
'other' => 'whatever'
);

foreach my $key (keys %foo) {
print "\$key = $key\n";
}
--- end script ---

The output of this script is as follows​:
-- start output of above script --
$key = other
$key = foo​::bar
--- end output of above script ---

The second key, i.e. foo​::bar, should actually be the output of the
'bar' function in
package 'foo', i.e. 'HASHKEY'.

HTH

-- Harmon S. Nine

This was resolved in perl-5.8.0.

perl-5.6.1 rt-7130.pl
$key = other
$key = foo​::bar

perl-5.6.2 rt-7130.pl
$key = other
$key = foo​::bar

perl-5.8.0 rt-7130.pl
$key = other
$key = HASHKEY

@p5pRT
Copy link
Author

p5pRT commented Jul 26, 2008

p5p@spam.wizbit.be - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Jul 26, 2008
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant