RFC: Need a better caller(n) - real reflection for call stack wanted

RubyInline has the following extension to Object:

def caller_method_name()
  /\`([^\']+)\'/.match(caller(2).first)[1]
end

Is there a better way??? caller(n) returns a string, and I have to
parse it for the method name. This is scary at best. I’d much rather
have something that gave me either the method instance itself, or some
instance representation of the call stack. Something like:

class CallStack

  def line ... end			# returns the line of the calling method at this 

level (ATL)
def method … end # returns the calling method ATL
def class … end # returns the class for the calling method ATL
def to_s … end # equivalent output to the regular caller(n)
method
def up … end # returns a CallStack instance for one level up,
or nil
def down … end # returns a CallStack instance for one level
down, or nil

end

and a method, callstack() that returns the current instance of
CallStack. Or something like that. it would change my above method to:

def caller_method_name()
  callstack.up.up.method.name
end

Which reads MUCH better, and you can manipulate a lot more with this
type of expression.

I suppose up and down should also take int args like caller.

Now I’m tempted to go implement this… :slight_smile: Just not sure how my ruby-fu
in the internals are.

Is there a better way??? caller(n) returns a string, and I have to
parse it for the method name. This is scary at best. I'd much rather
have something that gave me either the method instance itself, or some
instance representation of the call stack. Something like:

Look at [ruby-talk:12097] "RCR: replacing 'caller'" for a previous
discussion on this subject

Guy Decoux

Another thing, and this may not only be off-the-wall but also
YAGNI in the highest, but I’ve often wanted caller(-1).

That’s right folks: An object that represents the current method
invocation.

One example of the potential is caller(-1).variables, which could
return a hash representing all the local variables.

This would aid in hacking out some quick ExtractMethod’s:

def some_huge_method
# a dozen vars here
# a dozen dozen lines of code mixed in
some_newly_extracted_method caller(-1).variables
end

Now, this is surely crossing the wackiness line, but what if you
could /assign/ to these vars? Then the implementation of
some_newly_extracted_method would look like this:

def some_newly_extracted_method variables_hash
caller(-1).variables = variables_hash
# extracted code here, raw and unchanged.
end

Then, we’d have the ability to mechanically extract methods, for
free.

But maybe we don’t need that because we never leave our code to
get so poorly factored that we’d need something like this.
Cough.

  • Ryan King
···

On 2002.09.20, Ryan Davis ryand@zenspider.com wrote:

Is there a better way??? caller(n) returns a string, and I have to
parse it for the method name. This is scary at best. I’d much rather
have something that gave me either the method instance itself, or some
instance representation of the call stack. Something like:
[…]

So… Matz’s reply (granted, a year ago) says the change was
committed… but I can’t find it. Did it move out of eval??? Or was it
popped out later on?

If the latter, I’ll make a stab at writing the code to my proposal…
I’ll even write unit tests. :wink:

···

On Friday, September 20, 2002, at 02:45 AM, ts wrote:

Is there a better way??? caller(n) returns a string, and I have to
parse it for the method name. This is scary at best. I’d much rather
have something that gave me either the method instance itself, or
some
instance representation of the call stack. Something like:

Look at [ruby-talk:12097] “RCR: replacing ‘caller’” for a previous
discussion on this subject

Hi,

Another thing, and this may not only be off-the-wall but also
YAGNI in the highest, but I’ve often wanted caller(-1).

That’s right folks: An object that represents the current method
invocation.

One example of the potential is caller(-1).variables, which could
return a hash representing all the local variables.

It sounds like as local_variables.

Then, we’d have the ability to mechanically extract methods, for
free.

But maybe we don’t need that because we never leave our code to
get so poorly factored that we’d need something like this.

It doesn’t feel to me useful, nor “factored.”

···

At Sat, 21 Sep 2002 03:45:02 +0900, Ryan King wrote:


Nobu Nakada

So... Matz's reply (granted, a year ago) says the change was
committed... but I can't find it. Did it move out of eval??? Or was it
popped out later on?

If you want to make reference to [ruby-talk:12106], this was for another
problem I think

Guy Decoux