请教Perl源码中GvNAME与GvENAME、HvNAME与HvNAME_HEK的区别
Great question! Let's break down these pairs of Perl internal functions one by one, with concrete examples to make the differences crystal clear.
First, let's recall that a "gv" (glob value) in Perl represents a symbol table entry that can hold multiple types of values (scalar, array, hash, subroutine, etc.).
GvNAME(gv)returns the original name registered in the symbol table for that glob. This is the name you used when declaring or creating the glob, and it doesn't change even if the glob is aliased to another.GvENAME(gv)returns the effective name — this is the name of the glob that the target glob is actually linked to (if it's an alias). If the glob isn't an alias,GvENAMEwill matchGvNAME.
Here's a practical example to see this in action:
use strict; use warnings; use Devel::Peek qw(GvNAME GvENAME); # Create an original glob with a scalar value our $original = "I'm the original"; # Alias *alias to point to *original *alias = *original; # Create another alias pointing to the first alias *another_alias = *alias; # Check the original glob print "Original glob (*original):\n"; print " GvNAME: ", GvNAME(*original), "\n"; # Output: original print " GvENAME: ", GvENAME(*original), "\n"; # Output: original (no alias target) # Check the first alias print "\nFirst alias (*alias):\n"; print " GvNAME: ", GvNAME(*alias), "\n"; # Output: alias (its symbol table name) print " GvENAME: ", GvENAME(*alias), "\n"; # Output: original (its linked target) # Check the second alias print "\nSecond alias (*another_alias):\n"; print " GvNAME: ", GvNAME(*another_alias), "\n"; # Output: another_alias print " GvENAME: ", GvENAME(*another_alias), "\n"; # Output: original (directly links to the root target)
Notice how GvNAME always reflects the name the glob was created with, while GvENAME cuts through aliases to show the actual glob it's referencing.
Now for hash-related functions: "Hv" stands for hash value, which represents a Perl hash structure.
HvNAME(hv)returns the human-readable string name of the hash (if it's a named hash, like%my_hash). For anonymous hashes, this will returnundefor an empty string.HvNAME_HEK(hv)returns a pointer to Perl's internal HEK (Hash Entry Key) structure for the hash's name. This structure isn't meant for direct human use — it stores the name string, its precomputed hash value, and length, which Perl uses internally to optimize symbol table lookups and hash operations (avoiding recalculating the hash every time).
Here's an example demonstrating this:
use strict; use warnings; use Devel::Peek qw(HvNAME HvNAME_HEK HEK_KEY HEK_LEN); # Create a named hash our %test_hash = (apple => 1, banana => 2); # Get the string name print "HvNAME(\%test_hash): ", HvNAME(\%test_hash), "\n"; # Output: test_hash # Get the internal HEK structure and extract its contents my $hek = HvNAME_HEK(\%test_hash); print "HEK structure key: ", HEK_KEY($hek), "\n"; # Output: test_hash print "HEK structure length: ", HEK_LEN($hek), "\n"; # Output: 9 (length of "test_hash") # Try with an anonymous hash my $anon_hash = { x => 3, y => 4 }; print "\nHvNAME for anonymous hash: ", HvNAME($anon_hash) // 'undef', "\n"; # Output: undef print "HvNAME_HEK for anonymous hash: ", HvNAME_HEK($anon_hash) // 'undef', "\n"; # Output: undef
The key takeaway here is that HvNAME is for when you need a usable string name, while HvNAME_HEK is an internal optimization tool for Perl's core code to work with hash names efficiently.
内容的提问来源于stack exchange,提问作者Eugen Konkov

