using the current method name within current method

M

Matthew Heidemann

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
 
D

Daniel Harple

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
 
A

Aleks Kissinger

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'
 
M

Matt Todd

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.
 
R

Robert Klemme

Matt said:
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
 
L

Logan Capaldo

Matt said:
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

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.
 
M

Matt Todd

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.
 
R

Robert Klemme

Logan said:
Matt said:
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

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


#!/usr/bin/env ruby

require 'benchmark'

REPEAT = 1_00_000

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

def this_method_2
caller[0] =~ /`([^']*)'/ and $1
end

Benchmark.bmbm do |bm|
bm.report "global" do
REPEAT.times do
this_method_2
end
end

bm.report "String[]" do
REPEAT.times do
this_method_1
end
end
end
 
A

Aleks Kissinger

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>
 
R

Robert Klemme

Aleks said:
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
 
M

Matt Todd

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.
 
A

Ace Suares

Robert Klemme wrote:

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

Excellent! I was searching for this for a long time. 'what method called
this method' or 'how to find out which method called this method ?'

So, here's one:

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

Example:

def a
b
end

def b
puts "this method: " + this_method
puts "calling method: " + calling_method
end

calling 'a' will output
this method: b
calling method: a

Thx!
 
R

Robert Klemme

2010/3/10 Ace Suares said:
Robert Klemme wrote:

These methods are typically put into Kernel and made private. =A0Also, y= ou
don't check whether the RX actually matches. =A0I'd also prefer to chang= e
the RX to a more efficient one. =A0So that would give

module Kernel
private
=A0 =A0def this_method
=A0 =A0 =A0caller[0] =3D~ /`([^']*)'/ and $1
=A0 =A0end
end

Excellent! I was searching for this for a long time. 'what method called
this method' or 'how to find out which method called this method ?'

So, here's one:

module Kernel
private
=A0def this_method
=A0 =A0caller[0] =3D~ /`([^']*)'/ and $1
=A0end
=A0def calling_method
=A0 =A0caller[1] =3D~ /`([^']*)'/ and $1
=A0end
end

Example:

def a
=A0b
end

def b
=A0puts "this method: " + this_method
=A0puts "calling method: " + calling_method
end

calling 'a' will output
this method: b
calling method: a

Wow, you just reviewed a 3.5 year old thread! :)

Btw, nowadays I would change the regular expression matching to use
String#[] which I find much more elegant:

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

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
R

Robert Dober

2010/3/10 Ace Suares <[email protected]>:
I would leave Kernel (and Object ) alone for that

module Whatever
end

mix it in where and when you want. Ok that is a matter of taste but
gives you a less intrusive way

Cheers
R

--=20
Learning without thought is labor lost; thought without learning is perilou=
s.=94
--- Confucius
 
E

eT Ma

Reviving thread again: I'd use __method__

In terms of original example.

def test_method
puts __method__
end

Maybe __method__ didn't exist in 2006 (too lazy to check, maybe its
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,801
Messages
2,569,658
Members
45,425
Latest member
CorrineHol

Latest Threads

Top