Class: Byebug::Breakpoint

Inherits:
Object
  • Object
show all
Defined in:
lib/byebug/breakpoint.rb,
ext/byebug/breakpoint.c

Overview

Implements breakpoints

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, pos, expr) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'ext/byebug/breakpoint.c', line 256

static VALUE
brkpt_initialize(VALUE self, VALUE source, VALUE pos, VALUE expr)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);

  breakpoint->type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE;
  if (breakpoint->type == BP_POS_TYPE)
    breakpoint->pos.line = FIX2INT(pos);
  else
    breakpoint->pos.mid = SYM2ID(pos);

  breakpoint->id = ++breakpoint_max;
  breakpoint->source = StringValue(source);
  breakpoint->enabled = Qtrue;
  breakpoint->expr = NIL_P(expr) ? expr : StringValue(expr);
  breakpoint->hit_count = 0;
  breakpoint->hit_value = 0;
  breakpoint->hit_condition = HIT_COND_NONE;

  return Qnil;
}

Class Method Details

.add(file, line, expr = nil) ⇒ Object

Adds a new breakpoint

Parameters:

  • file (String)
  • line (Fixnum)
  • expr (String) (defaults to: nil)


27
28
29
30
31
# File 'lib/byebug/breakpoint.rb', line 27

def self.add(file, line, expr = nil)
  breakpoint = Breakpoint.new(file, line, expr)
  Byebug.breakpoints << breakpoint
  breakpoint
end

.firstObject

First breakpoint, in order of creation



9
10
11
# File 'lib/byebug/breakpoint.rb', line 9

def self.first
  Byebug.breakpoints.first
end

.lastObject

Last breakpoint, in order of creation



16
17
18
# File 'lib/byebug/breakpoint.rb', line 16

def self.last
  Byebug.breakpoints.last
end

.none?Boolean

True if there’s no breakpoints

Returns:

  • (Boolean)


76
77
78
# File 'lib/byebug/breakpoint.rb', line 76

def self.none?
  Byebug.breakpoints.empty?
end

.potential_line?(filename, lineno) ⇒ Boolean

Returns true if a breakpoint could be set in line number lineno in file name +filename.

Returns:

  • (Boolean)


69
70
71
# File 'lib/byebug/breakpoint.rb', line 69

def self.potential_line?(filename, lineno)
  potential_lines(filename).member?(lineno)
end

.potential_lines(filename) ⇒ Object

Returns an array of line numbers in file named filename where breakpoints could be set. The list will contain an entry for each distinct line event call so it is possible (and possibly useful) for a line number appear more than once.

Parameters:

  • filename (String)

    File name to inspect for possible breakpoints



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/byebug/breakpoint.rb', line 50

def self.potential_lines(filename)
  name = "#{Time.new.to_i}_#{rand(2**31)}"
  lines = {}
  iseq = RubyVM::InstructionSequence.compile(File.read(filename), name)

  iseq.disasm.each_line do |line|
    res = /^\d+ (?<insn>\w+)\s+.+\(\s*(?<lineno>\d+)\)$/.match(line)
    next unless res && res[:insn] == 'trace'

    lines[res[:lineno].to_i] = true
  end

  lines.keys
end

.remove(id) ⇒ Object

Removes a breakpoint

Parameters:

  • breakpoint (integer)

    number



38
39
40
# File 'lib/byebug/breakpoint.rb', line 38

def self.remove(id)
  Byebug.breakpoints.reject! { |b| b.id == id }
end

Instance Method Details

#enabled=(true) ⇒ Object

Enables or disables breakpoint.



45
46
47
48
49
50
51
52
# File 'ext/byebug/breakpoint.c', line 45

static VALUE
brkpt_set_enabled(VALUE self, VALUE enabled)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  return breakpoint->enabled = enabled;
}

#enabled?Boolean

Returns true if breakpoint is enabled, false otherwise.

Returns:

  • (Boolean)


30
31
32
33
34
35
36
37
# File 'ext/byebug/breakpoint.c', line 30

static VALUE
brkpt_enabled(VALUE self)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  return breakpoint->enabled;
}

#exprString

Returns a conditional expression which indicates when this breakpoint should be activated.

Returns:

  • (String)


61
62
63
64
65
66
67
68
# File 'ext/byebug/breakpoint.c', line 61

static VALUE
brkpt_expr(VALUE self)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  return breakpoint->expr;
}

#expr=(string) ⇒ Object

Sets or unsets the conditional expression which indicates when this breakpoint should be activated.



77
78
79
80
81
82
83
84
85
# File 'ext/byebug/breakpoint.c', line 77

static VALUE
brkpt_set_expr(VALUE self, VALUE expr)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  breakpoint->expr = NIL_P(expr) ? expr : StringValue(expr);
  return expr;
}

#hit_conditionObject

Returns the hit condition of the breakpoint: nil if it is an

unconditional breakpoint, or :greater_or_equal, :equal or :modulo otherwise


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'ext/byebug/breakpoint.c', line 94

static VALUE
brkpt_hit_condition(VALUE self)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  switch (breakpoint->hit_condition)
  {
    case HIT_COND_GE:
      return ID2SYM(rb_intern("greater_or_equal"));
    case HIT_COND_EQ:
      return ID2SYM(rb_intern("equal"));
    case HIT_COND_MOD:
      return ID2SYM(rb_intern("modulo"));
    case HIT_COND_NONE:
    default:
      return Qnil;
  }
}

#hit_condition=(symbol) ⇒ Object

Sets the hit condition of the breakpoint which must be one of the following values:

nil if it is an unconditional breakpoint, or :greater_or_equal(:ge), :equal(:eq), :modulo(:mod)



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'ext/byebug/breakpoint.c', line 124

static VALUE
brkpt_set_hit_condition(VALUE self, VALUE value)
{
  breakpoint_t *breakpoint;
  ID id_value;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  id_value = rb_to_id(value);

  if (rb_intern("greater_or_equal") == id_value || rb_intern("ge") == id_value)
    breakpoint->hit_condition = HIT_COND_GE;
  else if (rb_intern("equal") == id_value || rb_intern("eq") == id_value)
    breakpoint->hit_condition = HIT_COND_EQ;
  else if (rb_intern("modulo") == id_value || rb_intern("mod") == id_value)
    breakpoint->hit_condition = HIT_COND_MOD;
  else
    rb_raise(rb_eArgError, "Invalid condition parameter");
  return value;
}

#hit_countInteger

Returns the number of times this breakpoint has been hit.

Returns:

  • (Integer)


150
151
152
153
154
155
156
157
# File 'ext/byebug/breakpoint.c', line 150

static VALUE
brkpt_hit_count(VALUE self)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  return INT2FIX(breakpoint->hit_count);
}

#hit_valueInteger

Returns the hit value of the breakpoint, namely, a value to build a condition on the number of hits of the breakpoint.

Returns:

  • (Integer)


166
167
168
169
170
171
172
173
# File 'ext/byebug/breakpoint.c', line 166

static VALUE
brkpt_hit_value(VALUE self)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  return INT2FIX(breakpoint->hit_value);
}

#hit_value=(int) ⇒ Object

Sets the hit value of the breakpoint. This allows the user to set conditions on the number of hits to enable/disable the breakpoint.



182
183
184
185
186
187
188
189
190
# File 'ext/byebug/breakpoint.c', line 182

static VALUE
brkpt_set_hit_value(VALUE self, VALUE value)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  breakpoint->hit_value = FIX2INT(value);
  return value;
}

#idInteger

Returns the id of the breakpoint.

Returns:

  • (Integer)


198
199
200
201
202
203
204
205
# File 'ext/byebug/breakpoint.c', line 198

static VALUE
brkpt_id(VALUE self)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  return INT2FIX(breakpoint->id);
}

#inspectObject

Prints all information associated to the breakpoint



83
84
85
86
87
88
89
# File 'lib/byebug/breakpoint.rb', line 83

def inspect
  meths = %w(id pos source expr hit_condition hit_count hit_value enabled?)
  values = meths.map do |field|
    "#{field}: #{send(field)}"
  end.join(', ')
  "#<Byebug::Breakpoint #{values}>"
end

#posString, Integer

Returns the position of this breakpoint, either a method name or a line

number.

Returns:

  • (String, Integer)


214
215
216
217
218
219
220
221
222
223
224
# File 'ext/byebug/breakpoint.c', line 214

static VALUE
brkpt_pos(VALUE self)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  if (breakpoint->type == BP_METHOD_TYPE)
    return rb_str_new2(rb_id2name(breakpoint->pos.mid));
  else
    return INT2FIX(breakpoint->pos.line);
}

#sourceString

Returns the source file of the breakpoint.

Returns:

  • (String)


232
233
234
235
236
237
238
239
# File 'ext/byebug/breakpoint.c', line 232

static VALUE
brkpt_source(VALUE self)
{
  breakpoint_t *breakpoint;

  Data_Get_Struct(self, breakpoint_t, breakpoint);
  return breakpoint->source;
}