class LaunchDarkly::EvaluationReason

Describes the reason that a flag evaluation produced a particular value. This is returned by methods such as {LDClient#variation_detail} as the `reason` property of an {EvaluationDetail}.

The `kind` property is always defined, but other properties will have non-nil values only for certain values of `kind`. All properties are immutable.

There is a standard JSON representation of evaluation reasons when they appear in analytics events. Use `as_json` or `to_json` to convert to this representation.

Use factory methods such as {EvaluationReason#off} to obtain instances of this class.

Constants

ERROR

Value for {#kind} indicating that the flag could not be evaluated, e.g. because it does not exist or due to an unexpected error. In this case the result value will be the application default value that the caller passed to the client. Check {#error_kind} for more details on the problem.

ERROR_CLIENT_NOT_READY

Value for {#error_kind} indicating that the caller tried to evaluate a flag before the client had successfully initialized.

ERROR_EXCEPTION

Value for {#error_kind} indicating that an unexpected exception stopped flag evaluation. An error message will always be logged in this case.

ERROR_FLAG_NOT_FOUND

Value for {#error_kind} indicating that the caller provided a flag key that did not match any known flag.

ERROR_MALFORMED_FLAG

Value for {#error_kind} indicating that there was an internal inconsistency in the flag data, e.g. a rule specified a nonexistent variation. An error message will always be logged in this case.

ERROR_USER_NOT_SPECIFIED

Value for {#error_kind} indicating that the caller passed `nil` for the user parameter, or the user lacked a key.

FALLTHROUGH

Value for {#kind} indicating that the flag was on but the user did not match any targets or rules.

OFF

Value for {#kind} indicating that the flag was off and therefore returned its configured off value.

PREREQUISITE_FAILED

Value for {#kind} indicating that the flag was considered off because it had at least one prerequisite flag that either was off or did not return the desired variation.

RULE_MATCH

Value for {#kind} indicating that the user matched one of the flag's rules.

TARGET_MATCH

Value for {#kind} indicating that the user key was specifically targeted for this flag.

Attributes

error_kind[R]

A value indicating the general category of error. This should be one of the class constants such as {#ERROR_FLAG_NOT_FOUND}. If {#kind} is not {#ERROR}, it will be `nil`.

in_experiment[R]

A boolean or nil value representing if the rule or fallthrough has an experiment rollout.

kind[R]

Indicates the general category of the reason. Will always be one of the class constants such as {#OFF}.

prerequisite_key[R]

The key of the prerequisite flag that did not return the desired variation. If {#kind} is not {#PREREQUISITE_FAILED}, this will be `nil`.

rule_id[R]

A unique string identifier for the matched rule, which will not change if other rules are added or deleted. If {#kind} is not {#RULE_MATCH}, this will be `nil`.

rule_index[R]

The index of the rule that was matched (0 for the first rule in the feature flag). If {#kind} is not {#RULE_MATCH}, this will be `nil`.

Public Class Methods

error(error_kind) click to toggle source

Returns an instance whose {#kind} is {#ERROR}.

@param error_kind [Symbol] value indicating the general category of error @return [EvaluationReason] @raise [ArgumentError] if `error_kind` is not a symbol

# File lib/ldclient-rb/evaluation_detail.rb, line 190
def self.error(error_kind)
  raise ArgumentError.new("error_kind must be a symbol") if !(error_kind.is_a? Symbol)
  e = @@error_instances[error_kind]
  e.nil? ? make_error(error_kind) : e
end
fallthrough(in_experiment=false) click to toggle source

Returns an instance whose {#kind} is {#FALLTHROUGH}. @return [EvaluationReason]

# File lib/ldclient-rb/evaluation_detail.rb, line 142
def self.fallthrough(in_experiment=false)
  if in_experiment
    @@fallthrough_with_experiment
  else
    @@fallthrough
  end
end
off() click to toggle source

Returns an instance whose {#kind} is {#OFF}. @return [EvaluationReason]

# File lib/ldclient-rb/evaluation_detail.rb, line 136
def self.off
  @@off
end
prerequisite_failed(prerequisite_key) click to toggle source

Returns an instance whose {#kind} is {#PREREQUISITE_FAILED}.

@param prerequisite_key [String] key of the prerequisite flag that did not return the desired variation @return [EvaluationReason] @raise [ArgumentError] if `prerequisite_key` is nil or not a string

# File lib/ldclient-rb/evaluation_detail.rb, line 180
def self.prerequisite_failed(prerequisite_key)
  raise ArgumentError.new("prerequisite_key must be a string") if !(prerequisite_key.is_a? String)
  new(:PREREQUISITE_FAILED, nil, nil, prerequisite_key, nil)
end
rule_match(rule_index, rule_id, in_experiment=false) click to toggle source

Returns an instance whose {#kind} is {#RULE_MATCH}.

@param rule_index [Number] the index of the rule that was matched (0 for the first rule in

the feature flag)

@param rule_id [String] unique string identifier for the matched rule @return [EvaluationReason] @raise [ArgumentError] if `rule_index` is not a number or `rule_id` is not a string

# File lib/ldclient-rb/evaluation_detail.rb, line 163
def self.rule_match(rule_index, rule_id, in_experiment=false)
  raise ArgumentError.new("rule_index must be a number") if !(rule_index.is_a? Numeric)
  raise ArgumentError.new("rule_id must be a string") if !rule_id.nil? && !(rule_id.is_a? String) # in test data, ID could be nil
  
  if in_experiment
    er = new(:RULE_MATCH, rule_index, rule_id, nil, nil, true)
  else
    er = new(:RULE_MATCH, rule_index, rule_id, nil, nil)
  end
  er
end
target_match() click to toggle source

Returns an instance whose {#kind} is {#TARGET_MATCH}. @return [EvaluationReason]

# File lib/ldclient-rb/evaluation_detail.rb, line 152
def self.target_match
  @@target_match
end

Private Class Methods

make_error(error_kind) click to toggle source
# File lib/ldclient-rb/evaluation_detail.rb, line 308
def self.make_error(error_kind)
  new(:ERROR, nil, nil, nil, error_kind)
end
new(kind, rule_index, rule_id, prerequisite_key, error_kind, in_experiment=nil) click to toggle source
# File lib/ldclient-rb/evaluation_detail.rb, line 295
def initialize(kind, rule_index, rule_id, prerequisite_key, error_kind, in_experiment=nil)
  @kind = kind.to_sym
  @rule_index = rule_index
  @rule_id = rule_id
  @rule_id.freeze if !rule_id.nil?
  @prerequisite_key = prerequisite_key
  @prerequisite_key.freeze if !prerequisite_key.nil?
  @error_kind = error_kind
  @in_experiment = in_experiment
end

Public Instance Methods

==(other) click to toggle source
# File lib/ldclient-rb/evaluation_detail.rb, line 196
def ==(other)
  if other.is_a? EvaluationReason
    @kind == other.kind && @rule_index == other.rule_index && @rule_id == other.rule_id &&
      @prerequisite_key == other.prerequisite_key && @error_kind == other.error_kind
  elsif other.is_a? Hash
    @kind.to_s == other[:kind] && @rule_index == other[:ruleIndex] && @rule_id == other[:ruleId] &&
      @prerequisite_key == other[:prerequisiteKey] &&
      (other[:errorKind] == @error_kind.nil? ? nil : @error_kind.to_s)
  end
end
[](key) click to toggle source

Allows this object to be treated as a hash corresponding to its JSON representation. For instance, if `reason.kind` is {#RULE_MATCH}, then `reason` will be `“RULE_MATCH”` and `reason` will be equal to `reason.rule_index`.

# File lib/ldclient-rb/evaluation_detail.rb, line 276
def [](key)
  case key
  when :kind
    @kind.to_s
  when :ruleIndex
    @rule_index
  when :ruleId
    @rule_id
  when :prerequisiteKey
    @prerequisite_key
  when :errorKind
    @error_kind.nil? ? nil : @error_kind.to_s
  else
    nil
  end
end
as_json(*) click to toggle source

Returns a hash that can be used as a JSON representation of the reason, in the format used in LaunchDarkly analytics events. @return [Hash]

# File lib/ldclient-rb/evaluation_detail.rb, line 239
def as_json(*) # parameter is unused, but may be passed if we're using the json gem
  # Note that this implementation is somewhat inefficient; it allocates a new hash every time.
  # However, in normal usage the SDK only serializes reasons if 1. full event tracking is
  # enabled for a flag and the application called variation_detail, or 2. experimentation is
  # enabled for an evaluation. We can't reuse these hashes because an application could call
  # as_json and then modify the result.
  case @kind
  when :RULE_MATCH
    if @in_experiment
      { kind: @kind, ruleIndex: @rule_index, ruleId: @rule_id, inExperiment: @in_experiment }
    else
      { kind: @kind, ruleIndex: @rule_index, ruleId: @rule_id }
    end
  when :PREREQUISITE_FAILED
    { kind: @kind, prerequisiteKey: @prerequisite_key }
  when :ERROR
    { kind: @kind, errorKind: @error_kind }
  when :FALLTHROUGH
    if @in_experiment
      { kind: @kind, inExperiment: @in_experiment }
    else
      { kind: @kind }
    end
  else
    { kind: @kind }
  end
end
inspect() click to toggle source

Returns a concise string representation of the reason. Examples: `“FALLTHROUGH”`, `“ERROR(FLAG_NOT_FOUND)”`. The exact syntax is not guaranteed to remain the same; this is meant for debugging. @return [String]

# File lib/ldclient-rb/evaluation_detail.rb, line 217
def inspect
  case @kind
  when :RULE_MATCH
    if @in_experiment
      "RULE_MATCH(#{@rule_index},#{@rule_id},#{@in_experiment})"
    else
      "RULE_MATCH(#{@rule_index},#{@rule_id})"
    end
  when :PREREQUISITE_FAILED
    "PREREQUISITE_FAILED(#{@prerequisite_key})"
  when :ERROR
    "ERROR(#{@error_kind})"
  when :FALLTHROUGH
    @in_experiment ? "FALLTHROUGH(#{@in_experiment})" : @kind.to_s
  else
    @kind.to_s
  end
end
to_json(*a) click to toggle source

Same as {#as_json}, but converts the JSON structure into a string. @return [String]

# File lib/ldclient-rb/evaluation_detail.rb, line 269
def to_json(*a)
  as_json.to_json(a)
end
to_s() click to toggle source

Equivalent to {#inspect}. @return [String]

# File lib/ldclient-rb/evaluation_detail.rb, line 209
def to_s
  inspect
end