Catching attr_accessor with set_trace_func

Code using attr_accessor:

class User
  attr_accessor :something
  def initialize
    @something = 0
  end
end

@user = User.new

set_trace_func(lambda {|*trace| STDERR.puts trace.inspect})
@user.something

···

#########
prints this to STDERR:
["line", "trace_func.rb", 11, nil, #<Binding:0x2946df0>, false]
#########

Functionally equivalent code with a hand-written method, instead of
attr_accessor:

class User
  def something
    @something
  end
  def initialize
    @something = 0
  end
end

@user = User.new

set_trace_func(lambda {|*trace| STDERR.puts trace.inspect})
@user.something

#########
prints this to STDERR:
["line", "trace_func.rb", 13, nil, #<Binding:0x2946d78>, false]
["call", "trace_func.rb", 2, :something, #<Binding:0x2946c10>, User]
["line", "trace_func.rb", 3, :something, #<Binding:0x2946bc8>, User]
["return", "trace_func.rb", 4, :something, #<Binding:0x2946aa8>, User]
#########

How can I capture the fact that the 'something' accessor was called in
the first example?

Hi,

At Thu, 16 Nov 2006 13:51:53 +0900,
Wilson Bilkovich wrote in [ruby-talk:225245]:

How can I capture the fact that the 'something' accessor was called in
the first example?

You can't now.

Maybe, new event types might be better.

trace_attr.diff (1.18 KB)

···

--
Nobu Nakada

Hi,

At Thu, 16 Nov 2006 16:52:07 +0900,
Nobuyoshi Nakada wrote in [ruby-talk:225257]:

--- eval.c 7 Nov 2006 09:38:12 -0000 1.958
+++ eval.c 16 Nov 2006 07:32:05 -0000

Sorry, it was wrong.

trace_attr.diff (1.12 KB)

···

--
Nobu Nakada

Thank you. That explains why it wasn't traceable.

While I have you here, perhaps you have an idea about the problem I am
trying to solve.

Given:
@user.something.trace_me

..I am trying to 'unwind' the calling order, so that the 'trace_me'
method can get a reference to @user and :something.
I need to do this in a general way, where the name of the object
(@user), and the last message it was sent (:something) are not known
in advance.

Is set_trace_func the only way to do that? Kernel#caller doesn't seem
like enough.

···

On 11/16/06, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

Hi,

At Thu, 16 Nov 2006 16:52:07 +0900,
Nobuyoshi Nakada wrote in [ruby-talk:225257]:
> --- eval.c 7 Nov 2006 09:38:12 -0000 1.958
> +++ eval.c 16 Nov 2006 07:32:05 -0000

Sorry, it was wrong.

Hi,

At Fri, 17 Nov 2006 00:01:43 +0900,
Wilson Bilkovich wrote in [ruby-talk:225298]:

Given:
@user.something.trace_me

..I am trying to 'unwind' the calling order, so that the 'trace_me'
method can get a reference to @user and :something.
I need to do this in a general way, where the name of the object
(@user), and the last message it was sent (:something) are not known
in advance.

What do you expect when the receiver isn't assigned to any
variable?

···

--
Nobu Nakada

Something indicating that would be fine. I don't need a handle on
'intermediate' objects, just ones that have a real lexical existence
in source code.

···

On 11/16/06, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

Hi,

At Fri, 17 Nov 2006 00:01:43 +0900,
Wilson Bilkovich wrote in [ruby-talk:225298]:
> Given:
> @user.something.trace_me
>
> ..I am trying to 'unwind' the calling order, so that the 'trace_me'
> method can get a reference to @user and :something.
> I need to do this in a general way, where the name of the object
> (@user), and the last message it was sent (:something) are not known
> in advance.

What do you expect when the receiver isn't assigned to any
variable?