using the current method name within current method

Discussion in 'Ruby' started by Matthew Heidemann, Jul 31, 2006.

  1. 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
     
    Matthew Heidemann, Jul 31, 2006
    #1
    1. Advertising

  2. 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
     
    Daniel Harple, Jul 31, 2006
    #2
    1. Advertising

  3. 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'


    On 7/30/06, Daniel Harple <> wrote:
    > 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
    >
    >
    >
     
    Aleks Kissinger, Jul 31, 2006
    #3
  4. Matthew Heidemann

    Matt Todd Guest

    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.
     
    Matt Todd, Jul 31, 2006
    #4
  5. 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
     
    Robert Klemme, Jul 31, 2006
    #5
  6. On Jul 31, 2006, at 4:25 AM, Robert Klemme wrote:

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


    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.
     
    Logan Capaldo, Jul 31, 2006
    #6
  7. Matthew Heidemann

    Matt Todd Guest

    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.
     
    Matt Todd, Aug 1, 2006
    #7
  8. Logan Capaldo wrote:
    >
    > On Jul 31, 2006, at 4:25 AM, Robert Klemme wrote:
    >
    >> 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
    >>

    >
    > 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
     
    Robert Klemme, Aug 1, 2006
    #8
  9. 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>
     
    Aleks Kissinger, Aug 2, 2006
    #9
  10. 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
     
    Robert Klemme, Aug 3, 2006
    #10
  11. Matthew Heidemann

    Matt Todd Guest

    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.
     
    Matt Todd, Aug 3, 2006
    #11
  12. Matthew Heidemann

    Ace Suares Guest

    Robert Klemme wrote:

    <snip>

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




    --
    Posted via http://www.ruby-forum.com/.
     
    Ace Suares, Mar 10, 2010
    #12
  13. 2010/3/10 Ace Suares <>:
    > Robert Klemme wrote:
    >
    > <snip>
    >
    >> 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/
     
    Robert Klemme, Mar 10, 2010
    #13
  14. Matthew Heidemann

    Robert Dober Guest

    On Wed, Mar 10, 2010 at 9:29 AM, Robert Klemme
    <> wrote:
    > 2010/3/10 Ace Suares <>:

    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
     
    Robert Dober, Mar 10, 2010
    #14
  15. Matthew Heidemann

    eT Ma Guest

    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
    >=1.8.7), in 2010 it definitely did ;-)


    --
    Posted via http://www.ruby-forum.com/.
     
    eT Ma, Mar 22, 2011
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. nalbayo
    Replies:
    2
    Views:
    5,595
    Bruce Barker
    Nov 11, 2005
  2. ding feng
    Replies:
    2
    Views:
    2,907
    ding feng
    Jun 25, 2003
  3. Mitko Haralanov
    Replies:
    17
    Views:
    439
    Ben Finney
    Oct 20, 2006
  4. kj7ny
    Replies:
    9
    Views:
    285
    Peter Otten
    Aug 9, 2007
  5. Ezra Zygmuntowicz
    Replies:
    2
    Views:
    125
    Ezra Zygmuntowicz
    Jul 10, 2006
Loading...

Share This Page