Ruby Forum Ruby > using the current method name within current method

Posted by Matthew Heidemann (Guest)
on 31.07.2006 05:37
(Received via mailing list)
Is there a way to get the current method name within the current method?

def test_method
  puts self.current_method
end

--- output ----
test_method

Thanks,
Matt
Posted by Daniel Harple (Guest)
on 31.07.2006 05:46
(Received via mailing list)
On Jul 30, 2006, at 11:37 PM, Matthew Heidemann wrote:

> Is there a way to get the current method name within the current  
> method?
>
> def test_method
>  puts self.current_method
> end
>
> --- output ----
> test_method

In 1.9 (Ruby CVS HEAD) there is #__method__ and #__callee__: http://
eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l90

-- Daniel
Posted by Aleks Kissinger (Guest)
on 31.07.2006 06:08
(Received via mailing list)
This is kindof a hack, but it seems to work:

def get_mname
  caller[0]=~/`(.*?)'/  # note the first quote is a backtick
  $1
end

def dinosaur
  puts get_mname
end

dinosaur()
=> 'dinosaur'
Posted by Matt Todd (Guest)
on 31.07.2006 07:44
(Received via mailing list)
If you wanted to modularize it just for the sake of it, you could do
something similar to the following:

module CurrentMethodName
  def this_method
    caller[0]=~/`(.*?)'/
    $1
  end
end

And, then, use it like this:

class Foo
  include CurrentMethodName
  def bar
    this_method
  end
end

Hope this cleans it up a bit for you. It's a holdover until 1.9.

M.T.
Posted by Robert Klemme (Guest)
on 31.07.2006 10:30
(Received via mailing list)
Matt Todd wrote:
> If you wanted to modularize it just for the sake of it, you could do
> something similar to the following:
> 
> module CurrentMethodName
>  def this_method
>    caller[0]=~/`(.*?)'/
>    $1
>  end
> end

You can rewrite that as

def this_method
   caller[0][/`([^']*)'/, 1]
end

and thusly avoid the global variable.

Kind regards

	robert
Posted by Logan Capaldo (Guest)
on 31.07.2006 20:00
(Received via mailing list)
On Jul 31, 2006, at 4:25 AM, Robert Klemme wrote:

> You can rewrite that as
>
I have a sneaking suspicion he might have done it with the global
variable (although $1 isn't really global) on purpose, since =~ /
literal/ is the fastest way to do a regexp.
Posted by Matt Todd (Guest)
on 01.08.2006 05:29
(Received via mailing list)
As much as I'd like to take credit for knowing its superior speed, I
can't as I stole it from Aleks. :)

However, I did know that $1 wasn't a true global in the sense of the
term, but a magic variable specific to the regexp test. It's commonly
acceptable, and, hey, if it's faster, why not, right?

A side note: this is one of the first things I've worked with that I
decided to make into something that was includable.... It's a
milestone in my way of thinking and coding with Ruby! Yay! (Sorry, had
to tell someone!)

Cheers!

M.T.
Posted by Robert Klemme (Guest)
on 01.08.2006 13:49
(Received via mailing list)
Logan Capaldo wrote:
>>>  end
>> Kind regards
>>
>>     robert
>>
> 
> I have a sneaking suspicion he might have done it with the global 
> variable (although $1 isn't really global) on purpose, since =~ 
> /literal/ is the fastest way to do a regexp.

I did a benchmark just to put some meat to this:

13:37:39 [Temp]: ./bm.rb
Rehearsal --------------------------------------------
global     1.859000   0.000000   1.859000 (  1.863000)
String[]   2.156000   0.000000   2.156000 (  2.180000)
----------------------------------- total: 4.015000sec

                user     system      total        real
global     1.828000   0.000000   1.828000 (  1.872000)
String[]   2.094000   0.000000   2.094000 (  2.172000)

IOW, the global var version uses 87,3% of the time or is 15% faster.

Kind regards

	robert
Posted by Aleks Kissinger (Guest)
on 03.08.2006 12:55
(Received via mailing list)
Depending on how you feel about mucking with core ruby types, a method
like this one seems like a decent candidate for mixing in to Object.

class Object
  def this_method
    caller[0]=~/`(.*?)'/
    $1
  end
end

Course I'm one of those crazy irb hack loving people that mixes
convenience methods into everything....

> >> Matt Todd wrote:
> >>> If you wanted to modularize it just for the sake of it, you could do
> >>> something similar to the following:
> >>> module CurrentMethodName
> >>>  def this_method
> >>>    caller[0]=~/`(.*?)'/
> >>>    $1
> >>>  end
> >>> end

<snip>
Posted by Robert Klemme (Guest)
on 03.08.2006 14:24
(Received via mailing list)
Aleks Kissinger wrote:
> Depending on how you feel about mucking with core ruby types, a method
> like this one seems like a decent candidate for mixing in to Object.
> 
> class Object
>  def this_method
>    caller[0]=~/`(.*?)'/
>    $1
>  end
> end

These methods are typically put into Kernel and made private.  Also, you
don't check whether the RX actually matches.  I'd also prefer to change
the RX to a more efficient one.  So that would give

module Kernel
private
   def this_method
     caller[0] =~ /`([^']*)'/ and $1
   end
end

Kind regards

	robert
Posted by Matt Todd (Guest)
on 03.08.2006 17:49
(Received via mailing list)
I like that much better. That seems to fit in with the rest of how
Ruby works. Well done. Also, thanks for improving the RX efficiency: I
see how that would be a bit more efficient.

M.T.