HOME  |    TRAINING  |   FREE TUTORIALS   |   JOBS
Find out more about our new RSS feed.
FREE Tutorial
PROFESSIONAL PERL PART 5 - ATTRIBUTE LISTS

CATEGORY
SEARCH OUR OTHER TUTORIALS

DESCRIPTION

Attributes are a largely experimental feature, still under development, and only present from Perl version 5.6 onwards, so accordingly we have left them to the end of the chapter. The use of attributes in production code is not recommended, but being aware of them is not a bad idea, since they will ultimately mature into an official part of the language.


This free tutorial is a sample from the book Professional Perl Programming.


In brief, attributes are pieces of information associated with either variables or subroutines that can be set to modify their behavior in specific ways. The primary users of attributes are subroutines. Perl recognizes and understands three special attributes, lvalue, locked, and method, which alter the way in which the Perl interpreter executes subroutines. It is more than likely other special attributes will appear as Perl evolves. We have already seen lvalue in this chapter, and cover locked and method in brief below.

Currently, we cannot define our own attributes on either variables or subroutines, only those defined and understood by Perl. However, an experimental package attribute mechanism, which associates user-defined attributes with packages, is under development. All variables and subroutines that reside in the package automatically have the package attributes associated with them.

Attributes can be placed on both subroutines and lexical variables. The basic form of a variable attribute list is one or more variables declared with my followed by a semicolon and the attribute list. However, there are no variable attributes currently understood by Perl.

Defining Attributes on Subroutines

The basic form of a subroutine attribute list is a standard subroutine definition (or declaration), followed by a colon and the attributes to be defined. Attributes are separated by whitespace, and optionally a colon, these are then followed by the body of the subroutine or (in the case of a declaration) a semicolon:

sub mysubroutine : attr1 : attr2 {  # standard subroutine
... body of subroutine ...
}
sub mysubroutine : attr1 attr2;  # subroutine declaration


my $subref = sub : attr1 : attr2 {  # anonymous subroutine
... body of subroutine ...  
}
sub mysubroutine (\@$$;$) : attr;  # declaration with prototype
sub mysubroutine attr (parameters);  # attribute with parameters

At the time of writing, the attributes lvalue, locked, and method are the only attributes that can be set. None of these use a parameter list as shown in the last example, but the syntax accepts the possibility in anticipation of future applications.

Accessing Attributes

Attribute definitions are actually handled by the attributes pragmatic module, which implements the modified syntax for variables and subroutines that allows them to be defined. The attributes module also supplies subroutines to access these attributes, which we can use by importing them from the attributes module:

use attributes qw(get reftype);  # import 'get' and 'reftype' subroutines

The get subroutine takes a variable, or subroutine reference, and returns a list of attributes defined on that reference. If there are none, then the list is empty. For example:

sub mysubroutine : locked method {
...
}

my @attrlist = get &mysubroutine;  # contains ('locked', 'method')

The reftype subroutine also takes a reference to a variable or subroutine. It returns the underlying reference type; HASH for a hash variable, CODE for a subroutine reference, and so on. Blessed references return the underlying data type, which makes reftype a potentially useful subroutine as a replacement for ref, even if we are not using attributes.

Special Attributes

Perl currently defines three attributes with special meanings - locked, method, and lvalue. Of all the aspects of attributes discussed so far, these are the most immediately useful.

The lvalue attribute allows subroutines to return assignable values, rather like the substr function does when used on a variable, as we discussed earlier in the chapter.

The locked attribute is useful in threaded programming, when more than one thread of execution can call the same subroutine simultaneously. In many cases, such subroutines need to complete one call before the next can proceed, such as writing complex information to a file or the screen, or handing a database transaction. In order to stop simultaneous calls from treading on each other's toes, we can lock the subroutine so that only one thread can execute it at any time:

sub oneatatimeplease : locked {
# only one thread can execute this subroutine at a time.
}

The method attribute is used in object classes to indicate that a locked subroutine should lock on a per-object basis. It modifies the effect of the locked attribute to apply itself to the first argument of the subroutine. In an object method this is the blessed reference representing the object. As a result, the method block only calls if the object being passed is already busy in that method; other objects of the same class proceed unhindered:

sub objectmethodlock : locked : method {
my $self = shift;
# only one thread can execute this method on the same object
# but different threads can execute it on different objects
}

Whether or not it is used with locked, method also prevents Perl from confusing it with a built-in function of the same name. We can therefore create a method called print and be sure that it will only be used when an object-oriented call to print is made. Only if the subroutine is called as an object method will Perl call it instead of the built-in function.

We cover the locked and method attributes in a little more detail when we discuss threaded programming in Perl in chapter 22.

Package Attributes

Package attributes are an experimental feature implemented in the attributes module. We will do no more than take a brief look at what they are supposed to do here, because the mechanism and syntax of how they are defined and used is likely to change at some point.

The idea of package attributes is that we can implement our own attributes that work on a package-wide basis. To implement them, we write specially named subroutines within the package that will be called by the get subroutine mentioned above. Each different type may (or may not) have a distinct set of attributes associated with it, so a scalar variable has different attributes to an array, but all scalar variables in the package share the same set of attributes. This is very similar in concept to the way that tied variables work.

Attributes are stored and returned according to the package implementation. A given attribute data type is implemented by writing FETCH_X_ATTRIBUTES and MODIFY_X_ATTRIBUTES subroutines, where X is the data type - either SCALAR, ARRAY or HASH. The package may implement the details of storage and retrieval any way it likes, just as with tied variables. To retrieve attributes on subroutines, we define FETCH_CODE_ATTRIBUTES, and to allow them to be set as well, we define MODIFY_CODE_ATTRIBUTES.

FETCH subroutines are called by get whenever we use it on a reference of the correct type in the same package. They are passed a single argument, which is a reference to the entity being queried. They return a list of the attributes defined for that entity.

MODIFY subroutines are called during the import stage of compilation. They take a package name and a reference as their first two arguments, followed by a list of attributes to define. They return a list of unrecognized attributes, which may be empty.

The current design also allows for packages that inherit attributes from a parent package by calling SUPER::FETCH_X_ATTRIBUTES and SUPER::MODIFY_X_ATTRIBUTES. The intent is that a child FETCH or MODIFY subroutine should first call its parent, and then deal with any attributes returned. In the case of FETCH, it adds its own attributes to the list and returns it. In the case of MODIFY, it deals with the list of unrecognized attributes passed back from the parent.

Summary

In this chapter we saw how to declare and call subroutines. Specifically we looked at anonymous subroutines, subroutine references, and the use strict subs pragma. Next we looked at predeclaring subroutines, and learned how to override built-in functions. After this, we learned about the internal stack, which Perl uses to hold details of subroutines, and saw an example of a recursive subroutine.

Several issues concerning the passing of parameters were covered, including:

  • Passing lists and hashes.
  • Converting scalar subroutines into list processors.
  • Passing @_ directly into subroutines.
  • Named parameters

Prototypes were discussed in-depth, and the topics covered included the following:

  • Defining the number of parameters.
  • Prototyping code references.
  • Subroutines as scalar operators.
  • Optional parameters.
  • Disabling prototypes.

Following this, we looked at how to return values from subroutines, and saw how to return the undefined value, and determine and respond to the calling context. Finally, we covered attribute lists, and looked at defining attributes on subroutines, accessing attributes, special attributes, and package attributes.




5 RELATED COURSES AVAILABLE
MICROSOFT VISUAL BASIC V6 INTRODUCTION
To go from the fundamentals of Visual Basic programming to the threshold of Advanced level. Gaining in depth prog....
MICROSOFT VISUAL BASIC 5.0 PROFESSIONAL INTRODUCTION
To provide readers with a solid foundation upon which to build Windows applications using Visual Basic 5. Readers....
MICROSOFT VISUAL BASIC 5.0 CLIENT SERVER DEVELOPMENT
This course teaches the skills required to develop client server applications using MS Visual Basic 5.0 Enterpris....
C++ PROGRAMMING
Object oriented programming is fast becoming the leading software design methodology, with C++ becoming ever more....
C PROGRAMMING
This course is design to provide non-C programmers with the essential skills and knowledge necessary to allow the....
 
0 RELATED JOBS AVAILABLE
CONTACT US
Wednesday 3rd December 2008  © COPYRIGHT 2008 - VISUALSOFT