attributes - get/set subroutine or variable attributes
| 🔧 Use Case | 💻 Command | 📝 Description |
|---|---|---|
| Retrieve attributes | my @attrs = attributes::get(\&foo); | Get list of attributes on a subroutine |
| Declare a method | sub foo : method {} | Suppress ambiguous‑call warnings |
| Declare an lvalue sub | sub foo : lvalue {} | Subroutine that can be assigned to; must return modifiable value |
| Constant anonymous sub | my $s = sub : const { 'value' }; | Evaluated immediately and turned into a constant |
| Get reference type | my $type = attributes::reftype(\$var); | Returns 'SCALAR', 'ARRAY', etc. |
| Custom attribute validation | sub MODIFY_CODE_ATTRIBUTES { … } | Handle user‑defined attributes in a package |
sub foo : method ;
my ($x,@y,%z) : Bent = 1;
my $s = sub : method { ... };
use attributes (); # optional, to get subroutine declarations
my @attrlist = attributes::get(\&foo);
use attributes 'get'; # import the attributes::get subroutine
my @attrlist = get \&foo;
Subroutine declarations and definitions may optionally have attribute lists associated with them. (Variable my declarations also may, but see the warning below.) Perl handles these declarations by passing information about the call site and the thing being declared along with the attribute list to this module. The first example above is equivalent to:
use attributes __PACKAGE__, \&foo, 'method';
The second example does something equivalent to:
use attributes ();
my ($x,@y,%z);
attributes::->import(__PACKAGE__, \$x, 'Bent');
attributes::->import(__PACKAGE__, \@y, 'Bent');
attributes::->import(__PACKAGE__, \%z, 'Bent');
($x,@y,%z) = 1;
Yes, that's a lot of expansion.
⚠️ WARNING: attribute declarations for variables are still evolving. The semantics and interfaces of such declarations could change in future versions. They are present for purposes of experimentation with what the semantics ought to be. Do not rely on the current implementation of this feature.
There are only a few attributes currently handled by Perl itself (or directly by this module). However, package‑specific attributes are allowed by an extension mechanism. (See “Package‑specific Attribute Handling” below.)
The setting of subroutine attributes happens at compile time. Variable attributes in our declarations are also applied at compile time. However, my variables get their attributes applied at run‑time. This means that you have to reach the run‑time component of the my before those attributes will get applied. For example:
my $x : Bent = 42 if 0;
will neither assign 42 to $x nor apply the Bent attribute.
An attempt to set an unrecognized attribute is a fatal error. (The error is trappable, but it still stops compilation within that eval.) Setting an attribute whose name is all lowercase and not a built‑in (such as foo) will produce a warning with -w or use warnings 'reserved'.
import doesThe description says
sub foo : method;
is equivalent to
use attributes __PACKAGE__, \&foo, 'method';
This calls the import function of attributes at compile time with these parameters: the module name, the caller’s package, the code reference and 'method'.
attributes->import( __PACKAGE__, \&foo, 'method' );
So what does import actually do?
First, import gets the type of the third parameter ('CODE' in this case). attributes.pm checks if there is a subroutine called MODIFY_<reftype>_ATTRIBUTES in the caller’s namespace (here: 'main'). In this example a subroutine MODIFY_CODE_ATTRIBUTES is required. Then this method is called to check for “bad attributes”. The call would look like
MODIFY_CODE_ATTRIBUTES( 'main', \&foo, 'method' );
MODIFY_<reftype>_ATTRIBUTES must return a list of all “bad attributes”. If any are present, import croaks.
(See “Package‑specific Attribute Handling” below.)
The following are the built‑in attributes for subroutines:
sub foo($$) : prototype(@) {} is indistinguishable from sub foo(@){}.sub expression is evaluated. The return value is captured and turned into a constant subroutine.The following are the built‑in attributes for variables:
threads::shared modules.The following subroutines are available for general use once this module has been loaded:
get – Expects a single parameter – a reference to a subroutine or variable. Returns a list of attributes, which may be empty. If passed invalid arguments, it uses die() (via Carp::croak) to raise a fatal exception. If it can find an appropriate package name for a class method lookup, it will include the results from a FETCH_type_ATTRIBUTES call in its return list, as described in “Package‑specific Attribute Handling” below. Otherwise, only built‑in attributes will be returned.reftype – Expects a single parameter – a reference to a subroutine or variable. Returns the built‑in type of the referenced variable, ignoring any package into which it might have been blessed. Useful for determining the type value that forms part of the method names described in “Package‑specific Attribute Handling” below.These routines are not exported by default.
⚠️ WARNING: the mechanisms described here are still experimental. Do not rely on the current implementation. In particular, there is no provision for applying package attributes to ‘cloned’ copies of subroutines used as closures. Package‑specific attribute handling may change incompatibly in a future release.
When an attribute list is present in a declaration, a check is made to see whether an attribute ‘modify’ handler is present in the appropriate package (or its @ISA inheritance tree). Similarly, when attributes::get is called on a valid reference, a check is made for an appropriate attribute ‘fetch’ handler. See “EXAMPLES” to see how the “appropriate package” determination works.
The handler names are based on the underlying type of the variable being declared or of the reference passed. This deliberately ignores any possibility of being blessed into some package. Thus, a subroutine declaration uses “CODE” as its type, and even a blessed hash reference uses “HASH” as its type.
The class methods invoked for modifying and fetching are:
FETCH_type_ATTRIBUTES – Called with two arguments: the relevant package name, and a reference to a variable or subroutine for which package‑defined attributes are desired. The expected return value is a list of associated attributes (may be empty).MODIFY_type_ATTRIBUTES – Called with two fixed arguments, followed by the list of attributes from the relevant declaration. The two fixed arguments are the relevant package name and a reference to the declared subroutine or variable. The expected return value is a list of attributes that were not recognized by this handler. This allows a derived class to delegate a call to its base class and then only examine the attributes the base class didn’t already handle.The call to MODIFY_type_ATTRIBUTES is made during the processing of the declaration. In particular, a subroutine reference will probably be for an undefined subroutine, even if this declaration is actually part of the definition.
Calling attributes::get() from within the scope of a null package declaration package ; for an unblessed variable reference will not provide any starting package name for the ‘fetch’ method lookup, and thus will not result in a method call for package‑defined attributes. A named subroutine knows to which symbol table entry it belongs and will use the corresponding package. An anonymous subroutine knows the package name into which it was compiled (unless compiled with a null package declaration), and so it will use that package name.
An attribute list is a sequence of attribute specifications, separated by whitespace or a colon (with optional whitespace). Each attribute specification is a simple name, optionally followed by a parenthesised parameter list. If a parameter list is present, it is scanned past as for the rules of the q() operator (see “Quote and Quote‑like Operators” in perlop). The parameter list is passed as it was found, however, and not as per q().
Some examples of syntactically valid attribute lists:
switch(10,foo(7,3)) : expensiveUgly('\(") :Bad_5x5lvalue methodSome examples of syntactically invalid attribute lists (with annotation):
switch(10,foo() – ()‑string not balancedUgly('(') – ()‑string not balanced5x5 – “5x5” not a valid identifierY2::north – not a simple identifierfoo + bar – “+” neither a colon nor whitespaceNone.
The routines get and reftype are exportable.
The :ALL tag will get all of the above exports.
Samples of syntactically valid declarations, with annotation as to how they resolve internally into use attributes invocations by perl. These illustrate how the “appropriate package” is found for possible method lookups for package‑defined attributes.
package Canine;
package Dog;
my Canine $spot : Watchful ;
Effect: use attributes ();
attributes::->import(Canine => \$spot, "Watchful");
package Felis;
my $cat : Nervous;
Effect: use attributes ();
attributes::->import(Felis => \$cat, "Nervous");
package X;
sub foo : lvalue ;
Effect: use attributes X => \&foo, "lvalue";
package X;
sub Y::x : lvalue { 1 }
Effect: use attributes Y => \&Y::x, "lvalue";
package X;
sub foo { 1 }
package Y;
BEGIN { *bar = \&X::foo; }
package Z;
sub Y::bar : lvalue ;
Effect: use attributes X => \&X::foo, "lvalue";
This last example is purely for completeness. You should not be trying to mess with the attributes of something in a package that's not your own.
sub MODIFY_CODE_ATTRIBUTES {
my ($class,$code,@attrs) = @_;
my $allowed = 'MyAttribute';
my @bad = grep { $_ ne $allowed } @attrs;
return @bad;
}
sub foo : MyAttribute {
print "foo\n";
}
This example runs. At compile time MODIFY_CODE_ATTRIBUTES is called. We check if any attribute is disallowed and return a list of “bad attributes”. Since we return an empty list, everything is fine.
sub MODIFY_CODE_ATTRIBUTES {
my ($class,$code,@attrs) = @_;
my $allowed = 'MyAttribute';
my @bad = grep{ $_ ne $allowed }@attrs;
return @bad;
}
sub foo : MyAttribute Test {
print "foo\n";
}
This example is aborted at compile time because we use the attribute Test which isn’t allowed. MODIFY_CODE_ATTRIBUTES returns a list containing 'Test'.
“Private Variables via my()” in perlsub, “Subroutine Attributes” in perlsub for details on basic declarations; “use” in perlfunc for details on the normal invocation mechanism.
attributes - POSIX safety concepts
| 🛡️ Use Case | 📋 Concept | 📝 Description |
|---|---|---|
| Check thread safety | MT‑Safe / MT‑Unsafe markers | Look in function’s ATTRIBUTES section of man page |
| Initialise safely | init feature | Call function once in single‑thread context before starting threads |
| Avoid data races | race feature | Use mutexes around functions that modify shared state |
| Handle constant objects | const feature | Use read‑write lock; readers are safe, writers need write lock |
| Signal interference | sig feature | Block or ensure exclusive use of temporary signal handler |
| Terminal safety | term feature | Use a mutex to protect terminal attribute changes |
| Locale / environment reads | locale, env | Safe as long as modifying functions are not called concurrently |
Note: the text of this man page is based on the material taken from the “POSIX Safety Concepts” section of the GNU C Library manual. Further details on the topics described here can be found in that manual.
Various function manual pages include a section ATTRIBUTES that describes the safety of calling the function in various contexts. This section annotates functions with the following safety markings:
Other keywords that appear in safety notes are defined in subsequent sections.
For some features that make functions unsafe to call in certain contexts, there are known ways to avoid the safety problem other than refraining from calling the function altogether. The keywords that follow refer to such features, and each of their definitions indicates how the whole program needs to be constrained in order to remove the safety problem indicated by the keyword. Only when all the reasons that make a function unsafe are observed and addressed, by applying the documented constraints, does the function become safe to call in a context.
init as an MT‑Unsafe feature perform MT‑Unsafe initialisation when they are first called.race operate on objects in ways that may cause data races or similar forms of destructive interference out of concurrent execution. In some cases, the objects are passed to the functions by users; in others, they are used by the functions to return values to users; in others, they are not even exposed to users.const non‑atomically modify internal objects that are better regarded as constant, because a substantial portion of the GNU C Library accesses them without synchronisation. Unlike race, which causes both readers and writers of internal objects to be regarded as MT‑Unsafe, this mark is applied to writers only. Writers remain MT‑Unsafe to call, but the then‑mandatory constness of objects they modify enables readers to be regarded as MT‑Safe (as long as no other reasons for them to be unsafe remain).const mark will appear by itself as a safety note in readers. Programs that wish to work around this safety issue, so as to call writers, may use a non‑recursive read‑write lock associated with the identifier, and guard all calls to functions marked with const followed by the identifier with a write lock, and all calls to functions marked with the identifier by itself with a read lock.sig may temporarily install a signal handler for internal purposes, which may interfere with other uses of the signal, identified after a colon.term may change the terminal settings in the recommended way, namely: call tcgetattr(3), modify some flags, and then call tcsetattr(3), this creates a window in which changes made by other threads are lost. Thus, functions marked with term are MT‑Unsafe.race:tcattr(fd), where fd is a file descriptor for the controlling terminal.Additional keywords may be attached to functions, indicating features that do not make a function unsafe to call, but that may need to be taken into account in certain classes of programs:
locale read from the locale object without any form of synchronisation. Functions annotated with locale called concurrently with locale changes may behave in ways that do not correspond to any of the locales active during their execution, but an unpredictable mix thereof.const:locale and regarded as unsafe. Being unsafe, the latter are not to be called when multiple threads are running or asynchronous signals are enabled, and so the locale can be considered effectively constant in these contexts, which makes the former safe.env access the environment with getenv(3) or similar, without any guards to ensure safety in the presence of concurrent modifications.const:env and regarded as unsafe. Being unsafe, the latter are not to be called when multiple threads are running or asynchronous signals are enabled, and so the environment can be considered effectively constant in these contexts, which makes the former safe.hostid reads from the system‑wide data structures that hold the “host ID” of the machine. These data structures cannot generally be modified atomically. Since it is expected that the “host ID” will not normally change, the function that reads from it (gethostid(3)) is regarded as safe, whereas the function that modifies it (sethostid(3)) is marked with const:hostid, indicating it may require special care if it is to be called. In this specific case, the special care amounts to system‑wide (not merely intra‑process) coordination.sigintr access the GNU C Library _sigintr internal data structure without any guards to ensure safety in the presence of concurrent modifications.const:sigintr and regarded as unsafe. Being unsafe, the latter are not to be called when multiple threads are running or asynchronous signals are enabled, and so the data structure can be considered effectively constant in these contexts, which makes the former safe.cwd may temporarily change the current working directory during their execution, which may cause relative pathnames to be resolved in unexpected ways in other threads or within asynchronous signal or cancellation handlers.FTW_CHDIR), avoiding the option may be a good alternative to using full pathnames or file descriptor‑relative (e.g., openat(2)) system calls.race and const, or to provide more specific information, such as naming a signal in a function marked with sig. It is envisioned that it may be applied to lock and corrupt as well in the future.:buf(arg) to denote a buffer associated with the argument arg, or :tcattr(fd) to denote the terminal attributes of a file descriptor fd./!ps and /one_per_line indicate the preceding marker only applies when argument ps is NULL, or global variable one_per_line is nonzero.This page is part of release 5.10 of the Linux man-pages project. A description of the project, information about reporting bugs, and the latest version of this page, can be found at https://www.kernel.org/doc/man-pages/.
Generated by phpman v4.9.26-1-g511901d · Markdown · JSON · MCP Author: Che Dong Under GNU General Public License
2026-08-05 03:51 @216.73.216.89
CrawledBy Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
Enhanced by LLM: deepseek-v4-flash / taotoken.net / www.chedong.com - original format