ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:92679] [Ruby trunk Feature#15854] Tracing instance variable assignment
       [not found] <redmine.issue-15854.20190516063455@ruby-lang.org>
@ 2019-05-16  6:34 ` igaiga
  2019-05-16  7:00 ` [ruby-core:92680] " takashikkbn
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 5+ messages in thread
From: igaiga @ 2019-05-16  6:34 UTC (permalink / raw
  To: ruby-core

Issue #15854 has been reported by igaiga (Kuniaki IGARASHI).

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

* Author: igaiga (Kuniaki IGARASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
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/

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

* [ruby-core:92680] [Ruby trunk Feature#15854] Tracing instance variable assignment
       [not found] <redmine.issue-15854.20190516063455@ruby-lang.org>
  2019-05-16  6:34 ` [ruby-core:92679] [Ruby trunk Feature#15854] Tracing instance variable assignment igaiga
@ 2019-05-16  7:00 ` takashikkbn
  2019-05-16  8:37 ` [ruby-core:92681] " shevegen
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 5+ messages in thread
From: takashikkbn @ 2019-05-16  7:00 UTC (permalink / raw
  To: ruby-core

Issue #15854 has been updated by k0kubun (Takashi Kokubun).


This feature would be helpful if it will be integrated with byebug's tracevar, which currently supports only global variable tracing.

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

For me it's hard to understand what's `:iasgn` at a glance. Perhaps other TracePoint event names and Node's names have different naming conventions. Other TracePoint event names are like `:thread_begin` or `:fiber_switch`. So for `:iasgn`, I'd propose:

* `:ivar_assign` (close to original proposal)
* `:instance_variable_set` (same as official method name, maybe too long but "ivar" may not be friendly either)

> I think class variables tracing is useful too.

Cloud you describe a use case? Your reasoning behind `:iasgn` is Rails controllers / views and that makes sense, but I don't think it applies to `:casgn`.

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

* Author: igaiga (Kuniaki IGARASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
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/

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

* [ruby-core:92681] [Ruby trunk Feature#15854] Tracing instance variable assignment
       [not found] <redmine.issue-15854.20190516063455@ruby-lang.org>
  2019-05-16  6:34 ` [ruby-core:92679] [Ruby trunk Feature#15854] Tracing instance variable assignment igaiga
  2019-05-16  7:00 ` [ruby-core:92680] " takashikkbn
@ 2019-05-16  8:37 ` shevegen
  2019-05-21  8:38 ` [ruby-core:92741] " igaiga
  2019-07-29  7:13 ` [ruby-core:93971] [Ruby master " ko1
  4 siblings, 0 replies; 5+ messages in thread
From: shevegen @ 2019-05-16  8:37 UTC (permalink / raw
  To: ruby-core

Issue #15854 has been updated by shevegen (Robert A. Heiler).


> I suggest a feature "tracing instance variable assignment"

I love introspection. The old pickaxe had an example tracing global variables, and
it would seem nice if we could extend this to other/more variables, so I am +1 for
the suggestion. See also pry acting a bit like an introspection-debugger, e. g. 
"cd object; ls" what the object has (at the least as an idea).

I should, however had, also admit that I do not use the trace-var functionality
for global variables, primarily because I try to avoid global variables (and thus
use them so rarely that I don't need to trace anything), but also partially because
I am not completely sure whether I personally need that functionality. But still I
think it would be nice to have, so I agree from this point of view with igaiga.

I agree that :iasgn is a strange name but I guess other/better names can be used;
may be good to ask ko1 what he thinks about tracing (and exposing this for ruby
users) in principle (and of course matz whether he wants to expose functionality
to ruby users, but I think since we can trace global vars, it may be a related
topic to be able to trace other variables too).

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

* Author: igaiga (Kuniaki IGARASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
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/

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

* [ruby-core:92741] [Ruby trunk Feature#15854] Tracing instance variable assignment
       [not found] <redmine.issue-15854.20190516063455@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2019-05-16  8:37 ` [ruby-core:92681] " shevegen
@ 2019-05-21  8:38 ` igaiga
  2019-07-29  7:13 ` [ruby-core:93971] [Ruby master " ko1
  4 siblings, 0 replies; 5+ messages in thread
From: igaiga @ 2019-05-21  8:38 UTC (permalink / raw
  To: ruby-core

Issue #15854 has been updated by igaiga (Kuniaki IGARASHI).


Thanks to comments.

> :ivar_assign (close to original proposal)
> :instance_variable_set (same as official method name, maybe too long but "ivar" may not be friendly either)

Looks good. I feel they are good to read, so better than my suggested :iasgn.

> Cloud you describe a use case? ... but I don't think it applies to :casgn.

I've tried to describe the use cases, but I can't write use cases for class variables.

I thought following patterns that how to torigger their assign timings.

- global variable: Kernel#trace_var
- class variable: none
- instance variable: suggested by this issue
- local variable: none? (but we don't need)

So I thought class variable assignment trigger is useful for us. But cases to use class variables are not so often, so the trigger of :class_variable_set would be not so useful.


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

* Author: igaiga (Kuniaki IGARASHI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
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/

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

* [ruby-core:93971] [Ruby master Feature#15854] Tracing instance variable assignment
       [not found] <redmine.issue-15854.20190516063455@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2019-05-21  8:38 ` [ruby-core:92741] " igaiga
@ 2019-07-29  7:13 ` ko1
  4 siblings, 0 replies; 5+ messages in thread
From: ko1 @ 2019-07-29  7:13 UTC (permalink / raw
  To: ruby-core

Issue #15854 has been updated by ko1 (Koichi Sasada).

Assignee set to ko1 (Koichi Sasada)

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

* Author: igaiga (Kuniaki IGARASHI)
* Status: Open
* Priority: Normal
* Assignee: ko1 (Koichi Sasada)
* Target version: 
----------------------------------------
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/

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

end of thread, other threads:[~2019-07-29  7:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <redmine.issue-15854.20190516063455@ruby-lang.org>
2019-05-16  6:34 ` [ruby-core:92679] [Ruby trunk Feature#15854] Tracing instance variable assignment igaiga
2019-05-16  7:00 ` [ruby-core:92680] " takashikkbn
2019-05-16  8:37 ` [ruby-core:92681] " shevegen
2019-05-21  8:38 ` [ruby-core:92741] " igaiga
2019-07-29  7:13 ` [ruby-core:93971] [Ruby master " ko1

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 read-only IMAP folder(s) and NNTP newsgroup(s).