Class: Google::Cloud::Debugger::Breakpoint::Variable

Inherits:
Object
  • Object
show all
Defined in:
lib/google/cloud/debugger/breakpoint/variable.rb

Overview

Variable

Represents a variable or an argument possibly of a compound object type. Note how the following variables are represented:

A simple Variable:

  x = 5
  # Captured variable:
  # { name: "x", value: "5", type: "Integer" }

A Compound Variable:

  class T
    attr_accessor :m1, :m2
    ...
  end
  v = T.new(1, "2")
  # Captured variable:
  # {
  #   name: "v",
  #   type: "T",
  #   members: [
  #     { name: "@m1", value: "1", type: "Integer" },
  #     { name: "@m2", value: "2", type: "String" }
  #   ]
  # }

A Hash object:

  hash = { a: 1, b: :two }
  # Captured variable:
  # {
  #   name: "hash",
  #   type: "Hash",
  #   members: [
  #     { name: "a", value: "1", type: "Integer" },
  #     { name: "b", value: ":2", type: "Symbol" }
  #   ]
  # }

An Array object:

  ary = [1, nil]
  # Captured variable:
  # {
  #   name: "ary",
  #   type: "Array",
  #   members: [
  #     { name: "[0]", value: "1", type: "Integer" },
  #     { name: "[1]", value: "nil", type: "NilClass" }
  #   ]
  # }

Constant Summary collapse

MAX_DEPTH =

Max depth to convert on compound variables

3
MAX_MEMBERS =

Max number of member variables to evaluate in compound variables

1000
MAX_STRING_LENGTH =

Max length on variable inspect results. Truncate extra and replace with ellipsis.

500

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_rb_var(source, name: nil, depth: MAX_DEPTH, var_table: nil, limit: nil) ⇒ Google::Cloud::Debugger::Breakpoint::Variable

Convert a Ruby variable into a Google::Cloud::Debugger::Breakpoint::Variable object. If a variable table is provided, it will store all the subsequently created compound variables into the variable table for sharing.

Examples:

Simple variable conversion

x = 3
var = Variable.from_rb_var x, name: "x"
var.name  #=> "x"
var.value #=> "3"
var.type  #=> "Integer"

Hash conversion

hash = {a: 1, b: :two}
var = Variable.from_rb_var hash, name: "hash"
var.name  #=> "hash"
var.type  #=> "Hash"
var.members[0].name  #=> "a"
var.members[0].value #=> "1"
var.members[0].type  #=> "Integer"
var.members[1].name  #=> "b"
var.members[1].value #=> "two"
var.members[1].type  #=> "Symbol"

Custom compound variable conversion

foo = Foo.new(a: 1, b: []) #=> #<Foo:0x0000 @a: 1, @b: []>
var_table = VariableTable.new
var = Variable.from_rb_var foo, name: "foo"
var.name  #=> "foo"
var.type  #=> "Foo"
var.members[0].name  #=> "@a"
var.members[0].value #=> "1"
var.members[0].type  #=> "Integer"
var.members[1].name  #=> "@b"
var.members[1].value #=> "[]"
var.members[1].type  #=> "Array"

Use variable table for shared compound variables

hash = {a: 1}
ary = [hash, hash]
var_table = VariableTable.new
var = Variable.from_rb_var ary, name: "ary", var_table: var_table
var.name            #=> "ary"
var.var_table_index #=> 0
var_table[0].type   #=> "Array"
var_table[0].members[0].name            #=> "[0]"
var_table[0].members[0].var_table_index #=> 1
var_table[0].members[1].name            #=> "[1]"
var_table[0].members[1].var_table_index #=> 1
var_table[1].type #=> "Hash"
var_table[1].members[0].name #=> "a"
var_table[1].members[0].type #=> "Integer"
var_table[1].members[0].value #=> "1"

Parameters:

  • source (Any)

    Source Ruby variable to convert from

  • name (String)

    Name of the varaible

  • depth (Integer)

    Number of levels to evaluate in compound variables. Default to MAX_DEPTH

  • var_table (Breakpoint::VariableTable)

    A variable table to store shared compound variables. Optional.

  • limit (Integer)

    Maximum number of bytes this conversion should take. This include nested compound member variables' conversions.

Returns:



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/google/cloud/debugger/breakpoint/variable.rb', line 228

def self.from_rb_var source, name: nil, depth: MAX_DEPTH,
                     var_table: nil, limit: nil
  return source if source.is_a? Variable

  if limit && limit < MIN_REQUIRED_SIZE
    return buffer_full_variable var_table
  end

  # If source is a non-empty Array or Hash, or source has instance
  # variables, evaluate source as a compound variable.
  if compound_var?(source) && depth > 0
    from_compound_var source, name: name, depth: depth,
                              var_table: var_table, limit: limit
  else
    new.tap do |var|
      var.name = name.to_s if name
      var.type = source.class.to_s
      limit = deduct_limit limit,
                           var.name.to_s.bytesize + var.type.bytesize
      var.value = truncate_value source.inspect, limit
      var.source_var = source
    end
  end
end

Instance Method Details

#payload_sizeInteger

Calculate the bytesize of all the attributes and that of the member variables.

Returns:

  • (Integer)

    The total payload size of this variable in bytes.



490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
# File 'lib/google/cloud/debugger/breakpoint/variable.rb', line 490

def payload_size
  unless @payload_size
    @payload_size = name.to_s.bytesize +
                    type.to_s.bytesize +
                    value.to_s.bytesize

    unless members.nil?
      @payload_size = members.inject(@payload_size) do |sum, member|
        sum + member.payload_size
      end
    end
  end

  @payload_size
end

#set_error_state(message, refers_to: StatusMessage::UNSPECIFIED) ⇒ Object

Set this variable to an error state by setting the status field



455
456
457
458
459
460
461
# File 'lib/google/cloud/debugger/breakpoint/variable.rb', line 455

def set_error_state message, refers_to: StatusMessage::UNSPECIFIED
  @status = StatusMessage.new.tap do |s|
    s.is_error = true
    s.refers_to = refers_to
    s.description = message
  end
end

#to_grpcObject

Exports the Variable to a Google::Devtools::Clouddebugger::V2::Variable object.



441
442
443
444
445
446
447
448
449
450
451
# File 'lib/google/cloud/debugger/breakpoint/variable.rb', line 441

def to_grpc
  return nil if empty?
  Google::Devtools::Clouddebugger::V2::Variable.new(
    name: name.to_s,
    value: value.to_s,
    type: type.to_s,
    var_table_index: var_table_index_to_grpc,
    members: members_to_grpc || [],
    status: status_to_grpc
  )
end

#total_sizeInteger

Calculate the total bytesize of all the attributes and that of the member variables, plus references into other variables in the variable table.

Returns:

  • (Integer)

    The total payload size of this variable in bytes.



469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/google/cloud/debugger/breakpoint/variable.rb', line 469

def total_size
  unless @total_size
    vars = [self, *(unique_members || [])]

    @total_size = vars.inject(payload_size) do |sum, var|
      if var.var_table && var.var_table_index
        sum + var.var_table[var.var_table_index].total_size
      else
        sum
      end
    end
  end

  @total_size
end