-->

How to get the name of the calling alias method?

2019-05-03 09:26发布

问题:

I am having method called link_to_admin then I have aliased another method called simple_link_to

def link_to_admin(name,url,options={})

  # My stuff here
  link_to(name,url,options)          
end

alias_method :simple_link_to, :link_to_admin

Here I am facing one problem if I call link_to_admin, I want print the value into <li> tag

Ex.

def link_to_admin(name,url,options={})

  # My stuff here
   menu = ""
   menu << "<li> #{link_to(name,url,options)}</li>"
   menu.html_safe
end

And if I call simple_link_to no need of <li> tag. So currently I am passing one options like li_required then am checking condition in my method. This is working perfectly, I know this is correct way to do it.

def link_to_admin(name,url,options={})
   menu = ""
   menu << options[:li_required] ? "<li> #{link_to(name,url,options)}</li>" : link_to(name,url,options)
   menu.html_safe
end

But,Before I was trying to find the calling method like simple_method or link_to_admin, so I tried with:

1.__method__
2.caller[0]=~/`(.*?)'/

This is not working as expected.

I am calling simple_method or link_to_admin methods in layout so __method__ is always returning link_to_admin only.

But caller[0]=~/(.*?)'/if am calling fromlayoutmeans, it's returning layout path and if I am calling from any otherhelperorclass` means it's returning current method.

Any other way is there to check method name.

I know this is not good question, could any one please tell me any other way.

Note:- I have created alias_method for naming conversion only. Other than adding <li> tag I am not doing any thing.

Not only here am having this doubt from long back. I know I can define one more method and I can do it.

Leave my scenario, generally I wants to know this answer.

回答1:

Using __callee__ instead of __method__ will get the name of the alias being run.



回答2:

I would recommend that, instead of relying on method names and branching (which will become brittle with any method name refactoring, is obviously more complex, etc.) that you simply break apart the methods more to abstract common logic into a shared method.

Here's how I would write it:

def simple_link_to(name, url, options = {})
  # shared_link_to(name) ... or whatever
  link_to(name, url, options)
end

def link_to_admin(name, url, options = {})
  # shared_link_to(name) ... or whatever
  content_tag(:li) do
    simple_link_to(name, url, options)
  end
end

private
def shared_link_to(name)
  # do whatever is common
end

Note: I've made a bit of a guess that you have common code that you'd want to abstract out into some method (which I've called shared_link_to)... but do what you need with that part.