sort function warning, variable will not stay shared

C

ccc31807

Suggestions for dealing with a warning for a sort function, please.

My query of a database table returns a reference to a hash of all the
records in the database. $content contains the hash reference for the
records. One of the columns is called 'name' which contains values
like 'George Washington', 'John Adams', and 'Thomas Jefferson'. I want
to iterate through the hash, sorting by the last name, e.g., Adams,
Jefferson, and Washington. The first name is immaterial.

The key is 'username' which is the primary key in the table and a
unique value.

This is the code I use to iterate through the hash:
foreach my $key (sort sortf keys %{$content})
{
#print values here, like
$content->{$key}{'name'}
$content->{$key}{'status'}
$content->{$key}{'username'}
$content->{$key}{'role'}
}

Here is the sortf function, which is an inner subroutine in the block
containing the hash iteration:
sub sortf
{
my ($alast, $blast);
($alast = $content->{$a}{'name'}) =~ s/.* (.*)$/$1/; #---line 164---
($blast = $content->{$b}{'name'}) =~ s/.* (.*)$/$1/;
return lc($alast) cmp lc($blast) if $alast ne $blast;
return $a cmp $b;
}

If I place this subroutine outside the block, it can't see $content
and generates a syntax error. If I place it in the block, it runs, but
generates a warning message. This has been running for some time, and
I'm inclined to ignore the warnings, but I would like to know that the
warnings are surplus.

Here is the warning message:
perl -cw CONSOLE.pm
[Fri Oct 2 10:26:09 2009] CONSOLE.pm: Variable "$content" will not
stay shared at CONSOLE.pm line 164.
CONSOLE.pm syntax OK

Suggestions?

TIA, CC.
 
C

ccc31807

Does it contain names like

    George Forman Jr
    Susan Saint James
    Kim Jong Il

No. The data is validated and will always match /^(\w+) (\w+)$/.

Yeah, I am aware of constructs like O'Reilly, St. Cyr, de Ruyter,
etc., but these are handled by another routine (that works without
warnings). This particular table contains temporary values that users
will later edit. The important value is username, which is a
guaranteed unique value, and all the name does is cue the user. After
the user edits his name, the name value disappears forever.

CC
 
C

ccc31807

There are two solutions: use an anonymous sub instead, since anon subs
*are* closures, or pass sort a block instead of a sub, which compiles
the block as an anon sub.

Thanks, Ben. I moved the code in the block to the sort function, and
it works without generating warnings.

Actually, this occurred to me earlier, but I couldn't quite wrap my
mind around declaring lexical variables in the sort block. Now that I
see it, it looks (almost) normal.

I would like to make this observation -- Learning how to sort on the
various elements of a multi-level data structure isn't obvious, and
isn't particularly easy, and the know-how probably isn't that common,
but it's a very useful thing to learn. I'm not real good at it, but
I've figured out the basics enough to do what I need to do. We
occasionally have code walk-throughs with people who don't use Perl
(I'm essentially the only Perl guy in the shop) and I've learned to
expect and appreciate the WTF reaction every time we hit the unwinding
of a multi-level hash, with the sort block a little extra piece of
lunacy. It's nice being able to see order in what everyone else
perceives as chaos.

CC
 
U

Uri Guttman

c> I would like to make this observation -- Learning how to sort on
c> the various elements of a multi-level data structure isn't obvious,
c> and isn't particularly easy, and the know-how probably isn't that
c> common, but it's a very useful thing to learn. I'm not real good at
c> it, but I've figured out the basics enough to do what I need to
c> do. We occasionally have code walk-throughs with people who don't
c> use Perl (I'm essentially the only Perl guy in the shop) and I've
c> learned to expect and appreciate the WTF reaction every time we hit
c> the unwinding of a multi-level hash, with the sort block a little
c> extra piece of lunacy. It's nice being able to see order in what
c> everyone else perceives as chaos.

try Sort::Maker and see how it generates sorts. you can print out
generated source and cut/paste it into your code. it is much easier to
define how to get and compare keys in its syntax than the basic sort
when you do multilevel and complex key extraction. also it can generate
sorts in 4 styles including plain (which you did) and the fastest one
GRT.

the issue about accessing the hash ref from inside the sorter is still
a problem but you could eval the generated code in the current
context and it should have access to any lexicals. not tested yet.

uri
 
R

Randal L. Schwartz

Ben> The technical reason for this is
Ben> that named subs are not closures in Perl 5:

You have "not" in there, where I think you meant "named subs *are* closures",
because you correctly describe the effect of it being a closure here:

Ben> in simple terms, the
Ben> *second* time you run the block of code that does the sort the sub will
Ben> still be looking at the $content variable from the *first* time, and you
Ben> will get incorrect results.

As in, the variables get the closure treatment the first time, and therefore
they are no longer "shared".
 
M

Martien Verbruggen

Suggestions for dealing with a warning for a sort function, please.
Here is the warning message:
perl -cw CONSOLE.pm
[Fri Oct 2 10:26:09 2009] CONSOLE.pm: Variable "$content" will not
stay shared at CONSOLE.pm line 164.
CONSOLE.pm syntax OK

Ben has already given you the correct answer, but for future reference,
you should be aware of the perldiag documentation which documents all of
Perl's warning and error messages, including possible causes, and, more
importantly, possible fixes. The section for this warning would have
given you the fix, although it doesn't spell out as well as Ben's answer
what the cause is.

Regards,
Martien
 
M

Martien Verbruggen

Suggestions for dealing with a warning for a sort function, please.

The answer has already been given by Ben and Randal, but for future
reference, you should be aware of the perldiag documentation, which
documents all of Perl's warnings and errors, together with possible
causes and fixes.

Regards,
Martien
 
J

Justin C

[Fri Oct 2 10:26:09 2009] CONSOLE.pm: Variable "$content" will not
stay shared at CONSOLE.pm line 164.

GIYF

I started typing "variable w" into Google and "variable will not stay
shared" was the fourth option - it only moved higher the more I typed.
In what way does Google not resolve this problem?

Justin.
 
C

ccc31807

In what way does Google not resolve this problem?

I googled the warning message and probably read the same things you
did. That wasn't really the point. What I failed to understand was
that you could use lexical variables in a sort block.

The other issue was whether the sort function would ever misbehave.
This wasn't addressed directly, but I understood implicitly that the
sort function would do its job even with the warning message.

CC
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top