ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:121388] [Ruby Feature#15854] Tracing instance variable assignment
       [not found] <redmine.issue-15854.20190516063455.1935@ruby-lang.org>
@ 2025-03-17 19:41 ` st0012 (Stan Lo) via ruby-core
  2025-03-18 13:06 ` [ruby-core:121399] " Eregon (Benoit Daloze) via ruby-core
  2025-06-05 21:54 ` [ruby-core:122471] " st0012 (Stan Lo) via ruby-core
  2 siblings, 0 replies; 3+ messages in thread
From: st0012 (Stan Lo) via ruby-core @ 2025-03-17 19:41 UTC (permalink / raw)
  To: ruby-core; +Cc: st0012 (Stan Lo)

Issue #15854 has been updated by st0012 (Stan Lo).


How about this naming convention:

- `ivar_set`
- `cvar_set`
- `gvar_set`

`ivar`, `cvar`, and `gvar` all match Ruby's [internal glossary](https://docs.ruby-lang.org/en/master/contributing/glossary_md.html), and is quite commonly used in the community too (based on my personal experience).

I picked `set` because:
- It matches the `*_variable_set` method names
- It's one character shorter than `asgn`

And finally, if nobody else is looking at this, I'd like to give it a try 🙂


----------------------------------------
Feature #15854: Tracing instance variable assignment
https://bugs.ruby-lang.org/issues/15854#change-112361

* Author: igaiga (Kuniaki Igarashi)
* Status: Assigned
* Assignee: ko1 (Koichi Sasada)
----------------------------------------
I suggest a feature "tracing instance variable assignment". It's useful for debugging.

Use case:

In Rails, we use instance variables in views and controllers. When we got a bug caused by instance variable unintentional values, if we traced instance variable assignment timing, it would be good informations.

And in Rails views, there are no source codes of self class. That's built dynamically.

Current behavior (Ruby2.6):

In Ruby 2.6, only if there is a source code file to assign instance variable, we can trace instance variable assignment by following code (check_instance_variable_assignment.rb). But it's difficult if the assignment codes are defined dynamically. For example, in Rails view.

(And in another story, global variables assignment are traced by Kernel#trace_var.)

check_instance_variable_assignment.rb
```ruby
def trace_start
  TracePoint.trace(:line) do |tp|
    target_class_name = "Foo"
    target_instance_variable_name = "@bar"

    line = File.open(tp.path, "r"){|f| f.readlines[tp.lineno - 1] }
    node = RubyVM::AbstractSyntaxTree.parse(line).children.last

    # check instance variable assignment
    next unless node.type == :IASGN

    # check class name
    target_class = Kernel.const_get(target_class_name)
    next unless tp.self.is_a?(target_class)

    # check variable name
    instance_variable_name = node.children.first
    next unless instance_variable_name == target_instance_variable_name.to_sym

    puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.defined_class} #{tp.method_id}"
  end
end

class Foo
  def bar
    @bar = "text"
  end
end

trace_start
Foo.new.bar
#=> Foo @bar is assigned in check_instance_variable_assignment.rb:25 Foo bar
```

Suggesting feature example:

Add new arguments for TracePoint.new method like :line and :call to trace instance variables assignment.

- :iasgn (IASGN name from RubyVM::AbstractSyntaxTree::Node)
- :casgn (CVASGN (or CASGN?) name from RubyVM::AbstractSyntaxTree::Node. I think class variables tracing is useful too.)

And get informations

- class name (It might be get by trace_point.self)
- variable name ("@foo", "@@foo")

A sample code to use the feature:

tp_iasgn.rb

```ruby
TracePoint.trace(:iasgn) do |tp|
  target_class_name = "Foo"
  target_instance_variable_name = "@bar"

  # check class name
  target_class = Kernel.const_get(target_class_name)
  next unless tp.self.is_a?(target_class)

  # check variable name
  next unless target_instance_variable_name == tp.variable_name 

  puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.method_id} #{tp.defined_class}"
  puts caller # even in dynamic code case, we can get caller informations.
end
```




-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ruby-core:121399] [Ruby Feature#15854] Tracing instance variable assignment
       [not found] <redmine.issue-15854.20190516063455.1935@ruby-lang.org>
  2025-03-17 19:41 ` [ruby-core:121388] [Ruby Feature#15854] Tracing instance variable assignment st0012 (Stan Lo) via ruby-core
@ 2025-03-18 13:06 ` Eregon (Benoit Daloze) via ruby-core
  2025-06-05 21:54 ` [ruby-core:122471] " st0012 (Stan Lo) via ruby-core
  2 siblings, 0 replies; 3+ messages in thread
From: Eregon (Benoit Daloze) via ruby-core @ 2025-03-18 13:06 UTC (permalink / raw)
  To: ruby-core; +Cc: Eregon (Benoit Daloze)

Issue #15854 has been updated by Eregon (Benoit Daloze).


I think tracing ivar assignments would be prohibitively slow, and so probably not really usable in practice.

----------------------------------------
Feature #15854: Tracing instance variable assignment
https://bugs.ruby-lang.org/issues/15854#change-112374

* Author: igaiga (Kuniaki Igarashi)
* Status: Assigned
* Assignee: ko1 (Koichi Sasada)
----------------------------------------
I suggest a feature "tracing instance variable assignment". It's useful for debugging.

Use case:

In Rails, we use instance variables in views and controllers. When we got a bug caused by instance variable unintentional values, if we traced instance variable assignment timing, it would be good informations.

And in Rails views, there are no source codes of self class. That's built dynamically.

Current behavior (Ruby2.6):

In Ruby 2.6, only if there is a source code file to assign instance variable, we can trace instance variable assignment by following code (check_instance_variable_assignment.rb). But it's difficult if the assignment codes are defined dynamically. For example, in Rails view.

(And in another story, global variables assignment are traced by Kernel#trace_var.)

check_instance_variable_assignment.rb
```ruby
def trace_start
  TracePoint.trace(:line) do |tp|
    target_class_name = "Foo"
    target_instance_variable_name = "@bar"

    line = File.open(tp.path, "r"){|f| f.readlines[tp.lineno - 1] }
    node = RubyVM::AbstractSyntaxTree.parse(line).children.last

    # check instance variable assignment
    next unless node.type == :IASGN

    # check class name
    target_class = Kernel.const_get(target_class_name)
    next unless tp.self.is_a?(target_class)

    # check variable name
    instance_variable_name = node.children.first
    next unless instance_variable_name == target_instance_variable_name.to_sym

    puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.defined_class} #{tp.method_id}"
  end
end

class Foo
  def bar
    @bar = "text"
  end
end

trace_start
Foo.new.bar
#=> Foo @bar is assigned in check_instance_variable_assignment.rb:25 Foo bar
```

Suggesting feature example:

Add new arguments for TracePoint.new method like :line and :call to trace instance variables assignment.

- :iasgn (IASGN name from RubyVM::AbstractSyntaxTree::Node)
- :casgn (CVASGN (or CASGN?) name from RubyVM::AbstractSyntaxTree::Node. I think class variables tracing is useful too.)

And get informations

- class name (It might be get by trace_point.self)
- variable name ("@foo", "@@foo")

A sample code to use the feature:

tp_iasgn.rb

```ruby
TracePoint.trace(:iasgn) do |tp|
  target_class_name = "Foo"
  target_instance_variable_name = "@bar"

  # check class name
  target_class = Kernel.const_get(target_class_name)
  next unless tp.self.is_a?(target_class)

  # check variable name
  next unless target_instance_variable_name == tp.variable_name 

  puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.method_id} #{tp.defined_class}"
  puts caller # even in dynamic code case, we can get caller informations.
end
```




-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ruby-core:122471] [Ruby Feature#15854] Tracing instance variable assignment
       [not found] <redmine.issue-15854.20190516063455.1935@ruby-lang.org>
  2025-03-17 19:41 ` [ruby-core:121388] [Ruby Feature#15854] Tracing instance variable assignment st0012 (Stan Lo) via ruby-core
  2025-03-18 13:06 ` [ruby-core:121399] " Eregon (Benoit Daloze) via ruby-core
@ 2025-06-05 21:54 ` st0012 (Stan Lo) via ruby-core
  2 siblings, 0 replies; 3+ messages in thread
From: st0012 (Stan Lo) via ruby-core @ 2025-06-05 21:54 UTC (permalink / raw)
  To: ruby-core; +Cc: st0012 (Stan Lo)

Issue #15854 has been updated by st0012 (Stan Lo).


> I think tracing ivar assignments would be prohibitively slow, and so probably not really usable in practice.

Since TracePoint is only recommended for debugging use, I think trading execution speed for more efficient debugging experience is a worth tradeoff for many people (myself included).

Currently, tools like `debug` watch events like `call` and `return` to inspect instance variable changes ([example](https://github.com/ruby/debug/blob/master/lib/debug/breakpoint.rb#L381-L425)), or even line event like the description gives, which are all much slower than having a dedicated ivar set event.

Anyway, I made a PR to support it here: https://github.com/ruby/ruby/pull/13369

----------------------------------------
Feature #15854: Tracing instance variable assignment
https://bugs.ruby-lang.org/issues/15854#change-113659

* Author: igaiga (Kuniaki Igarashi)
* Status: Assigned
* Assignee: ko1 (Koichi Sasada)
----------------------------------------
I suggest a feature "tracing instance variable assignment". It's useful for debugging.

Use case:

In Rails, we use instance variables in views and controllers. When we got a bug caused by instance variable unintentional values, if we traced instance variable assignment timing, it would be good informations.

And in Rails views, there are no source codes of self class. That's built dynamically.

Current behavior (Ruby2.6):

In Ruby 2.6, only if there is a source code file to assign instance variable, we can trace instance variable assignment by following code (check_instance_variable_assignment.rb). But it's difficult if the assignment codes are defined dynamically. For example, in Rails view.

(And in another story, global variables assignment are traced by Kernel#trace_var.)

check_instance_variable_assignment.rb
```ruby
def trace_start
  TracePoint.trace(:line) do |tp|
    target_class_name = "Foo"
    target_instance_variable_name = "@bar"

    line = File.open(tp.path, "r"){|f| f.readlines[tp.lineno - 1] }
    node = RubyVM::AbstractSyntaxTree.parse(line).children.last

    # check instance variable assignment
    next unless node.type == :IASGN

    # check class name
    target_class = Kernel.const_get(target_class_name)
    next unless tp.self.is_a?(target_class)

    # check variable name
    instance_variable_name = node.children.first
    next unless instance_variable_name == target_instance_variable_name.to_sym

    puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.defined_class} #{tp.method_id}"
  end
end

class Foo
  def bar
    @bar = "text"
  end
end

trace_start
Foo.new.bar
#=> Foo @bar is assigned in check_instance_variable_assignment.rb:25 Foo bar
```

Suggesting feature example:

Add new arguments for TracePoint.new method like :line and :call to trace instance variables assignment.

- :iasgn (IASGN name from RubyVM::AbstractSyntaxTree::Node)
- :casgn (CVASGN (or CASGN?) name from RubyVM::AbstractSyntaxTree::Node. I think class variables tracing is useful too.)

And get informations

- class name (It might be get by trace_point.self)
- variable name ("@foo", "@@foo")

A sample code to use the feature:

tp_iasgn.rb

```ruby
TracePoint.trace(:iasgn) do |tp|
  target_class_name = "Foo"
  target_instance_variable_name = "@bar"

  # check class name
  target_class = Kernel.const_get(target_class_name)
  next unless tp.self.is_a?(target_class)

  # check variable name
  next unless target_instance_variable_name == tp.variable_name 

  puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.method_id} #{tp.defined_class}"
  puts caller # even in dynamic code case, we can get caller informations.
end
```




-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-06-05 21:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-15854.20190516063455.1935@ruby-lang.org>
2025-03-17 19:41 ` [ruby-core:121388] [Ruby Feature#15854] Tracing instance variable assignment st0012 (Stan Lo) via ruby-core
2025-03-18 13:06 ` [ruby-core:121399] " Eregon (Benoit Daloze) via ruby-core
2025-06-05 21:54 ` [ruby-core:122471] " st0012 (Stan Lo) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).