Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component ball_attribute
[Package ball]

Provide a representation of (literal) name/value pairs. More...

Namespaces

namespace  ball

Detailed Description

Outline
Purpose:
Provide a representation of (literal) name/value pairs.
Classes:
ball::Attribute (literal) name/value pair
See also:
Component ball_managedattribute
Description:
This component implements an unusual in-core value-semantic class, ball::Attribute. Each instance of this type represents an attribute that consists of a (literal) name (held but not owned), and an associated value (owned) that can be an int, long, long long, unsigned int, unsigned long', unsigned long long, or a bsl::string.
This component participates in the implementation of "Rule-Based Logging". For more information on how to use that feature, please see the package level documentation and usage examples for "Rule-Based Logging".
IMPORTANT: The attribute name, whose type is const char *, must therefore remain valid throughout the life time of the ball::Attribute object and that of any other ball::Attribute objects that are copied or assigned from the original object. It is recommended that only null-terminated C-string literals be used for names.
Attribute Naming Recommendations:
Attributes can be rendered as part of a log message and used for log post-processing and analysis. It is recommended to use the following naming conventions for attribute names:
  • An attribute name should start with an alphabetic character, no other special characters, digits should be allowed as the first character of the attribute name.
  • An attribute name should not contain whitespaces.
  • An attribute name should contain only alphanumeric characters, underscores(_), and dots(.). Do not use any other special characters.
Disregarding these conventions may prevent the log output from being correctly parsed by commonly used log processing software.
Usage:
This section illustrates intended use of this component.
Example 1: Basic Attribute usage:
The following code creates four attributes having the same name, but different attribute value types.
    ball::Attribute a1("day", "Sunday");
    ball::Attribute a2("day", 7);
    ball::Attribute a3("day", 7LL);
    ball::Attribute a4("day", 7ULL);
The names of the attributes can be found by calling the name method:
    assert(0 == bsl::strcmp("day", a1.name()));
    assert(0 == bsl::strcmp("day", a2.name()));
    assert(0 == bsl::strcmp("day", a3.name()));
    assert(0 == bsl::strcmp("day", a4.name()));
The value method returns a non-modifiable reference to the bdlb::Variant object that manages the value of the attribute:
    assert(true     == a1.value().is<bsl::string>());
    assert("Sunday" == a1.value().the<bsl::string>());

    assert(true     == a2.value().is<int>());
    assert(7        == a2.value().the<int>());

    assert(true     == a3.value().is<long long>());
    assert(7        == a3.value().the<long long>());

    assert(true     == a4.value().is<unsigned long long>());
    assert(7        == a4.value().the<unsigned long long>());
Note that the name string that is passed to the constructor of ball::Attribute must remain valid and unchanged after the ball::Attribute object is created. In the next example, we create a temporary buffer to store the name string, and then use the buffer to create an attribute. Note that any subsequent changes to this temporary buffer will also modify the name of the attribute:
    char buffer[] = "Hello";
    ball::Attribute a4(buffer, 1);                   // BAD IDEA!!!
    bsl::strcpy(buffer, "World");
    assert(0 == bsl::strcmp("World", a4.name()));
The ball::Attribute class also provides a constructor that takes a value of type ball::Attribute::Value:
    ball::Attribute::Value value;
    value.assign<bsl::string>("Sunday");
    ball::Attribute a5("day", value);
    assert(a5 == a1);
Example 2: Using Attribute to log pointers to opaque structure:
Consider we have an event scheduler that operates on events referred to by event handle:
    struct Event {
        d_int d_id;
    };

    typedef Event * EventHandle;
The event handler value can be logged using ball::Attribute as follows:
    Event           event;
    EventHandle     handle = &event;
    ball::Attribute a7("event", handle);

    assert(true   == a7.value().is<const void *>());
    assert(handle == a7.value().the<const void *>());