Although associating code blocks with individual
configurations may be a sufficient solution for some applications,
it can sometimes be difficult to maintain. You might find that you
are always adding a certain
of configurations to the same
code blocks. Or, when adding a new configuration to an existing
project, you might find it onerous associating that configuration
with each existing and appropriate code block.
In reality, code blocks are usually defined to
address some specific feature of the platform to which that code
will be deployed; and often, several deployment platforms share the
same features and, thus, the same code blocks. To address these
problems, configurations have the concept of abilities.
identifiers that can be associated with code blocks in much the
same way that configuration
are. Configurations can then be
associated with as many abilities as desired. Once this is done,
activating a configuration uncomments any code block containing
either the configuration or any of its associated abilities.
For example, you might be creating an
application with six different distributions. In your source, you
create some code blocks that handle calls to a vendorspecific
Bluetooth implementation. Three of your target distribution
platforms will have that specific Bluetooth API available. Rather
than list in each code block those three configuration names, you
would instead associate that code block with an ability called
VendorSpecificBluetoothAPI. Then you associate it with the three
configurations that support the Bluetooth API.
This makes maintenance much easier for existing
code blocks. Now, if you decide to support a new device that has a
certain ability, you can simply attach all appropriate abilities to
the new configuration. Then it will automatically be compatible
with all existing code blocks.
As such, it is almost always preferable to use
abilities when creating code blocks rather than simply
configurations. The only cases for using pure configuration names
are when you are never planning on supporting more than a few
platforms for a given application or when the code block is
specific to only one deployment platform.
In principle, abilities can be used as three
types of values even though they are all stored as
objects internally. They can be treated as Boolean symbols and the
preprocessor can check for their definition; they can be treated
and compared as Strings (e.g.,
they can also be used as Integers (e.g.,
provided that the string value they hold is a valid integer.