diff --git a/lib/ldclient-rb/config.rb b/lib/ldclient-rb/config.rb index 20ab4008..29bd2d66 100644 --- a/lib/ldclient-rb/config.rb +++ b/lib/ldclient-rb/config.rb @@ -262,6 +262,10 @@ def offline? # You can also specify the same behavior for an individual flag evaluation # by providing the context object with a list of private attributes. # + # Each entry is an attribute reference. A reference addresses attributes by + # symbol name, so it cannot make an attribute private if that attribute was + # given a string name. Refer to {LDContext} for the symbol requirement. + # # @see https://docs.launchdarkly.com/sdk/features/user-context-config#using-private-attributes # # @return [Array] diff --git a/lib/ldclient-rb/context.rb b/lib/ldclient-rb/context.rb index 081d61a2..58e8c40a 100644 --- a/lib/ldclient-rb/context.rb +++ b/lib/ldclient-rb/context.rb @@ -6,6 +6,17 @@ module LaunchDarkly # LDContext is a collection of attributes that can be referenced in flag # evaluations and analytics events. # + # Every attribute name must be a symbol. This applies to the built-in + # properties, such as :key and :kind, and to custom attributes at every level + # of nesting. The SDK addresses attributes by symbol, so it cannot find an + # attribute that has a string name. Such an attribute is invisible to flag + # evaluation and to private attribute redaction. + # + # Take care with data that arrives as JSON. `JSON.parse` returns string keys + # by default, so pass `symbolize_names: true` before you build a context from + # it. Note that the `"name": value` form in a hash literal already produces a + # symbol, so a hand-written literal is safe. + # # To create an LDContext of a single kind, such as a user, you may use # {LDContext#create} or {LDContext#with_key}. # @@ -148,6 +159,9 @@ def kinds # # Return an array of top level attribute keys (excluding built-in attributes) # + # The keys come back in the form the caller supplied. A string key is + # returned as a string, even though the SDK cannot address it. + # # @return [Array] # def get_custom_attribute_names @@ -172,6 +186,9 @@ def get_custom_attribute_names # values out of JSON objects or arrays, such as "/address/street". Use # {#get_value_for_reference} for that purpose. # + # The lookup treats the name as a symbol. An attribute that was stored under + # a string name is therefore not found, and the result is nil. + # # If the value is found, the return value is the attribute value; # otherwise, it is nil. # @@ -200,6 +217,10 @@ def get_value(attribute) # Use {#individual_context} to inspect a Context for a particular kind and # then get its attributes. # + # A Reference holds its path components as symbols, so each step of the + # lookup matches a symbol key. A path that crosses an attribute with a + # string name resolves to nil. + # # If the value is found, the return value is the attribute value; # otherwise, it is nil. # @@ -440,6 +461,14 @@ def self.with_key(key, kind = KIND_DEFAULT) # {https://docs.launchdarkly.com/sdk/features/user-config SDK # documentation}. # + # Every key in the hash must be a symbol, at the top level and inside any + # nested attribute value. Refer to the {LDContext} class documentation for + # why, and for the JSON.parse caveat. + # + # A string key does not make the context invalid, with two exceptions. The + # context requires a symbol :kind and a symbol :key, so a hash that supplies + # those as strings is invalid. + # # @param data [Hash] # @return [LDContext] # diff --git a/lib/ldclient-rb/reference.rb b/lib/ldclient-rb/reference.rb index 8c248fe3..d50b1e6d 100644 --- a/lib/ldclient-rb/reference.rb +++ b/lib/ldclient-rb/reference.rb @@ -12,6 +12,10 @@ module LaunchDarkly # or to identify an attribute or nested value that should be considered # private. # + # A Reference holds its path components as symbols, whichever form the input + # string used. It therefore addresses only context attributes that have symbol + # names, which is the form a context requires. + # # Parsing and validation are done at the time that the Reference is # constructed. If a Reference instance was created from an invalid string, it # is considered invalid and its {Reference#error} attribute will return a