Class: LaunchDarkly::EvaluationReason

Inherits:
Object
  • Object
show all
Defined in:
lib/ldclient-rb/evaluation_detail.rb

Overview

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.

Constant Summary collapse

OFF =

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

:OFF
FALLTHROUGH =

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

:FALLTHROUGH
TARGET_MATCH =

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

:TARGET_MATCH
RULE_MATCH =

Value for #kind indicating that the user matched one of the flag’s rules.

:RULE_MATCH
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.

:PREREQUISITE_FAILED
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
ERROR_CLIENT_NOT_READY =

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

:CLIENT_NOT_READY
ERROR_FLAG_NOT_FOUND =

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

:FLAG_NOT_FOUND
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.

:MALFORMED_FLAG
ERROR_USER_NOT_SPECIFIED =

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

:USER_NOT_SPECIFIED
ERROR_EXCEPTION =

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

:EXCEPTION

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#error_kindObject (readonly)

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`.



132
133
134
# File 'lib/ldclient-rb/evaluation_detail.rb', line 132

def error_kind
  @error_kind
end

#in_experimentObject (readonly)

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



124
125
126
# File 'lib/ldclient-rb/evaluation_detail.rb', line 124

def in_experiment
  @in_experiment
end

#kindObject (readonly)

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



113
114
115
# File 'lib/ldclient-rb/evaluation_detail.rb', line 113

def kind
  @kind
end

#prerequisite_keyObject (readonly)

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



128
129
130
# File 'lib/ldclient-rb/evaluation_detail.rb', line 128

def prerequisite_key
  @prerequisite_key
end

#rule_idObject (readonly)

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`.



121
122
123
# File 'lib/ldclient-rb/evaluation_detail.rb', line 121

def rule_id
  @rule_id
end

#rule_indexObject (readonly)

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`.



117
118
119
# File 'lib/ldclient-rb/evaluation_detail.rb', line 117

def rule_index
  @rule_index
end

Class Method Details

.error(error_kind) ⇒ EvaluationReason

Returns an instance whose #kind is #ERROR.

Parameters:

  • error_kind (Symbol)

    value indicating the general category of error

Returns:

Raises:

  • (ArgumentError)

    if ‘error_kind` is not a symbol



190
191
192
193
194
# 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) ⇒ EvaluationReason

Returns an instance whose #kind is #FALLTHROUGH.

Returns:



142
143
144
145
146
147
148
# 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

.offEvaluationReason

Returns an instance whose #kind is #OFF.

Returns:



136
137
138
# File 'lib/ldclient-rb/evaluation_detail.rb', line 136

def self.off
  @@off
end

.prerequisite_failed(prerequisite_key) ⇒ EvaluationReason

Returns an instance whose #kind is #PREREQUISITE_FAILED.

Parameters:

  • prerequisite_key (String)

    key of the prerequisite flag that did not return the desired variation

Returns:

Raises:

  • (ArgumentError)

    if ‘prerequisite_key` is nil or not a string



180
181
182
183
# 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) ⇒ EvaluationReason

Returns an instance whose #kind is #RULE_MATCH.

Parameters:

  • rule_index (Number)

    the index of the rule that was matched (0 for the first rule in the feature flag)

  • rule_id (String)

    unique string identifier for the matched rule

Returns:

Raises:

  • (ArgumentError)

    if ‘rule_index` is not a number or `rule_id` is not a string



163
164
165
166
167
168
169
170
171
172
173
# 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_matchEvaluationReason

Returns an instance whose #kind is #TARGET_MATCH.

Returns:



152
153
154
# File 'lib/ldclient-rb/evaluation_detail.rb', line 152

def self.target_match
  @@target_match
end

Instance Method Details

#==(other) ⇒ Object



196
197
198
199
200
201
202
203
204
205
# 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) ⇒ Object

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`.



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# 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_jsonHash

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

Returns:

  • (Hash)


239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# 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

#inspectString

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.

Returns:

  • (String)


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# 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) ⇒ String

Same as #as_json, but converts the JSON structure into a string.

Returns:

  • (String)


269
270
271
# File 'lib/ldclient-rb/evaluation_detail.rb', line 269

def to_json(*a)
  as_json.to_json(a)
end

#to_sString

Equivalent to #inspect.

Returns:

  • (String)


209
210
211
# File 'lib/ldclient-rb/evaluation_detail.rb', line 209

def to_s
  inspect
end